runtime.cc revision 5d40f182181488eb39ccd19ffd306bb1fb9740c9
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> 78a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom#include <limits> 82ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include <vector> 9ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 1090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "UniquePtr.h" 11578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 12578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "heap.h" 13cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes#include "intern_table.h" 14c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes#include "jni_internal.h" 15e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes#include "signal_catcher.h" 16578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 178daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread_list.h" 1861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 1990a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes// TODO: this drags in cutil/log.h, which conflicts with our logging.h. 2090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "JniConstants.h" 2190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes 226b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 237b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 242ed144c2b49ae1da6c464d7a1be0062870530802Carl ShapiroRuntime* Runtime::instance_ = NULL; 252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 26dcc247493fd8fb243e335c3ec08e5e625896a47cElliott HughesRuntime::Runtime() 27be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes : default_stack_size_(Thread::kDefaultStackSize), 28dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes thread_list_(NULL), 29dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes intern_table_(NULL), 30dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes class_linker_(NULL), 31dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes signal_catcher_(NULL), 32dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes java_vm_(NULL), 33161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom jni_stub_array_(NULL), 34ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers callee_save_method_(NULL), 35dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes started_(false), 36dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes vfprintf_(NULL), 37dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes exit_(NULL), 389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes abort_(NULL), 399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats_enabled_(false) { 40dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 41dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 4261e019d291583029c01b61b93bea750f2b663c37Carl ShapiroRuntime::~Runtime() { 435fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes // Make sure our internal threads are dead before we start tearing down things they're using. 445fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes delete signal_catcher_; 45038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // TODO: GC thread. 465fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 47038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended. 4893e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes delete thread_list_; 4993e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 5061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro delete class_linker_; 5169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Heap::Destroy(); 52cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes delete intern_table_; 53c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes delete java_vm_; 54c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes Thread::Shutdown(); 554acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 564a289ed61242964b921434de7d375f46480472a1Brian Carlstrom CHECK(instance_ == NULL || instance_ == this); 574acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro instance_ = NULL; 5861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 5961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 60ffe6736397d17457188727510f0a2953f69a383aElliott Hughesvoid Runtime::Abort(const char* file, int line) { 61ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Get any pending output out of the way. 62ffe6736397d17457188727510f0a2953f69a383aElliott Hughes fflush(NULL); 63ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 64ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Many people have difficulty distinguish aborts from crashes, 65ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // so be explicit. 66ffe6736397d17457188727510f0a2953f69a383aElliott Hughes LogMessage(file, line, ERROR, -1).stream() << "Runtime aborting..."; 67ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 68ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Perform any platform-specific pre-abort actions. 69ffe6736397d17457188727510f0a2953f69a383aElliott Hughes PlatformAbort(file, line); 70ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 716ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom // use abort hook if we have one 726ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) { 736ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom Runtime::Current()->abort_(); 746ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom // notreached 756ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } 766ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 77ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // If we call abort(3) on a device, all threads in the process 7869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // receive SIGABRT. debuggerd dumps the stack trace of the main 7969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // thread, whether or not that was the thread that failed. By 8069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // stuffing a value into a bogus address, we cause a segmentation 81ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // fault in the current thread, and get a useful log from debuggerd. 82ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // We can also trivially tell the difference between a VM crash and 83ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // a deliberate abort by looking at the fault address. 84ffe6736397d17457188727510f0a2953f69a383aElliott Hughes *reinterpret_cast<char*>(0xdeadd00d) = 38; 85ffe6736397d17457188727510f0a2953f69a383aElliott Hughes abort(); 86ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // notreached 87ffe6736397d17457188727510f0a2953f69a383aElliott Hughes} 88ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 89bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughesvoid Runtime::CallExitHook(jint status) { 90bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes if (exit_ != NULL) { 91bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), Thread::kNative); 92bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes exit_(status); 93bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes LOG(WARNING) << "Exit hook returned instead of exiting!"; 94bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes } 95bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 96bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 978a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify 988a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// memory sizes. [kK] indicates kilobytes, [mM] megabytes, and 998a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// [gG] gigabytes. 1008a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 1018a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// "s" should point just past the "-Xm?" part of the string. 1028a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// "div" specifies a divisor, e.g. 1024 if the value must be a multiple 1038a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// of 1024. 1048a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 1058a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// The spec says the -Xmx and -Xms options must be multiples of 1024. It 1068a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// doesn't say anything about -Xss. 1078a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 1088a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// Returns 0 (a useless size) if "s" is malformed or specifies a low or 1098a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// non-evenly-divisible value. 1108a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 1118a436595d36c1e4935984fcac249d7d877e00383Brian Carlstromsize_t ParseMemoryOption(const char *s, size_t div) { 1128a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // strtoul accepts a leading [+-], which we don't want, 1138a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // so make sure our string starts with a decimal digit. 1148a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (isdigit(*s)) { 1158a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom const char *s2; 1168a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom size_t val = strtoul(s, (char **)&s2, 10); 1178a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (s2 != s) { 1188a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // s2 should be pointing just after the number. 1198a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // If this is the end of the string, the user 1208a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // has specified a number of bytes. Otherwise, 1218a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // there should be exactly one more character 1228a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // that specifies a multiplier. 1238a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (*s2 != '\0') { 124f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // The remainder of the string is either a single multiplier 125f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // character, or nothing to indicate that the value is in 126f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // bytes. 127f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom char c = *s2++; 128f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (*s2 == '\0') { 129f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom size_t mul; 130f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (c == '\0') { 131f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = 1; 132f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'k' || c == 'K') { 133f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = KB; 134f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'm' || c == 'M') { 135f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = MB; 136f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'g' || c == 'G') { 137f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = GB; 1388a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else { 139f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // Unknown multiplier character. 1408a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return 0; 1418a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 142f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom 143f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (val <= std::numeric_limits<size_t>::max() / mul) { 144f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom val *= mul; 145f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else { 146f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // Clamp to a multiple of 1024. 147f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom val = std::numeric_limits<size_t>::max() & ~(1024-1); 148f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 149f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else { 150f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // There's more than one character after the numeric part. 151f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return 0; 152f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 1538a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 1548a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // The man page says that a -Xm value must be a multiple of 1024. 1558a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (val % div == 0) { 1568a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return val; 1578a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 158fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 159fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 1608a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return 0; 161fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 162fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 1630af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesvoid LoadJniLibrary(JavaVMExt* vm, const char* name) { 1640af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes // TODO: OS_SHARED_LIB_FORMAT_STR 1650af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::string mapped_name(StringPrintf("lib%s.so", name)); 1667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes std::string reason; 1677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (!vm->LoadNativeLibrary(mapped_name, NULL, reason)) { 1680af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": " 1690af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes << reason; 1700af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 1710af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes} 1720af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 1737ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughesvoid CreateClassPath(const std::string& class_path, 17469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::vector<const DexFile*>& class_path_vector) { 175fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro std::vector<std::string> parsed; 1767ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes Split(class_path, ':', parsed); 177fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro for (size_t i = 0; i < parsed.size(); ++i) { 178161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom const DexFile* dex_file = DexFile::Open(parsed[i], ""); 179fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro if (dex_file != NULL) { 18069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom class_path_vector.push_back(dex_file); 181fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 182fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 183fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 184fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 1856ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian CarlstromRuntime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) { 18690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<ParsedOptions> parsed(new ParsedOptions()); 1876ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->boot_image_ = NULL; 188515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes#ifdef NDEBUG 1895174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes // -Xcheck:jni is off by default for regular builds... 190515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes parsed->check_jni_ = false; 191515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes#else 192515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes // ...but on by default in debug builds. 193515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes parsed->check_jni_ = true; 194515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes#endif 19585d1545e985ac689db4bad7849880e843707c862Elliott Hughes 1966ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->heap_initial_size_ = Heap::kInitialSize; 1976ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->heap_maximum_size_ = Heap::kMaximumSize; 198f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->stack_size_ = Thread::kDefaultStackSize; 199f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom 2006ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_vfprintf_ = vfprintf; 2016ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_exit_ = exit; 2026ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_abort_ = abort; 2038a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 2048a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom for (size_t i = 0; i < options.size(); ++i) { 2058a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom const StringPiece& option = options[i].first; 2068a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (option.starts_with("-Xbootclasspath:")) { 2077ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data(); 2088a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else if (option == "bootclasspath") { 2097ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes UNIMPLEMENTED(WARNING) << "what should VMRuntime.getBootClassPath return here?"; 210f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom const void* dex_vector = options[i].second; 2119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const std::vector<const DexFile*>* v 2129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom = reinterpret_cast<const std::vector<const DexFile*>*>(dex_vector); 213f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (v == NULL) { 214f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 215f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 216f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 217f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // TODO: usage 21869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 219f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 220f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 221f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->boot_class_path_ = *v; 22278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } else if (option == "classpath") { 22378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const void* dex_vector = options[i].second; 22478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const std::vector<const DexFile*>* v 22578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom = reinterpret_cast<const std::vector<const DexFile*>*>(dex_vector); 22678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (v == NULL) { 22778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (ignore_unrecognized) { 22878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom continue; 22978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 23078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom // TODO: usage 23178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 23278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return NULL; 23378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 23478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom parsed->class_path_ = *v; 23569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option == "-classpath" || option == "-cp") { 23669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: support -Djava.class.path 23769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom i++; 23869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (i == options.size()) { 23969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: usage 24069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Missing required class path value for " << option; 24169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return NULL; 24269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 24369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const StringPiece& value = options[i].first; 2447ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes parsed->class_path_string_ = value.data(); 2458a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else if (option.starts_with("-Xbootimage:")) { 24669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: remove when intern_addr_ is removed, just use -Ximage: 2476ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->boot_image_ = option.substr(strlen("-Xbootimage:")).data(); 24869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("-Ximage:")) { 24969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom parsed->images_.push_back(option.substr(strlen("-Ximage:")).data()); 250515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes } else if (option.starts_with("-Xcheck:jni")) { 251515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes parsed->check_jni_ = true; 2528a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else if (option.starts_with("-Xms")) { 253f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).data(), 1024); 254f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 255f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 256f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 257f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 2584a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 25969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 260f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 261f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 262f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->heap_initial_size_ = size; 2638a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else if (option.starts_with("-Xmx")) { 264f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).data(), 1024); 265f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 266f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 267f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 268f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 2694a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 27069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 271f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 272f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 273f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->heap_maximum_size_ = size; 274f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (option.starts_with("-Xss")) { 275f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).data(), 1); 276f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 277f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 278f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 279f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 2804a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 28169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 282f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 283f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 284f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->stack_size_ = size; 2856ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option.starts_with("-D")) { 2866ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->properties_.push_back(option.substr(strlen("-D")).data()); 287a09576416788b916095739e43a16917e7948f3a4Elliott Hughes } else if (option.starts_with("-Xjnitrace:")) { 288a09576416788b916095739e43a16917e7948f3a4Elliott Hughes parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:")).data(); 2896ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option.starts_with("-verbose:")) { 2900af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::vector<std::string> verbose_options; 29134023801bd544e613d6e85c9a5b2e743f3710e8fElliott Hughes Split(option.substr(strlen("-verbose:")).data(), ',', verbose_options); 2920af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes for (size_t i = 0; i < verbose_options.size(); ++i) { 2930af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes parsed->verbose_.insert(verbose_options[i]); 2940af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 2956ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "vfprintf") { 2966ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_vfprintf_ = reinterpret_cast<int (*)(FILE *, const char*, va_list)>(options[i].second); 2976ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "exit") { 2986ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second); 2996ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "abort") { 3006ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second); 3018a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else { 3028a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (!ignore_unrecognized) { 3036ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom // TODO: print usage via vfprintf 30427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom LOG(ERROR) << "Unrecognized option " << option; 30527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // TODO: this should exit, but for now tolerate unknown options 30627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom //return NULL; 3078a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 3088a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 3098a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 3108a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 3117ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes // Consider it an error if both bootclasspath and -Xbootclasspath: are supplied. 31278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom // TODO: remove bootclasspath and classpath which are mostly just used by tests? 3137ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes if (!parsed->boot_class_path_.empty() && !parsed->boot_class_path_string_.empty()) { 31469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: usage 31569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "bootclasspath and -Xbootclasspath: are mutually exclusive options."; 31669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return NULL; 3178a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 31878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (!parsed->class_path_.empty() && !parsed->class_path_string_.empty()) { 31978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom // TODO: usage 32078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom LOG(FATAL) << "bootclasspath and -Xbootclasspath: are mutually exclusive options."; 32178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return NULL; 32278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 32369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (parsed->boot_class_path_.empty()) { 3247ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes if (parsed->boot_class_path_string_ == NULL) { 3257ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes const char* BOOTCLASSPATH = getenv("BOOTCLASSPATH"); 32627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (BOOTCLASSPATH != NULL) { 32727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom parsed->boot_class_path_string_ = BOOTCLASSPATH; 32827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 32969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 3307ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes CreateClassPath(parsed->boot_class_path_string_, parsed->boot_class_path_); 3318a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 3322ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 33378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (parsed->class_path_.empty()) { 33478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (parsed->class_path_string_ == NULL) { 33578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const char* CLASSPATH = getenv("CLASSPATH"); 33678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (CLASSPATH != NULL) { 33778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom parsed->class_path_string_ = CLASSPATH; 33878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 33969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 34078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom CreateClassPath(parsed->class_path_string_, parsed->class_path_); 34169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 34269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 34385d1545e985ac689db4bad7849880e843707c862Elliott Hughes LOG(INFO) << "CheckJNI is " << (parsed->check_jni_ ? "on" : "off"); 34485d1545e985ac689db4bad7849880e843707c862Elliott Hughes 34569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return parsed.release(); 3468a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom} 3478a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 3488a436595d36c1e4935984fcac249d7d877e00383Brian CarlstromRuntime* Runtime::Create(const Options& options, bool ignore_unrecognized) { 3492ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 3502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro if (Runtime::instance_ != NULL) { 3512ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return NULL; 3522ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 353dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes instance_ = new Runtime; 354dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes if (!instance_->Init(options, ignore_unrecognized)) { 355dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes delete instance_; 356dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes instance_ = NULL; 35761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro } 35869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return instance_; 35969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 3600af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 36169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromvoid Runtime::Start() { 362038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes InitNativeMethods(); 36385d1545e985ac689db4bad7849880e843707c862Elliott Hughes 364038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes Thread::FinishStartup(); 36585d1545e985ac689db4bad7849880e843707c862Elliott Hughes 3662a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes class_linker_->RunRootClinits(); 367f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom 3685d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom // Class::AllocObject asserts that all objects allocated better be 3695d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom // initialized after Runtime::IsStarted is true, so this needs to 3705d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom // come after ClassLinker::RunRootClinits. 3715d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom started_ = true; 3725d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom 37385d1545e985ac689db4bad7849880e843707c862Elliott Hughes StartDaemonThreads(); 37485d1545e985ac689db4bad7849880e843707c862Elliott Hughes} 37585d1545e985ac689db4bad7849880e843707c862Elliott Hughes 37685d1545e985ac689db4bad7849880e843707c862Elliott Hughesvoid Runtime::StartDaemonThreads() { 37785d1545e985ac689db4bad7849880e843707c862Elliott Hughes signal_catcher_ = new SignalCatcher; 37885d1545e985ac689db4bad7849880e843707c862Elliott Hughes 379719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes Thread* self = Thread::Current(); 380719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes JNIEnv* env = self->GetJniEnv(); 381719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes jclass c = env->FindClass("java/lang/Daemons"); 38285d1545e985ac689db4bad7849880e843707c862Elliott Hughes CHECK(c != NULL); 383719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes jmethodID mid = env->GetStaticMethodID(c, "start", "()V"); 384719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes CHECK(mid != NULL); 385719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes env->CallStaticVoidMethod(c, mid); 38661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 38761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 388dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughesbool Runtime::IsStarted() { 389dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return started_; 390dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 391dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 3920af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesbool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { 393c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize); 3946ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 39590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized)); 39690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes if (options.get() == NULL) { 39769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(WARNING) << "Failed to parse options"; 3986ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom return false; 3996ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } 4007ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 4017ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes boot_class_path_ = options->boot_class_path_string_; 4027ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes class_path_ = options->class_path_string_; 4037ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes properties_ = options->properties_; 4047ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 4050af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes vfprintf_ = options->hook_vfprintf_; 4060af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes exit_ = options->hook_exit_; 4070af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes abort_ = options->hook_abort_; 4086ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 409be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes default_stack_size_ = options->stack_size_; 4106ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 41114357e842b611279d467b64d450c569af33a6936Elliott Hughes thread_list_ = new ThreadList(options->IsVerbose("thread")); 412cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes intern_table_ = new InternTable; 413cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes 414be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Heap::Init(options->heap_initial_size_, options->heap_maximum_size_, 415be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes options->boot_image_, options->images_); 4166ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 417c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes BlockSignals(); 418c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 419a09576416788b916095739e43a16917e7948f3a4Elliott Hughes java_vm_ = new JavaVMExt(this, options.get()); 420515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes 421be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Thread::Startup(); 422d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 4235fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes // ClassLinker needs an attached thread, but we can't fully attach a thread 4245fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes // without creating objects. 4255fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Thread::Attach(this, "main", false); 4266ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 42769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom class_linker_ = ClassLinker::Create(options->boot_class_path_, 42869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options->class_path_, 42969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom intern_table_, 43069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Heap::GetBootSpace()); 4316ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 4327b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro return true; 4337b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 4347b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 435038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughesvoid Runtime::InitNativeMethods() { 436ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread* self = Thread::Current(); 437ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes JNIEnv* env = self->GetJniEnv(); 438ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 439418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Must be in the kNative state for calling native methods (JNI_OnLoad code). 440ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes ScopedThreadStateChange tsc(self, Thread::kNative); 441ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 442418d20fc407052d4152157f61e7453359f902383Elliott Hughes // First set up JniConstants, which is used by both the runtime's built-in native 443418d20fc407052d4152157f61e7453359f902383Elliott Hughes // methods and libcore. 444fea966e51e65f2040e1510a2e39d407baad29b2cElliott Hughes JniConstants::init(env); 445fea966e51e65f2040e1510a2e39d407baad29b2cElliott Hughes 446418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Then set up the native methods provided by the runtime itself. 447ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes RegisterRuntimeNativeMethods(env); 448ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 449418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad. 450418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's 451418d20fc407052d4152157f61e7453359f902383Elliott Hughes // the library that implements System.loadLibrary! 452ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes LoadJniLibrary(instance_->GetJavaVM(), "javacore"); 453ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes} 454ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 455ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesvoid Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { 456ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes#define REGISTER(FN) extern void FN(JNIEnv*); FN(env) 457f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom REGISTER(register_dalvik_system_DexFile); 4589d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes REGISTER(register_dalvik_system_VMDebug); 4597ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes REGISTER(register_dalvik_system_VMRuntime); 4608daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes REGISTER(register_dalvik_system_VMStack); 46101158d7a57c8321370667a6045220237d16e0da8Elliott Hughes REGISTER(register_dalvik_system_Zygote); 462d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes REGISTER(register_java_lang_Class); 463bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_Object); 464bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_Runtime); 465bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_String); 466bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_System); 4678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes REGISTER(register_java_lang_Thread); 4681240dade91d6c4bbf4e367ca608fcdc15348da45Elliott Hughes REGISTER(register_java_lang_Throwable); 46964bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes REGISTER(register_java_lang_VMClassLoader); 470ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes //REGISTER(register_java_lang_reflect_AccessibleObject); 4715b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom REGISTER(register_java_lang_reflect_Array); 4722a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes REGISTER(register_java_lang_reflect_Constructor); 473f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom REGISTER(register_java_lang_reflect_Field); 474f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom REGISTER(register_java_lang_reflect_Method); 475ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes //REGISTER(register_java_lang_reflect_Proxy); 476bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_util_concurrent_atomic_AtomicLong); 477395520eaa47eca25b92e86188accf3095d60af49Brian Carlstrom REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer); 478ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes //REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal); 4795ee7a8b56dee896245e0f4ae5215f8b7376c1787Elliott Hughes REGISTER(register_sun_misc_Unsafe); 480ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes#undef REGISTER 481ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes} 482ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 4838daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesvoid Runtime::Dump(std::ostream& os) { 484e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // TODO: dump other runtime statistics? 485e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes os << "Loaded classes: " << class_linker_->NumLoadedClasses() << "\n"; 486cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes os << "Intern table size: " << GetInternTable()->Size() << "\n"; 487e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // LOGV("VM stats: meth=%d ifld=%d sfld=%d linear=%d", 488e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // gDvm.numDeclaredMethods, 489e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // gDvm.numDeclaredInstFields, 490e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // gDvm.numDeclaredStaticFields, 491e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // gDvm.pBootLoaderAlloc->curOffset); 492e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes // LOGI("GC precise methods: %d", dvmPointerSetGetCount(gDvm.preciseMethods)); 49342ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes os << "\n"; 4948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 4958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes thread_list_->Dump(os); 496e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes} 497e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 4989d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid Runtime::SetStatsEnabled(bool new_state) { 4999d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (new_state == true) { 5009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes GetStats()->Clear(~0); 5019d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // TODO: wouldn't it make more sense to clear _all_ threads' stats? 5029d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Thread::Current()->GetStats()->Clear(~0); 5039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 5049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats_enabled_ = new_state; 5059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 5069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 5079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid Runtime::ResetStats(int kinds) { 5089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes GetStats()->Clear(kinds & 0xffff); 5099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // TODO: wouldn't it make more sense to clear _all_ threads' stats? 5109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Thread::Current()->GetStats()->Clear(kinds >> 16); 5119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 5129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 5139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott HughesRuntimeStats* Runtime::GetStats() { 5149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return &stats_; 5159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 5169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 5179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesint32_t Runtime::GetStat(int kind) { 5189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes RuntimeStats* stats; 5199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (kind < (1<<16)) { 5209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats = GetStats(); 5219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } else { 5229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats = Thread::Current()->GetStats(); 5239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes kind >>= 16; 5249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 5259d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes switch (kind) { 5269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_ALLOCATED_OBJECTS: 5279d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->allocated_objects; 5289d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_ALLOCATED_BYTES: 5299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->allocated_bytes; 5309d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_FREED_OBJECTS: 5319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->freed_objects; 5329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_FREED_BYTES: 5339d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->freed_bytes; 5349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_GC_INVOCATIONS: 5359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->gc_for_alloc_count; 5369d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_CLASS_INIT_COUNT: 5379d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->class_init_count; 5389d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_CLASS_INIT_TIME: 5399d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // Convert ns to us, reduce to 32 bits. 5409d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return (int) (stats->class_init_time_ns / 1000); 5419d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_ALLOCATED_OBJECTS: 5429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_ALLOCATED_BYTES: 5439d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_FREED_OBJECTS: 5449d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_FREED_BYTES: 5459d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return 0; // backward compatibility 5469d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes default: 5479d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes CHECK(false); 5489d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return -1; // unreachable 5499d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 5509d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 5519d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 552c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughesvoid Runtime::BlockSignals() { 553c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes sigset_t sigset; 554c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes if (sigemptyset(&sigset) == -1) { 555c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes PLOG(FATAL) << "sigemptyset failed"; 556c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes } 557c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes if (sigaddset(&sigset, SIGPIPE) == -1) { 558c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes PLOG(ERROR) << "sigaddset SIGPIPE failed"; 559c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes } 560c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes // SIGQUIT is used to dump the runtime's state (including stack traces). 561c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes if (sigaddset(&sigset, SIGQUIT) == -1) { 562c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes PLOG(ERROR) << "sigaddset SIGQUIT failed"; 563c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes } 564c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes // SIGUSR1 is used to initiate a heap dump. 565c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes if (sigaddset(&sigset, SIGUSR1) == -1) { 566c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes PLOG(ERROR) << "sigaddset SIGUSR1 failed"; 567c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes } 568c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes CHECK_EQ(sigprocmask(SIG_BLOCK, &sigset, NULL), 0); 569c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 570c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 5715fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughesvoid Runtime::AttachCurrentThread(const char* name, bool as_daemon) { 5725fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Thread::Attach(instance_, name, as_daemon); 57361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 57461e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 575d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughesvoid Runtime::DetachCurrentThread() { 576038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // TODO: check we're not calling DetachCurrentThread from a call stack that 577038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // includes managed frames. (It's only valid if the stack is all-native.) 57802b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes thread_list_->Unregister(); 5797b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 5807b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 581ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian RogersMethod* Runtime::CreateCalleeSaveMethod(InstructionSet insns) { 582ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers Class* method_class = Method::GetMethodClass(); 583ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers Method* method = down_cast<Method*>(method_class->AllocObject()); 584ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetDeclaringClass(method_class); 585ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetName(intern_table_->InternStrong("$$$callee_save_method$$$")); 586ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetSignature(intern_table_->InternStrong("()V")); 587ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetCode(NULL, insns, NULL); 588ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers if ((insns == kThumb2) || (insns == kArm)) { 58915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers size_t frame_size = (12 /* gprs */ + 32 /* fprs */ + 4 /* data */) * kPointerSize; 59015fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers method->SetFrameSizeInBytes(frame_size); 59115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers method->SetReturnPcOffsetInBytes(frame_size - kPointerSize); 592ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetCoreSpillMask((1 << art::arm::R1) | 593ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R2) | 594ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R3) | 595ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R4) | 596ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R5) | 597ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R6) | 598ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R7) | 599ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R8) | 600ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R9) | 601ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R10) | 602ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::R11) | 603ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::arm::LR)); 60415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers method->SetFpSpillMask((1 << art::arm::S0) | 60515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S1) | 60615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S2) | 60715fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S3) | 60815fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S4) | 60915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S5) | 61015fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S6) | 61115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S7) | 61215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S8) | 61315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S9) | 61415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S10) | 61515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S11) | 61615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S12) | 61715fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S13) | 61815fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S14) | 61915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S15) | 62015fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S16) | 62115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S17) | 62215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S18) | 62315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S19) | 62415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S20) | 62515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S21) | 62615fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S22) | 62715fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S23) | 62815fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S24) | 62915fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S25) | 63015fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S26) | 63115fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S27) | 63215fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S28) | 63315fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S29) | 63415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S30) | 63515fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers (1 << art::arm::S31)); 636ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } else if (insns == kX86) { 637ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetFrameSizeInBytes(32); 638ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetReturnPcOffsetInBytes(28); 639ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetCoreSpillMask((1 << art::x86::EBX) | 640ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::x86::EBP) | 641ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::x86::ESI) | 642ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers (1 << art::x86::EDI)); 643ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetFpSpillMask(0); 644ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } else { 645ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers UNIMPLEMENTED(FATAL); 646ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } 647ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers return method; 648ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers} 649ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers 650410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughesvoid Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) const { 651410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes class_linker_->VisitRoots(visitor, arg); 652410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes intern_table_->VisitRoots(visitor, arg); 653410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes java_vm_->VisitRoots(visitor, arg); 654410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes thread_list_->VisitRoots(visitor, arg); 655161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom visitor(jni_stub_array_, arg); 656ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers visitor(callee_save_method_, arg); 657410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 658410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes //(*visitor)(&gDvm.outOfMemoryObj, 0, ROOT_VM_INTERNAL, arg); 659410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes //(*visitor)(&gDvm.internalErrorObj, 0, ROOT_VM_INTERNAL, arg); 660410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes //(*visitor)(&gDvm.noClassDefFoundErrorObj, 0, ROOT_VM_INTERNAL, arg); 661410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes UNIMPLEMENTED(WARNING) << "some roots not marked"; 6621f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom} 6631f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom 6646b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 665