runtime.cc revision fc322c72d7a89a6f7a05c8bdc232d780aecd9232
16b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 26b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro 3578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "runtime.h" 47b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 5ffe6736397d17457188727510f0a2953f69a383aElliott Hughes#include <cstdio> 6ffe6736397d17457188727510f0a2953f69a383aElliott Hughes#include <cstdlib> 72ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include <vector> 8ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 9578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 10578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "heap.h" 11fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro#include "scoped_ptr.h" 12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 1361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 146b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 157b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 162ed144c2b49ae1da6c464d7a1be0062870530802Carl ShapiroRuntime* Runtime::instance_ = NULL; 172ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 1861e019d291583029c01b61b93bea750f2b663c37Carl ShapiroRuntime::~Runtime() { 1961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // TODO: use a smart pointer instead. 2061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro delete class_linker_; 2169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Heap::Destroy(); 2261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro delete thread_list_; 234acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 244acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro CHECK(instance_ == this); 254acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro instance_ = NULL; 2661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 2761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 28ffe6736397d17457188727510f0a2953f69a383aElliott Hughesvoid Runtime::Abort(const char* file, int line) { 29ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Get any pending output out of the way. 30ffe6736397d17457188727510f0a2953f69a383aElliott Hughes fflush(NULL); 31ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 32ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Many people have difficulty distinguish aborts from crashes, 33ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // so be explicit. 34ffe6736397d17457188727510f0a2953f69a383aElliott Hughes LogMessage(file, line, ERROR, -1).stream() << "Runtime aborting..."; 35ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 36ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // TODO: if we support an abort hook, call it here. 37ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 38ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Perform any platform-specific pre-abort actions. 39ffe6736397d17457188727510f0a2953f69a383aElliott Hughes PlatformAbort(file, line); 40ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 41ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // If we call abort(3) on a device, all threads in the process 4269759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // receive SIGABRT. debuggerd dumps the stack trace of the main 4369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // thread, whether or not that was the thread that failed. By 4469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // stuffing a value into a bogus address, we cause a segmentation 45ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // fault in the current thread, and get a useful log from debuggerd. 46ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // We can also trivially tell the difference between a VM crash and 47ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // a deliberate abort by looking at the fault address. 48ffe6736397d17457188727510f0a2953f69a383aElliott Hughes *reinterpret_cast<char*>(0xdeadd00d) = 38; 49ffe6736397d17457188727510f0a2953f69a383aElliott Hughes abort(); 50ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 51ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // notreached 52ffe6736397d17457188727510f0a2953f69a383aElliott Hughes} 53ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 54fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapirovoid ParseClassPath(const char* class_path, std::vector<std::string>* vec) { 55fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro CHECK(vec != NULL); 56fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro scoped_ptr_malloc<char> tmp(strdup(class_path)); 57fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro char* full = tmp.get(); 58fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro char* p = full; 59fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro while (p) { 60fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro p = strpbrk(full, ":"); 61fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (p != NULL) { 62fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro p[0] = '\0'; 63fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 64fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (full[0] != '\0') { 65fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro vec->push_back(std::string(full)); 66fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 67fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (p) { 68fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro full = p + 1; 69fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 70fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 71fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 72fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 73fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro// TODO: move option processing elsewhere. 74fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiroconst char* FindBootClassPath(const Runtime::Options& options) { 75fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro const char* boot_class_path = getenv("BOOTCLASSPATH"); 76fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro const char* flag = "-Xbootclasspath:"; 77fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro for (size_t i = 0; i < options.size(); ++i) { 78fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro const StringPiece& option = options[i].first; 79fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (option.starts_with(flag)) { 80fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro boot_class_path = option.substr(strlen(flag)).data(); 81fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 82fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 83fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (boot_class_path == NULL) { 84fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro return ""; 85fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } else { 86fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro return boot_class_path; 87fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 88fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 89fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 90fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapirovoid CreateBootClassPath(const Runtime::Options& options, 91fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro std::vector<DexFile*>* boot_class_path) { 92fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro CHECK(boot_class_path != NULL); 93fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro const char* str = FindBootClassPath(options); 94fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro std::vector<std::string> parsed; 95fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro ParseClassPath(str, &parsed); 96fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro for (size_t i = 0; i < parsed.size(); ++i) { 97fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro DexFile* dex_file = DexFile::OpenFile(parsed[i].c_str()); 98fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (dex_file != NULL) { 99fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro boot_class_path->push_back(dex_file); 100fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 101fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 102fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 103fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 104fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro// TODO: do something with ignore_unrecognized when we parse the option 105fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro// strings for real. 1062ed144c2b49ae1da6c464d7a1be0062870530802Carl ShapiroRuntime* Runtime::Create(const Options& options, bool ignore_unrecognized) { 107fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro std::vector<DexFile*> boot_class_path; 108fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro CreateBootClassPath(options, &boot_class_path); 1092ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return Runtime::Create(boot_class_path); 1102ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 1112ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 1122ed144c2b49ae1da6c464d7a1be0062870530802Carl ShapiroRuntime* Runtime::Create(const std::vector<DexFile*>& boot_class_path) { 1132ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 1142ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro if (Runtime::instance_ != NULL) { 1152ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return NULL; 1162ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 11761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro scoped_ptr<Runtime> runtime(new Runtime()); 118578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom bool success = runtime->Init(boot_class_path); 11961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro if (!success) { 12061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro return NULL; 12161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro } else { 1222ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return Runtime::instance_ = runtime.release(); 12361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro } 12461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 12561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 1262ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapirobool Runtime::Init(const std::vector<DexFile*>& boot_class_path) { 12761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro thread_list_ = ThreadList::Create(); 12869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Heap::Init(Heap::kStartupSize, Heap::kMaximumSize); 12961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro Thread::Init(); 13061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro Thread* current_thread = Thread::Attach(); 13161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro thread_list_->Register(current_thread); 132578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom class_linker_ = ClassLinker::Create(boot_class_path); 1337b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro return true; 1347b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 1357b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 1362ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapirobool Runtime::AttachCurrentThread(const char* name, JniEnvironment** penv) { 1372ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return Thread::Attach() != NULL; 1382ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 1392ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 1402ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapirobool Runtime::AttachCurrentThreadAsDaemon(const char* name, 1412ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro JniEnvironment** penv) { 1422ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro // TODO: do something different for daemon threads. 143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return Thread::Attach() != NULL; 14461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 14561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Runtime::DetachCurrentThread() { 147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(WARNING) << "Unimplemented: Runtime::DetachCurrentThread"; 148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return true; 1497b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 1507b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 1516b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 152