runtime.cc revision 6c1c69eea21cce39dd043d89368a684d250c9abe
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 166b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro 17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "runtime.h" 187b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 19dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom#include <signal.h> 20dbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1Brian Carlstrom 21ffe6736397d17457188727510f0a2953f69a383aElliott Hughes#include <cstdio> 22ffe6736397d17457188727510f0a2953f69a383aElliott Hughes#include <cstdlib> 238a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom#include <limits> 242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include <vector> 25b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa#include <fstream> 26ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 27578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "class_linker.h" 28aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom#include "class_loader.h" 290f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_arm.h" 300f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include "constants_x86.h" 313bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes#include "debugger.h" 32578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "heap.h" 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "image.h" 34cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes#include "intern_table.h" 35c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes#include "jni_internal.h" 3632d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes#include "monitor.h" 37e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_file.h" 38726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes#include "ScopedLocalRef.h" 39e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes#include "signal_catcher.h" 40457005c557b8762475db3220ce5a747d629f975bElliott Hughes#include "signal_set.h" 41e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "space.h" 42578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "thread.h" 438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread_list.h" 44b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao#include "trace.h" 453bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes#include "UniquePtr.h" 46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "verifier/method_verifier.h" 4761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 4890a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes// TODO: this drags in cutil/log.h, which conflicts with our logging.h. 4990a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes#include "JniConstants.h" 5090a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes 516b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 527b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 532ed144c2b49ae1da6c464d7a1be0062870530802Carl ShapiroRuntime* Runtime::instance_ = NULL; 542ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 55dcc247493fd8fb243e335c3ec08e5e625896a47cElliott HughesRuntime::Runtime() 56d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes : is_compiler_(false), 57d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes is_zygote_(false), 580a5b14de5115f51e0ed2dd6c3fcc5b84bbce690eBrian Carlstrom default_stack_size_(Thread::kDefaultStackSize), 59b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes heap_(NULL), 60c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes monitor_list_(NULL), 61dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes thread_list_(NULL), 62dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes intern_table_(NULL), 63dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes class_linker_(NULL), 64dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes signal_catcher_(NULL), 65dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes java_vm_(NULL), 66161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom jni_stub_array_(NULL), 67e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom abstract_method_error_stub_array_(NULL), 681984651929744dd603fd082e23eacd877b9bc177Ian Rogers resolution_method_(NULL), 697c3757fb51450d0669883c82375040ece051e189Ian Rogers system_class_loader_(NULL), 706b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes shutting_down_(false), 71dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes started_(false), 72dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes vfprintf_(NULL), 73dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes exit_(NULL), 749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes abort_(NULL), 752692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao stats_enabled_(false), 76776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers method_trace_(0), 77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers method_trace_file_size_(0), 78b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes tracer_(NULL), 79b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes use_compile_time_class_path_(false) { 804f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 814f0d07c783afef89703dce32c94440fc8621a29bIan Rogers resolution_stub_array_[i] = NULL; 824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 834f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 844f0d07c783afef89703dce32c94440fc8621a29bIan Rogers callee_save_method_[i] = NULL; 854f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 86dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 87dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 8861e019d291583029c01b61b93bea750f2b663c37Carl ShapiroRuntime::~Runtime() { 896b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes shutting_down_ = true; 906b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes 91b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao if (IsMethodTracingActive()) { 92b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao Trace::Shutdown(); 93b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao } 94b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao 955fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes // Make sure our internal threads are dead before we start tearing down things they're using. 96e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes Dbg::StopJdwp(); 975fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes delete signal_catcher_; 985fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes 99038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended. 10093e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes delete thread_list_; 101c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes delete monitor_list_; 10293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 10361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro delete class_linker_; 104b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes delete heap_; 105dd361c9eab3284e76e2d07c2e7d371b0f5269942Logan Chien#if defined(ART_USE_LLVM_COMPILER) 106776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers verifier::MethodVerifier::DeleteInferredRegCategoryMaps(); 107dd361c9eab3284e76e2d07c2e7d371b0f5269942Logan Chien#endif 108776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers verifier::MethodVerifier::DeleteGcMaps(); 109cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes delete intern_table_; 110c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes delete java_vm_; 111c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes Thread::Shutdown(); 1124acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 1134a289ed61242964b921434de7d375f46480472a1Brian Carlstrom CHECK(instance_ == NULL || instance_ == this); 1144acf4646fbbd6c1893cec5bb700d3c7cd09e4a26Carl Shapiro instance_ = NULL; 11561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 11661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 117cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughesstatic bool gAborting = false; 118cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 119e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughesstruct AbortState { 120e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes void Dump(std::ostream& os) { 121cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes if (gAborting) { 122cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes os << "Runtime aborting --- recursively, so no thread-specific detail!\n"; 123cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes return; 124cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes } 125cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes gAborting = true; 126e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes os << "Runtime aborting...\n"; 1276c7d244058b74cdd61533968dd6cddd7003d2671Elliott Hughes if (Runtime::Current() == NULL) { 1286c7d244058b74cdd61533968dd6cddd7003d2671Elliott Hughes os << "(Runtime does not yet exist!)\n"; 1296c7d244058b74cdd61533968dd6cddd7003d2671Elliott Hughes return; 1306c7d244058b74cdd61533968dd6cddd7003d2671Elliott Hughes } 131e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes Thread* self = Thread::Current(); 132e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes if (self == NULL) { 133e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes os << "(Aborting thread was not attached to runtime!)\n"; 134e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes } else { 135899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes self->Dump(os); 136899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes if (self->IsExceptionPending()) { 137899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes os << "Pending " << PrettyTypeOf(self->GetException()) << " on thread:\n" 138899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes << self->GetException()->Dump(); 139899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes } 140e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes } 141e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes } 142e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes}; 143e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes 144b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesstatic Mutex& GetAbortLock() { 145b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes static Mutex abort_lock("abort lock"); 146b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes return abort_lock; 147b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 148b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 1498593fdbacf97261f790ca53ea0ec416f57c987a7Elliott Hughesvoid Runtime::Abort() { 150131aef8c94292cc530da2fd91ee98d1432352959Elliott Hughes // Ensure that we don't have multiple threads trying to abort at once, 151131aef8c94292cc530da2fd91ee98d1432352959Elliott Hughes // which would result in significantly worse diagnostics. 152b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes MutexLock mu(GetAbortLock()); 153131aef8c94292cc530da2fd91ee98d1432352959Elliott Hughes 154ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Get any pending output out of the way. 155ffe6736397d17457188727510f0a2953f69a383aElliott Hughes fflush(NULL); 156ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 157ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // Many people have difficulty distinguish aborts from crashes, 158ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // so be explicit. 159e0918556e7551de638870dcad3f2023f94f85a50Elliott Hughes AbortState state; 1609ee5f9ccba015beb3ae376ed08b3363bd9df6422Elliott Hughes LOG(INTERNAL_FATAL) << Dumpable<AbortState>(state); 161ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 1628593fdbacf97261f790ca53ea0ec416f57c987a7Elliott Hughes // Call the abort hook if we have one. 1636ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) { 1646c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes LOG(INTERNAL_FATAL) << "Calling abort hook..."; 1656ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom Runtime::Current()->abort_(); 1666ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom // notreached 1676c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes LOG(INTERNAL_FATAL) << "Unexpectedly returned from abort hook!"; 1686ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } 1696ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 1706c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes // TODO: finish merging patches to fix abort(3) in bionic, then lose this! 1716c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes // Bionic doesn't implement POSIX semantics for abort(3) in a multi-threaded 1726c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes // process, so if we call abort(3) on a device, all threads in the process 17369759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // receive SIGABRT. debuggerd dumps the stack trace of the main 17469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // thread, whether or not that was the thread that failed. By 17569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // stuffing a value into a bogus address, we cause a segmentation 176ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // fault in the current thread, and get a useful log from debuggerd. 17781ff3184e7eb8de4605c7646674ea4f9fa29b5f3Elliott Hughes // We can also trivially tell the difference between a crash and 178ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // a deliberate abort by looking at the fault address. 179ffe6736397d17457188727510f0a2953f69a383aElliott Hughes *reinterpret_cast<char*>(0xdeadd00d) = 38; 180ffe6736397d17457188727510f0a2953f69a383aElliott Hughes abort(); 181ffe6736397d17457188727510f0a2953f69a383aElliott Hughes // notreached 182ffe6736397d17457188727510f0a2953f69a383aElliott Hughes} 183ffe6736397d17457188727510f0a2953f69a383aElliott Hughes 184bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughesvoid Runtime::CallExitHook(jint status) { 185bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes if (exit_ != NULL) { 18634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes ScopedThreadStateChange tsc(Thread::Current(), kNative); 187bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes exit_(status); 188bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes LOG(WARNING) << "Exit hook returned instead of exiting!"; 189bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes } 190bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes} 191bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes 1928a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify 1938a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// memory sizes. [kK] indicates kilobytes, [mM] megabytes, and 1948a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// [gG] gigabytes. 1958a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 1968a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// "s" should point just past the "-Xm?" part of the string. 1978a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// "div" specifies a divisor, e.g. 1024 if the value must be a multiple 1988a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// of 1024. 1998a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 2008a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// The spec says the -Xmx and -Xms options must be multiples of 1024. It 2018a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// doesn't say anything about -Xss. 2028a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 2038a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// Returns 0 (a useless size) if "s" is malformed or specifies a low or 2048a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// non-evenly-divisible value. 2058a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom// 206c1f143de3d0370a17a4561eb83bf10a5d7908aa3Elliott Hughessize_t ParseMemoryOption(const char* s, size_t div) { 2078a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // strtoul accepts a leading [+-], which we don't want, 2088a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // so make sure our string starts with a decimal digit. 2098a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (isdigit(*s)) { 210398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes char* s2; 211398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes size_t val = strtoul(s, &s2, 10); 2128a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (s2 != s) { 2138a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // s2 should be pointing just after the number. 2148a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // If this is the end of the string, the user 2158a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // has specified a number of bytes. Otherwise, 2168a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // there should be exactly one more character 2178a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // that specifies a multiplier. 2188a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (*s2 != '\0') { 219f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // The remainder of the string is either a single multiplier 220f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // character, or nothing to indicate that the value is in 221f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // bytes. 222f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom char c = *s2++; 223f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (*s2 == '\0') { 224f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom size_t mul; 225f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (c == '\0') { 226f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = 1; 227f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'k' || c == 'K') { 228f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = KB; 229f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'm' || c == 'M') { 230f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = MB; 231f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else if (c == 'g' || c == 'G') { 232f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom mul = GB; 2338a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else { 234f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // Unknown multiplier character. 2358a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return 0; 2368a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 237f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom 238f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (val <= std::numeric_limits<size_t>::max() / mul) { 239f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom val *= mul; 240f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else { 241f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // Clamp to a multiple of 1024. 242f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom val = std::numeric_limits<size_t>::max() & ~(1024-1); 243f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 244f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } else { 245f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom // There's more than one character after the numeric part. 246f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return 0; 247f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 2488a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 2498a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom // The man page says that a -Xm value must be a multiple of 1024. 2508a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (val % div == 0) { 2518a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return val; 2528a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 253fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 254fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro } 2558a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom return 0; 256fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro} 257fc322c72d7a89a6f7a05c8bdc232d780aecd9232Carl Shapiro 258f1a5adc87760f938b01df26d906295063546b259Elliott Hughessize_t ParseIntegerOrDie(const std::string& s) { 259f1a5adc87760f938b01df26d906295063546b259Elliott Hughes std::string::size_type colon = s.find(':'); 260f1a5adc87760f938b01df26d906295063546b259Elliott Hughes if (colon == std::string::npos) { 261bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes LOG(FATAL) << "Missing integer: " << s; 262bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes } 263f1a5adc87760f938b01df26d906295063546b259Elliott Hughes const char* begin = &s[colon + 1]; 264bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes char* end; 265bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes size_t result = strtoul(begin, &end, 10); 266bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes if (begin == end || *end != '\0') { 267bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes LOG(FATAL) << "Failed to parse integer in: " << s; 268bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes } 269bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes return result; 270bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes} 271bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes 2720af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesvoid LoadJniLibrary(JavaVMExt* vm, const char* name) { 2736cc332ef80edf56221676e33ea16bb4022130344Elliott Hughes std::string mapped_name(StringPrintf(OS_SHARED_LIB_FORMAT_STR, name)); 2747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes std::string reason; 2757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (!vm->LoadNativeLibrary(mapped_name, NULL, reason)) { 2760af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": " 2770af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes << reason; 2780af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 2790af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes} 2800af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 2816ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian CarlstromRuntime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) { 28290a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<ParsedOptions> parsed(new ParsedOptions()); 283a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const char* boot_class_path_string = getenv("BOOTCLASSPATH"); 284a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom if (boot_class_path_string != NULL) { 285a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->boot_class_path_string_ = boot_class_path_string; 28658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 287a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const char* class_path_string = getenv("CLASSPATH"); 288a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom if (class_path_string != NULL) { 289a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->class_path_string_ = class_path_string; 29058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 29167d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes // -Xcheck:jni is off by default for regular builds but on by default in debug builds. 29267d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes parsed->check_jni_ = kIsDebugBuild; 29385d1545e985ac689db4bad7849880e843707c862Elliott Hughes 2946ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->heap_initial_size_ = Heap::kInitialSize; 2956ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->heap_maximum_size_ = Heap::kMaximumSize; 296c11607024d2e7a52ca690b8339306cab040e6653jeffhao parsed->heap_growth_limit_ = 0; // 0 means no growth limit 297f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->stack_size_ = Thread::kDefaultStackSize; 298f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom 299d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes parsed->is_compiler_ = false; 3009ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes parsed->is_zygote_ = false; 3019ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes 302bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes parsed->jni_globals_max_ = 0; 303fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes parsed->lock_profiling_threshold_ = 0; 304fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes parsed->hook_is_sensitive_thread_ = NULL; 305fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 3066ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_vfprintf_ = vfprintf; 3076ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_exit_ = exit; 3086c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes parsed->hook_abort_ = NULL; // We don't call abort(3) by default; see Runtime::Abort. 3096c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes#if defined(__APPLE__) 3106c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes parsed->hook_abort_ = abort; // On the Mac, abort(3) gives better results; see Runtime::InitPlatformSignalHandlers. 3116c1c69eea21cce39dd043d89368a684d250c9abeElliott Hughes#endif 3128a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 313b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.class_linker = true; // TODO: don't check this in! 314b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.compiler = true; // TODO: don't check this in! 315b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.heap = true; // TODO: don't check this in! 316b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.gc = true; // TODO: don't check this in! 317b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.jdwp = true; // TODO: don't check this in! 318b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.jni = true; // TODO: don't check this in! 319b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.monitor = true; // TODO: don't check this in! 320b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.startup = true; // TODO: don't check this in! 321b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.third_party_jni = true; // TODO: don't check this in! 322b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes// gLogVerbosity.threads = true; // TODO: don't check this in! 323b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 324b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_ = false; 325b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_file_ = "/data/method-trace-file.bin"; 326b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_file_size_ = 10 * MB; 327b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao 3288a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom for (size_t i = 0; i < options.size(); ++i) { 329f1a5adc87760f938b01df26d906295063546b259Elliott Hughes const std::string option(options[i].first); 3300796af03edc06d92bb8d631f1c0c23befdae2315Brian Carlstrom if (true && options[0].first == "-Xzygote") { 33158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom LOG(INFO) << "option[" << i << "]=" << option; 33258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 333f1a5adc87760f938b01df26d906295063546b259Elliott Hughes if (StartsWith(option, "-Xbootclasspath:")) { 334a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data(); 33569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option == "-classpath" || option == "-cp") { 33669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: support -Djava.class.path 33769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom i++; 33869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (i == options.size()) { 33969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // TODO: usage 34069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Missing required class path value for " << option; 34169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return NULL; 34269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 343a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const StringPiece& value = options[i].first; 344a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->class_path_string_ = value.data(); 345a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom } else if (option == "bootclasspath") { 346a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->boot_class_path_ 347a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom = reinterpret_cast<const std::vector<const DexFile*>*>(options[i].second); 348f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Ximage:")) { 349a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom parsed->image_ = option.substr(strlen("-Ximage:")).data(); 350f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xcheck:jni")) { 351515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes parsed->check_jni_ = true; 352f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xrunjdwp:") || StartsWith(option, "-agentlib:jdwp=")) { 353f1a5adc87760f938b01df26d906295063546b259Elliott Hughes std::string tail(option.substr(option[1] == 'X' ? 10 : 15)); 3543bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes if (tail == "help" || !Dbg::ParseJdwpOptions(tail)) { 3553bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes LOG(FATAL) << "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n" 3563bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes << "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n"; 3573bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes return NULL; 3583bb81563481d02b5a6349b8ed918392454e761d8Elliott Hughes } 359f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xms")) { 360f1a5adc87760f938b01df26d906295063546b259Elliott Hughes size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).c_str(), 1024); 361f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 362f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 363f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 364f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 3654a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 36669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 367f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 368f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 369f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->heap_initial_size_ = size; 370f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xmx")) { 371f1a5adc87760f938b01df26d906295063546b259Elliott Hughes size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).c_str(), 1024); 372f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 373f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 374f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 375f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 3764a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 37769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 378f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 379f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 380f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->heap_maximum_size_ = size; 381f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-XX:HeapGrowthLimit=")) { 382f1a5adc87760f938b01df26d906295063546b259Elliott Hughes size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapGrowthLimit=")).c_str(), 1024); 383c11607024d2e7a52ca690b8339306cab040e6653jeffhao if (size == 0) { 384c11607024d2e7a52ca690b8339306cab040e6653jeffhao if (ignore_unrecognized) { 385c11607024d2e7a52ca690b8339306cab040e6653jeffhao continue; 386c11607024d2e7a52ca690b8339306cab040e6653jeffhao } 387c11607024d2e7a52ca690b8339306cab040e6653jeffhao // TODO: usage 388c11607024d2e7a52ca690b8339306cab040e6653jeffhao LOG(FATAL) << "Failed to parse " << option; 389c11607024d2e7a52ca690b8339306cab040e6653jeffhao return NULL; 390c11607024d2e7a52ca690b8339306cab040e6653jeffhao } 391c11607024d2e7a52ca690b8339306cab040e6653jeffhao parsed->heap_growth_limit_ = size; 392f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xss")) { 393f1a5adc87760f938b01df26d906295063546b259Elliott Hughes size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).c_str(), 1); 394f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (size == 0) { 395f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom if (ignore_unrecognized) { 396f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom continue; 397f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 3984a289ed61242964b921434de7d375f46480472a1Brian Carlstrom // TODO: usage 39969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom LOG(FATAL) << "Failed to parse " << option; 400f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom return NULL; 401f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom } 402f734cf55d510976f4862b15e35fc86eae2a3daf8Brian Carlstrom parsed->stack_size_ = size; 403f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-D")) { 404f1a5adc87760f938b01df26d906295063546b259Elliott Hughes parsed->properties_.push_back(option.substr(strlen("-D"))); 405f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xjnitrace:")) { 406f1a5adc87760f938b01df26d906295063546b259Elliott Hughes parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:")); 4075de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom } else if (option == "compiler") { 408d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes parsed->is_compiler_ = true; 4099ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes } else if (option == "-Xzygote") { 4109ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes parsed->is_zygote_ = true; 411f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-verbose:")) { 4120af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes std::vector<std::string> verbose_options; 413f1a5adc87760f938b01df26d906295063546b259Elliott Hughes Split(option.substr(strlen("-verbose:")), ',', verbose_options); 4140af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes for (size_t i = 0; i < verbose_options.size(); ++i) { 4154dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes if (verbose_options[i] == "class") { 4164dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.class_linker = true; 4174dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "compiler") { 4184dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.compiler = true; 4194dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "heap") { 4204dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.heap = true; 4214dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "gc") { 4224dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.gc = true; 4234dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "jdwp") { 4244dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.jdwp = true; 4254dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "jni") { 4264dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.jni = true; 4274dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "monitor") { 4284dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.monitor = true; 4294dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "startup") { 4304dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.startup = true; 4314dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "third-party-jni") { 4324dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.third_party_jni = true; 4334dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else if (verbose_options[i] == "threads") { 4344dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes gLogVerbosity.threads = true; 435b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa } else if (StartsWith(verbose_options[i], "log-to=")) { 436b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa std::string log_file_name(verbose_options[i].substr(strlen("log-to="))); 437b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa std::ofstream* log_file = new std::ofstream(log_file_name.c_str()); 438b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa if (log_file->is_open() && log_file->good()) { 439b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa gLogVerbosity.SetLoggingStream(log_file); 440b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa } else { 441b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa LOG(ERROR) << "Fail to open log file: \"" << log_file_name << "\"," 442b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa << " use default logging stream."; 443b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60TDYa } 4444dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } else { 4454dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes LOG(WARNING) << "Ignoring unknown -verbose option: " << verbose_options[i]; 4464dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes } 4470af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes } 448f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xjnigreflimit:")) { 449bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes parsed->jni_globals_max_ = ParseIntegerOrDie(option); 450f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xlockprofthreshold:")) { 451bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option); 452f1a5adc87760f938b01df26d906295063546b259Elliott Hughes } else if (StartsWith(option, "-Xstacktracefile:")) { 45367d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes if (kIsDebugBuild) { 45467d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes // Ignore the zygote and always show stack traces in debug builds. 45567d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes } else { 45667d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes parsed->stack_trace_file_ = option.substr(strlen("-Xstacktracefile:")); 45767d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes } 458fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } else if (option == "sensitiveThread") { 459fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(options[i].second); 4606ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "vfprintf") { 4616ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_vfprintf_ = reinterpret_cast<int (*)(FILE *, const char*, va_list)>(options[i].second); 4626ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "exit") { 4636ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second); 4646ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } else if (option == "abort") { 4656ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second); 46658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } else if (option == "host-prefix") { 46758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second); 468b3e66dfcd069db8818cd902d787ff1d7bbca45f2Elliott Hughes } else if (option == "-Xgenregmap" || option == "-Xgc:precise") { 469b3e66dfcd069db8818cd902d787ff1d7bbca45f2Elliott Hughes // We silently ignore these for backwards compatibility. 470b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao } else if (option == "-Xmethod-trace") { 471b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_ = true; 472b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao } else if (StartsWith(option, "-Xmethod-trace-file:")) { 473b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:")); 474b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao } else if (StartsWith(option, "-Xmethod-trace-file-size:")) { 475b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao parsed->method_trace_file_size_ = ParseIntegerOrDie(option); 4768a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } else { 4778a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom if (!ignore_unrecognized) { 4786ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom // TODO: print usage via vfprintf 47927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom LOG(ERROR) << "Unrecognized option " << option; 48027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom // TODO: this should exit, but for now tolerate unknown options 48127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom //return NULL; 4828a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 4838a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 4848a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom } 4858a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 486223f20fa939c386c695977263780dea2195093dbBrian Carlstrom if (!parsed->is_compiler_ && parsed->image_.empty()) { 487223f20fa939c386c695977263780dea2195093dbBrian Carlstrom parsed->image_ += GetAndroidRoot(); 488223f20fa939c386c695977263780dea2195093dbBrian Carlstrom parsed->image_ += "/framework/boot.art"; 4895de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom } 490c11607024d2e7a52ca690b8339306cab040e6653jeffhao if (parsed->heap_growth_limit_ == 0) { 491c11607024d2e7a52ca690b8339306cab040e6653jeffhao parsed->heap_growth_limit_ = parsed->heap_maximum_size_; 492c11607024d2e7a52ca690b8339306cab040e6653jeffhao } 4935de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom 494cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes LOG(INFO) << "Build type: " 49567d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes << (kIsDebugBuild ? "debug" : "optimized") 496cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes << "; CheckJNI: " << (parsed->check_jni_ ? "on" : "off"); 49785d1545e985ac689db4bad7849880e843707c862Elliott Hughes 49869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return parsed.release(); 4998a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom} 5008a436595d36c1e4935984fcac249d7d877e00383Brian Carlstrom 5018a436595d36c1e4935984fcac249d7d877e00383Brian CarlstromRuntime* Runtime::Create(const Options& options, bool ignore_unrecognized) { 5022ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro // TODO: acquire a static mutex on Runtime to avoid racing. 5032ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro if (Runtime::instance_ != NULL) { 5042ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return NULL; 5052ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 506dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes instance_ = new Runtime; 507dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes if (!instance_->Init(options, ignore_unrecognized)) { 508dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes delete instance_; 509dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes instance_ = NULL; 51061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro } 51169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return instance_; 51269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 5130af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 514aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstromvoid CreateSystemClassLoader() { 515b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (Runtime::Current()->UseCompileTimeClassPath()) { 516aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return; 517aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 518aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 519aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom Thread* self = Thread::Current(); 520aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 521aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom // Must be in the kNative state for calling native methods. 52234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes CHECK_EQ(self->GetState(), kNative); 523aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 524aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom JNIEnv* env = self->GetJniEnv(); 525df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom ScopedLocalRef<jclass> ClassLoader_class(env, env->FindClass("java/lang/ClassLoader")); 526df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom CHECK(ClassLoader_class.get() != NULL); 527df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom jmethodID getSystemClassLoader = env->GetStaticMethodID(ClassLoader_class.get(), 528df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom "getSystemClassLoader", 529df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom "()Ljava/lang/ClassLoader;"); 530df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom CHECK(getSystemClassLoader != NULL); 531df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom ScopedLocalRef<jobject> class_loader(env, env->CallStaticObjectMethod(ClassLoader_class.get(), 532df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom getSystemClassLoader)); 533df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom CHECK(class_loader.get() != NULL); 534df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom 535df143242f4beaad4cc9fbabebfc033b68c40964eBrian Carlstrom Thread::Current()->SetClassLoaderOverride(Decode<ClassLoader*>(env, class_loader.get())); 5361b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson 5371b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson ScopedLocalRef<jclass> Thread_class(env, env->FindClass("java/lang/Thread")); 5381b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson CHECK(Thread_class.get() != NULL); 5391b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson jfieldID contextClassLoader = env->GetFieldID(Thread_class.get(), 5401b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson "contextClassLoader", 5411b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson "Ljava/lang/ClassLoader;"); 5421b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson CHECK(contextClassLoader != NULL); 5431b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson ScopedLocalRef<jobject> self_jobject(env, AddLocalReference<jobject>(env, self->GetPeer())); 5441b2b2f26c4202020d54cc7a5b9c342e6bca5b680Jesse Wilson env->SetObjectField(self_jobject.get(), contextClassLoader, class_loader.get()); 545aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom} 546aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 54769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromvoid Runtime::Start() { 5484dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::Start entering"; 54958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom 55058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom CHECK(host_prefix_.empty()) << host_prefix_; 55158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom 5520c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien // Relocate the OatFiles (ELF images) 5530c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien class_linker_->RelocateExecutable(); 5540c717dd1c56bd29cf860d0feda8e629dab2cadb3Logan Chien 555f28bc5b6df6edb4b22aeca360ff102a95f3155e1Brian Carlstrom // Restore main thread state to kNative as expected by native code 55634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes Thread::Current()->SetState(kNative); 557f28bc5b6df6edb4b22aeca360ff102a95f3155e1Brian Carlstrom 5585d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom started_ = true; 5595d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom 560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // InitNativeMethods needs to be after started_ so that the classes 561ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // it touches will have methods linked to the oat file if necessary. 562ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom InitNativeMethods(); 563ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 5649a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson Thread::FinishStartup(); 5659a6bae896a2f003d7216603bf29771d105c10ca4Jesse Wilson 566d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes if (!is_zygote_) { 567d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes DidForkFromZygote(); 568d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes } 5699ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes 57085d1545e985ac689db4bad7849880e843707c862Elliott Hughes StartDaemonThreads(); 5710a5b14de5115f51e0ed2dd6c3fcc5b84bbce690eBrian Carlstrom 572aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CreateSystemClassLoader(); 573aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 574726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes Thread::Current()->GetJniEnv()->locals.AssertEmpty(); 575726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes 5764dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::Start exiting"; 57785d1545e985ac689db4bad7849880e843707c862Elliott Hughes} 57885d1545e985ac689db4bad7849880e843707c862Elliott Hughes 579caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Runtime::DidForkFromZygote() { 580caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom is_zygote_ = false; 581d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes 582caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom StartSignalCatcher(); 583d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes 584d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes // Start the JDWP thread. If the command-line debugger flags specified "suspend=y", 585d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes // this will pause the runtime, so we probably want this to come last. 586d1cc8363d4f4bbac7568b1d02a5ca481cd10830fElliott Hughes Dbg::StartJdwp(); 587caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 588caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 589caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstromvoid Runtime::StartSignalCatcher() { 590caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom if (!is_zygote_) { 59194ce37a3919a0bdb8855a3d3264a50df1dbc41beElliott Hughes signal_catcher_ = new SignalCatcher(stack_trace_file_); 592caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom } 593caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom} 594caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom 59585d1545e985ac689db4bad7849880e843707c862Elliott Hughesvoid Runtime::StartDaemonThreads() { 5964dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::StartDaemonThreads entering"; 59785d1545e985ac689db4bad7849880e843707c862Elliott Hughes 598719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes Thread* self = Thread::Current(); 599aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 600aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom // Must be in the kNative state for calling native methods. 60134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes CHECK_EQ(self->GetState(), kNative); 602aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 603719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes JNIEnv* env = self->GetJniEnv(); 604726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes ScopedLocalRef<jclass> c(env, env->FindClass("java/lang/Daemons")); 605726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes CHECK(c.get() != NULL); 606726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes jmethodID mid = env->GetStaticMethodID(c.get(), "start", "()V"); 607719b323e6a290a075239ac8f4b664e23fd3190f4Elliott Hughes CHECK(mid != NULL); 608726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes env->CallStaticVoidMethod(c.get(), mid); 6098cf5bc0ab8742df107f0f4fc8ec0e991b6568f11Elliott Hughes CHECK(!env->ExceptionCheck()); 6109ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes 6114dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::StartDaemonThreads exiting"; 61261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 61361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 6146b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughesbool Runtime::IsShuttingDown() const { 6156b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes return shutting_down_; 6166b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes} 6176b3557571e798b60df995f978fa01c0ca1980dfdElliott Hughes 61858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrombool Runtime::IsStarted() const { 619dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes return started_; 620dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes} 621dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes 6220af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesbool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { 623c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize); 6246ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 62590a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized)); 62690a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes if (options.get() == NULL) { 627e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom LOG(ERROR) << "Failed to parse options"; 6286ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom return false; 6296ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom } 6304dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::Init -verbose:startup enabled"; 6317ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 632bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes SetJniGlobalsMax(options->jni_globals_max_); 6334dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_); 63432d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes 63558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom host_prefix_ = options->host_prefix_; 636a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom boot_class_path_string_ = options->boot_class_path_string_; 637a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom class_path_string_ = options->class_path_string_; 6387ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes properties_ = options->properties_; 6397ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 640d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes is_compiler_ = options->is_compiler_; 6419ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes is_zygote_ = options->is_zygote_; 6429ca7a1fdd0daa546b790adb6a24dbc13c22df76aElliott Hughes 6430af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes vfprintf_ = options->hook_vfprintf_; 6440af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes exit_ = options->hook_exit_; 6450af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes abort_ = options->hook_abort_; 6466ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 647be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes default_stack_size_ = options->stack_size_; 64894ce37a3919a0bdb8855a3d3264a50df1dbc41beElliott Hughes stack_trace_file_ = options->stack_trace_file_; 6496ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 650c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes monitor_list_ = new MonitorList; 6514dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes thread_list_ = new ThreadList; 652cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes intern_table_ = new InternTable; 653cf4c6c41b0084dc4567ff709fb8ce9ebd72b26acElliott Hughes 654776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers verifier::MethodVerifier::InitGcMaps(); 655b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 656dd361c9eab3284e76e2d07c2e7d371b0f5269942Logan Chien#if defined(ART_USE_LLVM_COMPILER) 657776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers verifier::MethodVerifier::InitInferredRegCategoryMaps(); 658dd361c9eab3284e76e2d07c2e7d371b0f5269942Logan Chien#endif 659dd361c9eab3284e76e2d07c2e7d371b0f5269942Logan Chien 660b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes heap_ = new Heap(options->heap_initial_size_, 661b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes options->heap_growth_limit_, 662b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes options->heap_maximum_size_, 663b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes options->image_); 6646ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 665c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes BlockSignals(); 666457005c557b8762475db3220ce5a747d629f975bElliott Hughes InitPlatformSignalHandlers(); 667c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 668a09576416788b916095739e43a16917e7948f3a4Elliott Hughes java_vm_ = new JavaVMExt(this, options.get()); 669515a5bc89282d6f910cae4d5852bb77124a47825Elliott Hughes 670be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Thread::Startup(); 671d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 6725fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes // ClassLinker needs an attached thread, but we can't fully attach a thread 673462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // without creating objects. We can't supply a thread group yet; it will be fixed later. 674462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes Thread::Attach("main", false, NULL); 6756ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 676f28bc5b6df6edb4b22aeca360ff102a95f3155e1Brian Carlstrom // Set us to runnable so tools using a runtime can allocate and GC by default 67734e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes Thread::Current()->SetState(kRunnable); 678f28bc5b6df6edb4b22aeca360ff102a95f3155e1Brian Carlstrom 679141d62275f207bf68c55f583fb206fe586d857cfIan Rogers // Now we're attached, we can take the heap lock and validate the heap. 680141d62275f207bf68c55f583fb206fe586d857cfIan Rogers GetHeap()->EnableObjectValidation(); 681141d62275f207bf68c55f583fb206fe586d857cfIan Rogers 682b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes CHECK_GE(GetHeap()->GetSpaces().size(), 1U); 683b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (GetHeap()->GetSpaces()[0]->IsImageSpace()) { 684a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom class_linker_ = ClassLinker::CreateFromImage(intern_table_); 685a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom } else { 686a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom CHECK(options->boot_class_path_ != NULL); 687a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom CHECK_NE(options->boot_class_path_->size(), 0U); 688a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom class_linker_ = ClassLinker::CreateFromCompiler(*options->boot_class_path_, intern_table_); 689a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom } 690a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom CHECK(class_linker_ != NULL); 6916ea095ad30bf13cc00b4fee7afbbe4731a349c83Brian Carlstrom 692b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao method_trace_ = options->method_trace_; 693b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao method_trace_file_ = options->method_trace_file_; 694b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao method_trace_file_size_ = options->method_trace_file_size_; 695b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao 696b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao if (options->method_trace_) { 697b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, false); 698b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao } 699b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao 7004dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::Init exiting"; 7017b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro return true; 7027b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 7037b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 704038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughesvoid Runtime::InitNativeMethods() { 7054dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::InitNativeMethods entering"; 706ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes Thread* self = Thread::Current(); 707ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes JNIEnv* env = self->GetJniEnv(); 708ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 709418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Must be in the kNative state for calling native methods (JNI_OnLoad code). 71034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes CHECK_EQ(self->GetState(), kNative); 711ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 712418d20fc407052d4152157f61e7453359f902383Elliott Hughes // First set up JniConstants, which is used by both the runtime's built-in native 713418d20fc407052d4152157f61e7453359f902383Elliott Hughes // methods and libcore. 714fea966e51e65f2040e1510a2e39d407baad29b2cElliott Hughes JniConstants::init(env); 715fea966e51e65f2040e1510a2e39d407baad29b2cElliott Hughes 716418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Then set up the native methods provided by the runtime itself. 717ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes RegisterRuntimeNativeMethods(env); 718ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 719418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad. 720418d20fc407052d4152157f61e7453359f902383Elliott Hughes // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's 721418d20fc407052d4152157f61e7453359f902383Elliott Hughes // the library that implements System.loadLibrary! 722ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes LoadJniLibrary(instance_->GetJavaVM(), "javacore"); 7234dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(startup) << "Runtime::InitNativeMethods exiting"; 724ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes} 725ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 726ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughesvoid Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { 727ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes#define REGISTER(FN) extern void FN(JNIEnv*); FN(env) 7285167c97a4f672ba821453418e3943988fabbfc43Ian Rogers // Register Throwable first so that registration of other native methods can throw exceptions 7295167c97a4f672ba821453418e3943988fabbfc43Ian Rogers REGISTER(register_java_lang_Throwable); 730f91c8c328c922ecd522e1d3508d2603e78de8a7bBrian Carlstrom REGISTER(register_dalvik_system_DexFile); 7319d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes REGISTER(register_dalvik_system_VMDebug); 7327ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes REGISTER(register_dalvik_system_VMRuntime); 7338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes REGISTER(register_dalvik_system_VMStack); 73401158d7a57c8321370667a6045220237d16e0da8Elliott Hughes REGISTER(register_dalvik_system_Zygote); 735d369bb76dee0df2d2a106e9bf7f4e6446ed6deaaElliott Hughes REGISTER(register_java_lang_Class); 736bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_Object); 737bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_Runtime); 738bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_String); 739bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_lang_System); 7408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes REGISTER(register_java_lang_Thread); 74164bf5a33d55aa779ef452552a466943002d39e4fElliott Hughes REGISTER(register_java_lang_VMClassLoader); 7425b8e4c810a97c9dc417142b8c6e07871ae15c797Brian Carlstrom REGISTER(register_java_lang_reflect_Array); 7432a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes REGISTER(register_java_lang_reflect_Constructor); 744f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom REGISTER(register_java_lang_reflect_Field); 745f867b6f706818c886087f61b89d1e8f5fc4653cfBrian Carlstrom REGISTER(register_java_lang_reflect_Method); 74695caa791e560da97363c0c0d22bfda4a7e7377c3Jesse Wilson REGISTER(register_java_lang_reflect_Proxy); 747bf86d0438e9ef9c145ebcf16a2e74c4efaa2686aElliott Hughes REGISTER(register_java_util_concurrent_atomic_AtomicLong); 748395520eaa47eca25b92e86188accf3095d60af49Brian Carlstrom REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer); 749f6a1e1e44b94221c4e6b063b36921c712a33910bElliott Hughes REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal); 7505ee7a8b56dee896245e0f4ae5215f8b7376c1787Elliott Hughes REGISTER(register_sun_misc_Unsafe); 751ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes#undef REGISTER 752ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes} 753ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes 754c967f78cd29b6019f7cfca40a02e9b677112da70Elliott Hughesvoid Runtime::DumpForSigQuit(std::ostream& os) { 755cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes GetClassLinker()->DumpForSigQuit(os); 756cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes GetInternTable()->DumpForSigQuit(os); 757c967f78cd29b6019f7cfca40a02e9b677112da70Elliott Hughes GetHeap()->DumpForSigQuit(os); 75842ee14279065352a4b9a3e8028d02c567e847d05Elliott Hughes os << "\n"; 7598daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 760c967f78cd29b6019f7cfca40a02e9b677112da70Elliott Hughes thread_list_->DumpForSigQuit(os); 761e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes} 762e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes 76321a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughesvoid Runtime::DumpLockHolders(std::ostream& os) { 764b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes pid_t heap_lock_owner = GetHeap()->GetLockOwner(); 76521a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes pid_t thread_list_lock_owner = GetThreadList()->GetLockOwner(); 76621a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes pid_t classes_lock_owner = GetClassLinker()->GetClassesLockOwner(); 76721a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes pid_t dex_lock_owner = GetClassLinker()->GetDexLockOwner(); 76821a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes if ((heap_lock_owner | thread_list_lock_owner | classes_lock_owner | dex_lock_owner) != 0) { 76921a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes os << "Heap lock owner tid: " << heap_lock_owner << "\n" 77021a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes << "ThreadList lock owner tid: " << thread_list_lock_owner << "\n" 77121a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes << "ClassLinker classes lock owner tid: " << classes_lock_owner << "\n" 77221a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes << "ClassLinker dex lock owner tid: " << dex_lock_owner << "\n"; 77321a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes } 77421a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes} 77521a5bf2dc8c9cb3fbe5a30a88d1149c328e3aacaElliott Hughes 7769d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid Runtime::SetStatsEnabled(bool new_state) { 7779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (new_state == true) { 7789d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes GetStats()->Clear(~0); 7799d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // TODO: wouldn't it make more sense to clear _all_ threads' stats? 7809d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Thread::Current()->GetStats()->Clear(~0); 7819d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 7829d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats_enabled_ = new_state; 7839d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 7849d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 7859d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesvoid Runtime::ResetStats(int kinds) { 7869d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes GetStats()->Clear(kinds & 0xffff); 7879d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // TODO: wouldn't it make more sense to clear _all_ threads' stats? 7889d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes Thread::Current()->GetStats()->Clear(kinds >> 16); 7899d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 7909d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 7919d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott HughesRuntimeStats* Runtime::GetStats() { 7929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return &stats_; 7939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 7949d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 7959d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesint32_t Runtime::GetStat(int kind) { 7969d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes RuntimeStats* stats; 7979d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes if (kind < (1<<16)) { 7989d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats = GetStats(); 7999d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } else { 8009d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes stats = Thread::Current()->GetStats(); 8019d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes kind >>= 16; 8029d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 8039d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes switch (kind) { 8049d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_ALLOCATED_OBJECTS: 8059d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->allocated_objects; 8069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_ALLOCATED_BYTES: 8079d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->allocated_bytes; 8089d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_FREED_OBJECTS: 8099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->freed_objects; 8109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_FREED_BYTES: 8119d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->freed_bytes; 8129d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_GC_INVOCATIONS: 8139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->gc_for_alloc_count; 8149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_CLASS_INIT_COUNT: 8159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return stats->class_init_count; 8169d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_CLASS_INIT_TIME: 8179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes // Convert ns to us, reduce to 32 bits. 818398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes return static_cast<int>(stats->class_init_time_ns / 1000); 8199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_ALLOCATED_OBJECTS: 8209d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_ALLOCATED_BYTES: 8219d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_FREED_OBJECTS: 8229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes case KIND_EXT_FREED_BYTES: 8239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return 0; // backward compatibility 8249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes default: 8257b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes LOG(FATAL) << "Unknown statistic " << kind; 8269d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes return -1; // unreachable 8279d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 8289d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 8299d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 830c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughesvoid Runtime::BlockSignals() { 831457005c557b8762475db3220ce5a747d629f975bElliott Hughes SignalSet signals; 832457005c557b8762475db3220ce5a747d629f975bElliott Hughes signals.Add(SIGPIPE); 833c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes // SIGQUIT is used to dump the runtime's state (including stack traces). 834457005c557b8762475db3220ce5a747d629f975bElliott Hughes signals.Add(SIGQUIT); 8350879504b6ac72f6d93dcccf9e1b7e1769a73b230Elliott Hughes // SIGUSR1 is used to initiate a GC. 836457005c557b8762475db3220ce5a747d629f975bElliott Hughes signals.Add(SIGUSR1); 837457005c557b8762475db3220ce5a747d629f975bElliott Hughes signals.Block(); 838c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 839c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 840462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughesvoid Runtime::AttachCurrentThread(const char* thread_name, bool as_daemon, Object* thread_group) { 841462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes Thread::Attach(thread_name, as_daemon, thread_group); 84222869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes if (thread_name == NULL) { 84322869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes LOG(WARNING) << *Thread::Current() << " attached without supplying a name"; 84422869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes } 84561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro} 84661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 847d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughesvoid Runtime::DetachCurrentThread() { 84822869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes if (Thread::Current()->GetTopOfStack().GetSP() != NULL) { 84922869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes LOG(FATAL) << *Thread::Current() << " attempting to detach while still running code"; 85022869a9026a08b544eca4cefd67386d347e30d2cElliott Hughes } 85102b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes thread_list_->Unregister(); 8527b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro} 8537b21670581d13db32f1384a3b2692bcfc8f57320Carl Shapiro 854e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) const { 855bfe487be25652c5456236661b9d9c3579d2296c1Elliott Hughes Dbg::VisitRoots(visitor, arg); 856e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom class_linker_->VisitRoots(visitor, arg); 857e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom intern_table_->VisitRoots(visitor, arg); 858e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom java_vm_->VisitRoots(visitor, arg); 859e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom thread_list_->VisitRoots(visitor, arg); 860e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom visitor(jni_stub_array_, arg); 861e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom visitor(abstract_method_error_stub_array_, arg); 8624f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 8634f0d07c783afef89703dce32c94440fc8621a29bIan Rogers visitor(resolution_stub_array_[i], arg); 8644f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 8651984651929744dd603fd082e23eacd877b9bc177Ian Rogers visitor(resolution_method_, arg); 8664f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 8674f0d07c783afef89703dce32c94440fc8621a29bIan Rogers visitor(callee_save_method_[i], arg); 8684f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 869e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 870e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 871169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogersbool Runtime::HasJniDlsymLookupStub() const { 872e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return jni_stub_array_ != NULL; 873e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 874e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 875169c9a7f46776b235d0a37d5e0ff27682deffe06Ian RogersByteArray* Runtime::GetJniDlsymLookupStub() const { 876e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(jni_stub_array_ != NULL); 877e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return jni_stub_array_; 878e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 879e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 880169c9a7f46776b235d0a37d5e0ff27682deffe06Ian Rogersvoid Runtime::SetJniDlsymLookupStub(ByteArray* jni_stub_array) { 881aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(jni_stub_array != NULL) << " jni_stub_array=" << jni_stub_array; 882aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array) 883aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom << "jni_stub_array_=" << jni_stub_array_ << " jni_stub_array=" << jni_stub_array; 884e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom jni_stub_array_ = jni_stub_array; 885e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 886e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 887e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrombool Runtime::HasAbstractMethodErrorStubArray() const { 888e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return abstract_method_error_stub_array_ != NULL; 889e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 890e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 891e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian CarlstromByteArray* Runtime::GetAbstractMethodErrorStubArray() const { 892e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(abstract_method_error_stub_array_ != NULL); 893e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return abstract_method_error_stub_array_; 894e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 895e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 896e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstromvoid Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) { 897e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(abstract_method_error_stub_array != NULL); 898e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array); 899e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom abstract_method_error_stub_array_ = abstract_method_error_stub_array; 900e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 901e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 9021cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers 9031cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersRuntime::TrampolineType Runtime::GetTrampolineType(Method* method) { 9041cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers if (method == NULL) { 9051cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return Runtime::kUnknownMethod; 9061cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } else if (method->IsStatic()) { 9071cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return Runtime::kStaticMethod; 9081cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } else { 909fb6adba0d5d5505610fbd325e7911db700a2f1e8Ian Rogers return Runtime::kUnknownMethod; 9101cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } 9111cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers} 9121cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers 9131cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogersbool Runtime::HasResolutionStubArray(TrampolineType type) const { 9141cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return resolution_stub_array_[type] != NULL; 915ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 916ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 9171cb0a1dfc32531c79a968aeac26ccb5525862497Ian RogersByteArray* Runtime::GetResolutionStubArray(TrampolineType type) const { 9181cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers CHECK(HasResolutionStubArray(type)); 9194f0d07c783afef89703dce32c94440fc8621a29bIan Rogers DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType)); 9201cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers return resolution_stub_array_[type]; 921ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 922ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 9231cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogersvoid Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) { 924ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers CHECK(resolution_stub_array != NULL); 9251cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array); 9261cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers resolution_stub_array_[type] = resolution_stub_array; 927ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers} 928ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers 9291984651929744dd603fd082e23eacd877b9bc177Ian RogersMethod* Runtime::CreateResolutionMethod() { 9301984651929744dd603fd082e23eacd877b9bc177Ian Rogers Class* method_class = Method::GetMethodClass(); 9311984651929744dd603fd082e23eacd877b9bc177Ian Rogers SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject())); 9321984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetDeclaringClass(method_class); 9331984651929744dd603fd082e23eacd877b9bc177Ian Rogers // TODO: use a special method for resolution method saves 9341984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetDexMethodIndex(DexFile::kDexNoIndex16); 9351984651929744dd603fd082e23eacd877b9bc177Ian Rogers ByteArray* unknown_resolution_stub = GetResolutionStubArray(kUnknownMethod); 9361984651929744dd603fd082e23eacd877b9bc177Ian Rogers CHECK(unknown_resolution_stub != NULL); 9371984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetCode(unknown_resolution_stub->GetData()); 9381984651929744dd603fd082e23eacd877b9bc177Ian Rogers return method.get(); 9391984651929744dd603fd082e23eacd877b9bc177Ian Rogers} 9401984651929744dd603fd082e23eacd877b9bc177Ian Rogers 9411984651929744dd603fd082e23eacd877b9bc177Ian Rogersbool Runtime::HasResolutionMethod() const { 9421984651929744dd603fd082e23eacd877b9bc177Ian Rogers return resolution_method_ != NULL; 9431984651929744dd603fd082e23eacd877b9bc177Ian Rogers} 9441984651929744dd603fd082e23eacd877b9bc177Ian Rogers 9451984651929744dd603fd082e23eacd877b9bc177Ian Rogers// Returns a special method that calls into a trampoline for runtime method resolution 9461984651929744dd603fd082e23eacd877b9bc177Ian RogersMethod* Runtime::GetResolutionMethod() const { 9471984651929744dd603fd082e23eacd877b9bc177Ian Rogers CHECK(HasResolutionMethod()); 9481984651929744dd603fd082e23eacd877b9bc177Ian Rogers return resolution_method_; 9491984651929744dd603fd082e23eacd877b9bc177Ian Rogers} 9501984651929744dd603fd082e23eacd877b9bc177Ian Rogers 9511984651929744dd603fd082e23eacd877b9bc177Ian Rogersvoid Runtime::SetResolutionMethod(Method* method) { 9521984651929744dd603fd082e23eacd877b9bc177Ian Rogers resolution_method_ = method; 9531984651929744dd603fd082e23eacd877b9bc177Ian Rogers} 9541984651929744dd603fd082e23eacd877b9bc177Ian Rogers 955ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian CarlstromMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type) { 956ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers Class* method_class = Method::GetMethodClass(); 95740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject())); 958ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetDeclaringClass(method_class); 9596d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers // TODO: use a special method for callee saves 9601984651929744dd603fd082e23eacd877b9bc177Ian Rogers method->SetDexMethodIndex(DexFile::kDexNoIndex16); 9613320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom method->SetCode(NULL); 962ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if ((instruction_set == kThumb2) || (instruction_set == kArm)) { 9634f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6) | (1 << art::arm::R7) | 9644f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11); 9654f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3); 9664f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9); 9674f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills :0) | 9684f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (type == kSaveAll ? all_spills :0) | (1 << art::arm::LR); 9694f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t fp_all_spills = (1 << art::arm::S0) | (1 << art::arm::S1) | (1 << art::arm::S2) | 9704f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S3) | (1 << art::arm::S4) | (1 << art::arm::S5) | 9714f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S6) | (1 << art::arm::S7) | (1 << art::arm::S8) | 9724f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S9) | (1 << art::arm::S10) | (1 << art::arm::S11) | 9734f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S12) | (1 << art::arm::S13) | (1 << art::arm::S14) | 9744f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S15) | (1 << art::arm::S16) | (1 << art::arm::S17) | 9754f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S18) | (1 << art::arm::S19) | (1 << art::arm::S20) | 9764f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) | 9774f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) | 9784f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) | 9794f0d07c783afef89703dce32c94440fc8621a29bIan Rogers (1 << art::arm::S30) | (1 << art::arm::S31); 9804f0d07c783afef89703dce32c94440fc8621a29bIan Rogers uint32_t fp_spills = type == kSaveAll ? fp_all_spills : 0; 9814f0d07c783afef89703dce32c94440fc8621a29bIan Rogers size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ + 9824f0d07c783afef89703dce32c94440fc8621a29bIan Rogers __builtin_popcount(fp_spills) /* fprs */ + 9834f0d07c783afef89703dce32c94440fc8621a29bIan Rogers 1 /* Method* */) * kPointerSize, kStackAlignment); 98415fdb8cfb5b2e3fc882113ec0648d492cebf852cIan Rogers method->SetFrameSizeInBytes(frame_size); 9854f0d07c783afef89703dce32c94440fc8621a29bIan Rogers method->SetCoreSpillMask(core_spills); 9864f0d07c783afef89703dce32c94440fc8621a29bIan Rogers method->SetFpSpillMask(fp_spills); 987ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } else if (instruction_set == kX86) { 9887caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers uint32_t ref_spills = (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI); 9897caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers uint32_t arg_spills = (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); 9907caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) | 9917caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers (1 << art::x86::kNumberOfCpuRegisters); // fake return address callee save 9927caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ + 9937caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 1 /* Method* */) * kPointerSize, kStackAlignment); 9947caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers method->SetFrameSizeInBytes(frame_size); 9957caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers method->SetCoreSpillMask(core_spills); 996ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers method->SetFpSpillMask(0); 997ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } else { 998ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers UNIMPLEMENTED(FATAL); 999ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } 100040381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom return method.get(); 1001ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers} 1002ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers 10034f0d07c783afef89703dce32c94440fc8621a29bIan Rogersbool Runtime::HasCalleeSaveMethod(CalleeSaveType type) const { 10044f0d07c783afef89703dce32c94440fc8621a29bIan Rogers return callee_save_method_[type] != NULL; 1005e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 1006410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 1007e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom// Returns a special method that describes all callee saves being spilled to the stack. 10084f0d07c783afef89703dce32c94440fc8621a29bIan RogersMethod* Runtime::GetCalleeSaveMethod(CalleeSaveType type) const { 10094f0d07c783afef89703dce32c94440fc8621a29bIan Rogers CHECK(HasCalleeSaveMethod(type)); 10104f0d07c783afef89703dce32c94440fc8621a29bIan Rogers return callee_save_method_[type]; 10111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom} 10121f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom 10134f0d07c783afef89703dce32c94440fc8621a29bIan Rogersvoid Runtime::SetCalleeSaveMethod(Method* method, CalleeSaveType type) { 10144f0d07c783afef89703dce32c94440fc8621a29bIan Rogers DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType)); 10154f0d07c783afef89703dce32c94440fc8621a29bIan Rogers callee_save_method_[type] = method; 1016e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom} 1017e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 10182692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaovoid Runtime::EnableMethodTracing(Trace* tracer) { 10192692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao CHECK(!IsMethodTracingActive()); 10202692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao tracer_ = tracer; 10212692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao} 10222692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 10232692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaovoid Runtime::DisableMethodTracing() { 10242692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao CHECK(IsMethodTracingActive()); 10252692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao delete tracer_; 10262692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao tracer_ = NULL; 10272692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao} 10282692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 10292692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaobool Runtime::IsMethodTracingActive() const { 10302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao return (tracer_ != NULL); 10312692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao} 10322692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 10332692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhaoTrace* Runtime::GetTracer() const { 10342692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao CHECK(IsMethodTracingActive()); 10352692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao return tracer_; 10362692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao} 10372692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1038b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesconst std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(const ClassLoader* class_loader) { 1039b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes if (class_loader == NULL) { 1040b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes return GetClassLinker()->GetBootClassPath(); 1041b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes } 1042b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes CHECK(UseCompileTimeClassPath()); 1043b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes CompileTimeClassPaths::const_iterator it = compile_time_class_paths_.find(class_loader); 1044b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes CHECK(it != compile_time_class_paths_.end()); 1045b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes return it->second; 1046b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 1047b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 1048b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughesvoid Runtime::SetCompileTimeClassPath(const ClassLoader* class_loader, std::vector<const DexFile*>& class_path) { 1049b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes CHECK(!IsStarted()); 1050b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes use_compile_time_class_path_ = true; 1051a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes compile_time_class_paths_.Put(class_loader, class_path); 1052b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes} 1053b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes 10546b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 1055