runtime.cc revision 6c1c69eea21cce39dd043d89368a684d250c9abe
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "runtime.h" 18 19#include <signal.h> 20 21#include <cstdio> 22#include <cstdlib> 23#include <limits> 24#include <vector> 25#include <fstream> 26 27#include "class_linker.h" 28#include "class_loader.h" 29#include "constants_arm.h" 30#include "constants_x86.h" 31#include "debugger.h" 32#include "heap.h" 33#include "image.h" 34#include "intern_table.h" 35#include "jni_internal.h" 36#include "monitor.h" 37#include "oat_file.h" 38#include "ScopedLocalRef.h" 39#include "signal_catcher.h" 40#include "signal_set.h" 41#include "space.h" 42#include "thread.h" 43#include "thread_list.h" 44#include "trace.h" 45#include "UniquePtr.h" 46#include "verifier/method_verifier.h" 47 48// TODO: this drags in cutil/log.h, which conflicts with our logging.h. 49#include "JniConstants.h" 50 51namespace art { 52 53Runtime* Runtime::instance_ = NULL; 54 55Runtime::Runtime() 56 : is_compiler_(false), 57 is_zygote_(false), 58 default_stack_size_(Thread::kDefaultStackSize), 59 heap_(NULL), 60 monitor_list_(NULL), 61 thread_list_(NULL), 62 intern_table_(NULL), 63 class_linker_(NULL), 64 signal_catcher_(NULL), 65 java_vm_(NULL), 66 jni_stub_array_(NULL), 67 abstract_method_error_stub_array_(NULL), 68 resolution_method_(NULL), 69 system_class_loader_(NULL), 70 shutting_down_(false), 71 started_(false), 72 vfprintf_(NULL), 73 exit_(NULL), 74 abort_(NULL), 75 stats_enabled_(false), 76 method_trace_(0), 77 method_trace_file_size_(0), 78 tracer_(NULL), 79 use_compile_time_class_path_(false) { 80 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 81 resolution_stub_array_[i] = NULL; 82 } 83 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 84 callee_save_method_[i] = NULL; 85 } 86} 87 88Runtime::~Runtime() { 89 shutting_down_ = true; 90 91 if (IsMethodTracingActive()) { 92 Trace::Shutdown(); 93 } 94 95 // Make sure our internal threads are dead before we start tearing down things they're using. 96 Dbg::StopJdwp(); 97 delete signal_catcher_; 98 99 // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended. 100 delete thread_list_; 101 delete monitor_list_; 102 103 delete class_linker_; 104 delete heap_; 105#if defined(ART_USE_LLVM_COMPILER) 106 verifier::MethodVerifier::DeleteInferredRegCategoryMaps(); 107#endif 108 verifier::MethodVerifier::DeleteGcMaps(); 109 delete intern_table_; 110 delete java_vm_; 111 Thread::Shutdown(); 112 // TODO: acquire a static mutex on Runtime to avoid racing. 113 CHECK(instance_ == NULL || instance_ == this); 114 instance_ = NULL; 115} 116 117static bool gAborting = false; 118 119struct AbortState { 120 void Dump(std::ostream& os) { 121 if (gAborting) { 122 os << "Runtime aborting --- recursively, so no thread-specific detail!\n"; 123 return; 124 } 125 gAborting = true; 126 os << "Runtime aborting...\n"; 127 if (Runtime::Current() == NULL) { 128 os << "(Runtime does not yet exist!)\n"; 129 return; 130 } 131 Thread* self = Thread::Current(); 132 if (self == NULL) { 133 os << "(Aborting thread was not attached to runtime!)\n"; 134 } else { 135 self->Dump(os); 136 if (self->IsExceptionPending()) { 137 os << "Pending " << PrettyTypeOf(self->GetException()) << " on thread:\n" 138 << self->GetException()->Dump(); 139 } 140 } 141 } 142}; 143 144static Mutex& GetAbortLock() { 145 static Mutex abort_lock("abort lock"); 146 return abort_lock; 147} 148 149void Runtime::Abort() { 150 // Ensure that we don't have multiple threads trying to abort at once, 151 // which would result in significantly worse diagnostics. 152 MutexLock mu(GetAbortLock()); 153 154 // Get any pending output out of the way. 155 fflush(NULL); 156 157 // Many people have difficulty distinguish aborts from crashes, 158 // so be explicit. 159 AbortState state; 160 LOG(INTERNAL_FATAL) << Dumpable<AbortState>(state); 161 162 // Call the abort hook if we have one. 163 if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) { 164 LOG(INTERNAL_FATAL) << "Calling abort hook..."; 165 Runtime::Current()->abort_(); 166 // notreached 167 LOG(INTERNAL_FATAL) << "Unexpectedly returned from abort hook!"; 168 } 169 170 // TODO: finish merging patches to fix abort(3) in bionic, then lose this! 171 // Bionic doesn't implement POSIX semantics for abort(3) in a multi-threaded 172 // process, so if we call abort(3) on a device, all threads in the process 173 // receive SIGABRT. debuggerd dumps the stack trace of the main 174 // thread, whether or not that was the thread that failed. By 175 // stuffing a value into a bogus address, we cause a segmentation 176 // fault in the current thread, and get a useful log from debuggerd. 177 // We can also trivially tell the difference between a crash and 178 // a deliberate abort by looking at the fault address. 179 *reinterpret_cast<char*>(0xdeadd00d) = 38; 180 abort(); 181 // notreached 182} 183 184void Runtime::CallExitHook(jint status) { 185 if (exit_ != NULL) { 186 ScopedThreadStateChange tsc(Thread::Current(), kNative); 187 exit_(status); 188 LOG(WARNING) << "Exit hook returned instead of exiting!"; 189 } 190} 191 192// Parse a string of the form /[0-9]+[kKmMgG]?/, which is used to specify 193// memory sizes. [kK] indicates kilobytes, [mM] megabytes, and 194// [gG] gigabytes. 195// 196// "s" should point just past the "-Xm?" part of the string. 197// "div" specifies a divisor, e.g. 1024 if the value must be a multiple 198// of 1024. 199// 200// The spec says the -Xmx and -Xms options must be multiples of 1024. It 201// doesn't say anything about -Xss. 202// 203// Returns 0 (a useless size) if "s" is malformed or specifies a low or 204// non-evenly-divisible value. 205// 206size_t ParseMemoryOption(const char* s, size_t div) { 207 // strtoul accepts a leading [+-], which we don't want, 208 // so make sure our string starts with a decimal digit. 209 if (isdigit(*s)) { 210 char* s2; 211 size_t val = strtoul(s, &s2, 10); 212 if (s2 != s) { 213 // s2 should be pointing just after the number. 214 // If this is the end of the string, the user 215 // has specified a number of bytes. Otherwise, 216 // there should be exactly one more character 217 // that specifies a multiplier. 218 if (*s2 != '\0') { 219 // The remainder of the string is either a single multiplier 220 // character, or nothing to indicate that the value is in 221 // bytes. 222 char c = *s2++; 223 if (*s2 == '\0') { 224 size_t mul; 225 if (c == '\0') { 226 mul = 1; 227 } else if (c == 'k' || c == 'K') { 228 mul = KB; 229 } else if (c == 'm' || c == 'M') { 230 mul = MB; 231 } else if (c == 'g' || c == 'G') { 232 mul = GB; 233 } else { 234 // Unknown multiplier character. 235 return 0; 236 } 237 238 if (val <= std::numeric_limits<size_t>::max() / mul) { 239 val *= mul; 240 } else { 241 // Clamp to a multiple of 1024. 242 val = std::numeric_limits<size_t>::max() & ~(1024-1); 243 } 244 } else { 245 // There's more than one character after the numeric part. 246 return 0; 247 } 248 } 249 // The man page says that a -Xm value must be a multiple of 1024. 250 if (val % div == 0) { 251 return val; 252 } 253 } 254 } 255 return 0; 256} 257 258size_t ParseIntegerOrDie(const std::string& s) { 259 std::string::size_type colon = s.find(':'); 260 if (colon == std::string::npos) { 261 LOG(FATAL) << "Missing integer: " << s; 262 } 263 const char* begin = &s[colon + 1]; 264 char* end; 265 size_t result = strtoul(begin, &end, 10); 266 if (begin == end || *end != '\0') { 267 LOG(FATAL) << "Failed to parse integer in: " << s; 268 } 269 return result; 270} 271 272void LoadJniLibrary(JavaVMExt* vm, const char* name) { 273 std::string mapped_name(StringPrintf(OS_SHARED_LIB_FORMAT_STR, name)); 274 std::string reason; 275 if (!vm->LoadNativeLibrary(mapped_name, NULL, reason)) { 276 LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": " 277 << reason; 278 } 279} 280 281Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) { 282 UniquePtr<ParsedOptions> parsed(new ParsedOptions()); 283 const char* boot_class_path_string = getenv("BOOTCLASSPATH"); 284 if (boot_class_path_string != NULL) { 285 parsed->boot_class_path_string_ = boot_class_path_string; 286 } 287 const char* class_path_string = getenv("CLASSPATH"); 288 if (class_path_string != NULL) { 289 parsed->class_path_string_ = class_path_string; 290 } 291 // -Xcheck:jni is off by default for regular builds but on by default in debug builds. 292 parsed->check_jni_ = kIsDebugBuild; 293 294 parsed->heap_initial_size_ = Heap::kInitialSize; 295 parsed->heap_maximum_size_ = Heap::kMaximumSize; 296 parsed->heap_growth_limit_ = 0; // 0 means no growth limit 297 parsed->stack_size_ = Thread::kDefaultStackSize; 298 299 parsed->is_compiler_ = false; 300 parsed->is_zygote_ = false; 301 302 parsed->jni_globals_max_ = 0; 303 parsed->lock_profiling_threshold_ = 0; 304 parsed->hook_is_sensitive_thread_ = NULL; 305 306 parsed->hook_vfprintf_ = vfprintf; 307 parsed->hook_exit_ = exit; 308 parsed->hook_abort_ = NULL; // We don't call abort(3) by default; see Runtime::Abort. 309#if defined(__APPLE__) 310 parsed->hook_abort_ = abort; // On the Mac, abort(3) gives better results; see Runtime::InitPlatformSignalHandlers. 311#endif 312 313// gLogVerbosity.class_linker = true; // TODO: don't check this in! 314// gLogVerbosity.compiler = true; // TODO: don't check this in! 315// gLogVerbosity.heap = true; // TODO: don't check this in! 316// gLogVerbosity.gc = true; // TODO: don't check this in! 317// gLogVerbosity.jdwp = true; // TODO: don't check this in! 318// gLogVerbosity.jni = true; // TODO: don't check this in! 319// gLogVerbosity.monitor = true; // TODO: don't check this in! 320// gLogVerbosity.startup = true; // TODO: don't check this in! 321// gLogVerbosity.third_party_jni = true; // TODO: don't check this in! 322// gLogVerbosity.threads = true; // TODO: don't check this in! 323 324 parsed->method_trace_ = false; 325 parsed->method_trace_file_ = "/data/method-trace-file.bin"; 326 parsed->method_trace_file_size_ = 10 * MB; 327 328 for (size_t i = 0; i < options.size(); ++i) { 329 const std::string option(options[i].first); 330 if (true && options[0].first == "-Xzygote") { 331 LOG(INFO) << "option[" << i << "]=" << option; 332 } 333 if (StartsWith(option, "-Xbootclasspath:")) { 334 parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data(); 335 } else if (option == "-classpath" || option == "-cp") { 336 // TODO: support -Djava.class.path 337 i++; 338 if (i == options.size()) { 339 // TODO: usage 340 LOG(FATAL) << "Missing required class path value for " << option; 341 return NULL; 342 } 343 const StringPiece& value = options[i].first; 344 parsed->class_path_string_ = value.data(); 345 } else if (option == "bootclasspath") { 346 parsed->boot_class_path_ 347 = reinterpret_cast<const std::vector<const DexFile*>*>(options[i].second); 348 } else if (StartsWith(option, "-Ximage:")) { 349 parsed->image_ = option.substr(strlen("-Ximage:")).data(); 350 } else if (StartsWith(option, "-Xcheck:jni")) { 351 parsed->check_jni_ = true; 352 } else if (StartsWith(option, "-Xrunjdwp:") || StartsWith(option, "-agentlib:jdwp=")) { 353 std::string tail(option.substr(option[1] == 'X' ? 10 : 15)); 354 if (tail == "help" || !Dbg::ParseJdwpOptions(tail)) { 355 LOG(FATAL) << "Example: -Xrunjdwp:transport=dt_socket,address=8000,server=y\n" 356 << "Example: -Xrunjdwp:transport=dt_socket,address=localhost:6500,server=n"; 357 return NULL; 358 } 359 } else if (StartsWith(option, "-Xms")) { 360 size_t size = ParseMemoryOption(option.substr(strlen("-Xms")).c_str(), 1024); 361 if (size == 0) { 362 if (ignore_unrecognized) { 363 continue; 364 } 365 // TODO: usage 366 LOG(FATAL) << "Failed to parse " << option; 367 return NULL; 368 } 369 parsed->heap_initial_size_ = size; 370 } else if (StartsWith(option, "-Xmx")) { 371 size_t size = ParseMemoryOption(option.substr(strlen("-Xmx")).c_str(), 1024); 372 if (size == 0) { 373 if (ignore_unrecognized) { 374 continue; 375 } 376 // TODO: usage 377 LOG(FATAL) << "Failed to parse " << option; 378 return NULL; 379 } 380 parsed->heap_maximum_size_ = size; 381 } else if (StartsWith(option, "-XX:HeapGrowthLimit=")) { 382 size_t size = ParseMemoryOption(option.substr(strlen("-XX:HeapGrowthLimit=")).c_str(), 1024); 383 if (size == 0) { 384 if (ignore_unrecognized) { 385 continue; 386 } 387 // TODO: usage 388 LOG(FATAL) << "Failed to parse " << option; 389 return NULL; 390 } 391 parsed->heap_growth_limit_ = size; 392 } else if (StartsWith(option, "-Xss")) { 393 size_t size = ParseMemoryOption(option.substr(strlen("-Xss")).c_str(), 1); 394 if (size == 0) { 395 if (ignore_unrecognized) { 396 continue; 397 } 398 // TODO: usage 399 LOG(FATAL) << "Failed to parse " << option; 400 return NULL; 401 } 402 parsed->stack_size_ = size; 403 } else if (StartsWith(option, "-D")) { 404 parsed->properties_.push_back(option.substr(strlen("-D"))); 405 } else if (StartsWith(option, "-Xjnitrace:")) { 406 parsed->jni_trace_ = option.substr(strlen("-Xjnitrace:")); 407 } else if (option == "compiler") { 408 parsed->is_compiler_ = true; 409 } else if (option == "-Xzygote") { 410 parsed->is_zygote_ = true; 411 } else if (StartsWith(option, "-verbose:")) { 412 std::vector<std::string> verbose_options; 413 Split(option.substr(strlen("-verbose:")), ',', verbose_options); 414 for (size_t i = 0; i < verbose_options.size(); ++i) { 415 if (verbose_options[i] == "class") { 416 gLogVerbosity.class_linker = true; 417 } else if (verbose_options[i] == "compiler") { 418 gLogVerbosity.compiler = true; 419 } else if (verbose_options[i] == "heap") { 420 gLogVerbosity.heap = true; 421 } else if (verbose_options[i] == "gc") { 422 gLogVerbosity.gc = true; 423 } else if (verbose_options[i] == "jdwp") { 424 gLogVerbosity.jdwp = true; 425 } else if (verbose_options[i] == "jni") { 426 gLogVerbosity.jni = true; 427 } else if (verbose_options[i] == "monitor") { 428 gLogVerbosity.monitor = true; 429 } else if (verbose_options[i] == "startup") { 430 gLogVerbosity.startup = true; 431 } else if (verbose_options[i] == "third-party-jni") { 432 gLogVerbosity.third_party_jni = true; 433 } else if (verbose_options[i] == "threads") { 434 gLogVerbosity.threads = true; 435 } else if (StartsWith(verbose_options[i], "log-to=")) { 436 std::string log_file_name(verbose_options[i].substr(strlen("log-to="))); 437 std::ofstream* log_file = new std::ofstream(log_file_name.c_str()); 438 if (log_file->is_open() && log_file->good()) { 439 gLogVerbosity.SetLoggingStream(log_file); 440 } else { 441 LOG(ERROR) << "Fail to open log file: \"" << log_file_name << "\"," 442 << " use default logging stream."; 443 } 444 } else { 445 LOG(WARNING) << "Ignoring unknown -verbose option: " << verbose_options[i]; 446 } 447 } 448 } else if (StartsWith(option, "-Xjnigreflimit:")) { 449 parsed->jni_globals_max_ = ParseIntegerOrDie(option); 450 } else if (StartsWith(option, "-Xlockprofthreshold:")) { 451 parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option); 452 } else if (StartsWith(option, "-Xstacktracefile:")) { 453 if (kIsDebugBuild) { 454 // Ignore the zygote and always show stack traces in debug builds. 455 } else { 456 parsed->stack_trace_file_ = option.substr(strlen("-Xstacktracefile:")); 457 } 458 } else if (option == "sensitiveThread") { 459 parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(options[i].second); 460 } else if (option == "vfprintf") { 461 parsed->hook_vfprintf_ = reinterpret_cast<int (*)(FILE *, const char*, va_list)>(options[i].second); 462 } else if (option == "exit") { 463 parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second); 464 } else if (option == "abort") { 465 parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second); 466 } else if (option == "host-prefix") { 467 parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second); 468 } else if (option == "-Xgenregmap" || option == "-Xgc:precise") { 469 // We silently ignore these for backwards compatibility. 470 } else if (option == "-Xmethod-trace") { 471 parsed->method_trace_ = true; 472 } else if (StartsWith(option, "-Xmethod-trace-file:")) { 473 parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:")); 474 } else if (StartsWith(option, "-Xmethod-trace-file-size:")) { 475 parsed->method_trace_file_size_ = ParseIntegerOrDie(option); 476 } else { 477 if (!ignore_unrecognized) { 478 // TODO: print usage via vfprintf 479 LOG(ERROR) << "Unrecognized option " << option; 480 // TODO: this should exit, but for now tolerate unknown options 481 //return NULL; 482 } 483 } 484 } 485 486 if (!parsed->is_compiler_ && parsed->image_.empty()) { 487 parsed->image_ += GetAndroidRoot(); 488 parsed->image_ += "/framework/boot.art"; 489 } 490 if (parsed->heap_growth_limit_ == 0) { 491 parsed->heap_growth_limit_ = parsed->heap_maximum_size_; 492 } 493 494 LOG(INFO) << "Build type: " 495 << (kIsDebugBuild ? "debug" : "optimized") 496 << "; CheckJNI: " << (parsed->check_jni_ ? "on" : "off"); 497 498 return parsed.release(); 499} 500 501Runtime* Runtime::Create(const Options& options, bool ignore_unrecognized) { 502 // TODO: acquire a static mutex on Runtime to avoid racing. 503 if (Runtime::instance_ != NULL) { 504 return NULL; 505 } 506 instance_ = new Runtime; 507 if (!instance_->Init(options, ignore_unrecognized)) { 508 delete instance_; 509 instance_ = NULL; 510 } 511 return instance_; 512} 513 514void CreateSystemClassLoader() { 515 if (Runtime::Current()->UseCompileTimeClassPath()) { 516 return; 517 } 518 519 Thread* self = Thread::Current(); 520 521 // Must be in the kNative state for calling native methods. 522 CHECK_EQ(self->GetState(), kNative); 523 524 JNIEnv* env = self->GetJniEnv(); 525 ScopedLocalRef<jclass> ClassLoader_class(env, env->FindClass("java/lang/ClassLoader")); 526 CHECK(ClassLoader_class.get() != NULL); 527 jmethodID getSystemClassLoader = env->GetStaticMethodID(ClassLoader_class.get(), 528 "getSystemClassLoader", 529 "()Ljava/lang/ClassLoader;"); 530 CHECK(getSystemClassLoader != NULL); 531 ScopedLocalRef<jobject> class_loader(env, env->CallStaticObjectMethod(ClassLoader_class.get(), 532 getSystemClassLoader)); 533 CHECK(class_loader.get() != NULL); 534 535 Thread::Current()->SetClassLoaderOverride(Decode<ClassLoader*>(env, class_loader.get())); 536 537 ScopedLocalRef<jclass> Thread_class(env, env->FindClass("java/lang/Thread")); 538 CHECK(Thread_class.get() != NULL); 539 jfieldID contextClassLoader = env->GetFieldID(Thread_class.get(), 540 "contextClassLoader", 541 "Ljava/lang/ClassLoader;"); 542 CHECK(contextClassLoader != NULL); 543 ScopedLocalRef<jobject> self_jobject(env, AddLocalReference<jobject>(env, self->GetPeer())); 544 env->SetObjectField(self_jobject.get(), contextClassLoader, class_loader.get()); 545} 546 547void Runtime::Start() { 548 VLOG(startup) << "Runtime::Start entering"; 549 550 CHECK(host_prefix_.empty()) << host_prefix_; 551 552 // Relocate the OatFiles (ELF images) 553 class_linker_->RelocateExecutable(); 554 555 // Restore main thread state to kNative as expected by native code 556 Thread::Current()->SetState(kNative); 557 558 started_ = true; 559 560 // InitNativeMethods needs to be after started_ so that the classes 561 // it touches will have methods linked to the oat file if necessary. 562 InitNativeMethods(); 563 564 Thread::FinishStartup(); 565 566 if (!is_zygote_) { 567 DidForkFromZygote(); 568 } 569 570 StartDaemonThreads(); 571 572 CreateSystemClassLoader(); 573 574 Thread::Current()->GetJniEnv()->locals.AssertEmpty(); 575 576 VLOG(startup) << "Runtime::Start exiting"; 577} 578 579void Runtime::DidForkFromZygote() { 580 is_zygote_ = false; 581 582 StartSignalCatcher(); 583 584 // Start the JDWP thread. If the command-line debugger flags specified "suspend=y", 585 // this will pause the runtime, so we probably want this to come last. 586 Dbg::StartJdwp(); 587} 588 589void Runtime::StartSignalCatcher() { 590 if (!is_zygote_) { 591 signal_catcher_ = new SignalCatcher(stack_trace_file_); 592 } 593} 594 595void Runtime::StartDaemonThreads() { 596 VLOG(startup) << "Runtime::StartDaemonThreads entering"; 597 598 Thread* self = Thread::Current(); 599 600 // Must be in the kNative state for calling native methods. 601 CHECK_EQ(self->GetState(), kNative); 602 603 JNIEnv* env = self->GetJniEnv(); 604 ScopedLocalRef<jclass> c(env, env->FindClass("java/lang/Daemons")); 605 CHECK(c.get() != NULL); 606 jmethodID mid = env->GetStaticMethodID(c.get(), "start", "()V"); 607 CHECK(mid != NULL); 608 env->CallStaticVoidMethod(c.get(), mid); 609 CHECK(!env->ExceptionCheck()); 610 611 VLOG(startup) << "Runtime::StartDaemonThreads exiting"; 612} 613 614bool Runtime::IsShuttingDown() const { 615 return shutting_down_; 616} 617 618bool Runtime::IsStarted() const { 619 return started_; 620} 621 622bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { 623 CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize); 624 625 UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized)); 626 if (options.get() == NULL) { 627 LOG(ERROR) << "Failed to parse options"; 628 return false; 629 } 630 VLOG(startup) << "Runtime::Init -verbose:startup enabled"; 631 632 SetJniGlobalsMax(options->jni_globals_max_); 633 Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_); 634 635 host_prefix_ = options->host_prefix_; 636 boot_class_path_string_ = options->boot_class_path_string_; 637 class_path_string_ = options->class_path_string_; 638 properties_ = options->properties_; 639 640 is_compiler_ = options->is_compiler_; 641 is_zygote_ = options->is_zygote_; 642 643 vfprintf_ = options->hook_vfprintf_; 644 exit_ = options->hook_exit_; 645 abort_ = options->hook_abort_; 646 647 default_stack_size_ = options->stack_size_; 648 stack_trace_file_ = options->stack_trace_file_; 649 650 monitor_list_ = new MonitorList; 651 thread_list_ = new ThreadList; 652 intern_table_ = new InternTable; 653 654 verifier::MethodVerifier::InitGcMaps(); 655 656#if defined(ART_USE_LLVM_COMPILER) 657 verifier::MethodVerifier::InitInferredRegCategoryMaps(); 658#endif 659 660 heap_ = new Heap(options->heap_initial_size_, 661 options->heap_growth_limit_, 662 options->heap_maximum_size_, 663 options->image_); 664 665 BlockSignals(); 666 InitPlatformSignalHandlers(); 667 668 java_vm_ = new JavaVMExt(this, options.get()); 669 670 Thread::Startup(); 671 672 // ClassLinker needs an attached thread, but we can't fully attach a thread 673 // without creating objects. We can't supply a thread group yet; it will be fixed later. 674 Thread::Attach("main", false, NULL); 675 676 // Set us to runnable so tools using a runtime can allocate and GC by default 677 Thread::Current()->SetState(kRunnable); 678 679 // Now we're attached, we can take the heap lock and validate the heap. 680 GetHeap()->EnableObjectValidation(); 681 682 CHECK_GE(GetHeap()->GetSpaces().size(), 1U); 683 if (GetHeap()->GetSpaces()[0]->IsImageSpace()) { 684 class_linker_ = ClassLinker::CreateFromImage(intern_table_); 685 } else { 686 CHECK(options->boot_class_path_ != NULL); 687 CHECK_NE(options->boot_class_path_->size(), 0U); 688 class_linker_ = ClassLinker::CreateFromCompiler(*options->boot_class_path_, intern_table_); 689 } 690 CHECK(class_linker_ != NULL); 691 692 method_trace_ = options->method_trace_; 693 method_trace_file_ = options->method_trace_file_; 694 method_trace_file_size_ = options->method_trace_file_size_; 695 696 if (options->method_trace_) { 697 Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, false); 698 } 699 700 VLOG(startup) << "Runtime::Init exiting"; 701 return true; 702} 703 704void Runtime::InitNativeMethods() { 705 VLOG(startup) << "Runtime::InitNativeMethods entering"; 706 Thread* self = Thread::Current(); 707 JNIEnv* env = self->GetJniEnv(); 708 709 // Must be in the kNative state for calling native methods (JNI_OnLoad code). 710 CHECK_EQ(self->GetState(), kNative); 711 712 // First set up JniConstants, which is used by both the runtime's built-in native 713 // methods and libcore. 714 JniConstants::init(env); 715 716 // Then set up the native methods provided by the runtime itself. 717 RegisterRuntimeNativeMethods(env); 718 719 // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad. 720 // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's 721 // the library that implements System.loadLibrary! 722 LoadJniLibrary(instance_->GetJavaVM(), "javacore"); 723 VLOG(startup) << "Runtime::InitNativeMethods exiting"; 724} 725 726void Runtime::RegisterRuntimeNativeMethods(JNIEnv* env) { 727#define REGISTER(FN) extern void FN(JNIEnv*); FN(env) 728 // Register Throwable first so that registration of other native methods can throw exceptions 729 REGISTER(register_java_lang_Throwable); 730 REGISTER(register_dalvik_system_DexFile); 731 REGISTER(register_dalvik_system_VMDebug); 732 REGISTER(register_dalvik_system_VMRuntime); 733 REGISTER(register_dalvik_system_VMStack); 734 REGISTER(register_dalvik_system_Zygote); 735 REGISTER(register_java_lang_Class); 736 REGISTER(register_java_lang_Object); 737 REGISTER(register_java_lang_Runtime); 738 REGISTER(register_java_lang_String); 739 REGISTER(register_java_lang_System); 740 REGISTER(register_java_lang_Thread); 741 REGISTER(register_java_lang_VMClassLoader); 742 REGISTER(register_java_lang_reflect_Array); 743 REGISTER(register_java_lang_reflect_Constructor); 744 REGISTER(register_java_lang_reflect_Field); 745 REGISTER(register_java_lang_reflect_Method); 746 REGISTER(register_java_lang_reflect_Proxy); 747 REGISTER(register_java_util_concurrent_atomic_AtomicLong); 748 REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer); 749 REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal); 750 REGISTER(register_sun_misc_Unsafe); 751#undef REGISTER 752} 753 754void Runtime::DumpForSigQuit(std::ostream& os) { 755 GetClassLinker()->DumpForSigQuit(os); 756 GetInternTable()->DumpForSigQuit(os); 757 GetHeap()->DumpForSigQuit(os); 758 os << "\n"; 759 760 thread_list_->DumpForSigQuit(os); 761} 762 763void Runtime::DumpLockHolders(std::ostream& os) { 764 pid_t heap_lock_owner = GetHeap()->GetLockOwner(); 765 pid_t thread_list_lock_owner = GetThreadList()->GetLockOwner(); 766 pid_t classes_lock_owner = GetClassLinker()->GetClassesLockOwner(); 767 pid_t dex_lock_owner = GetClassLinker()->GetDexLockOwner(); 768 if ((heap_lock_owner | thread_list_lock_owner | classes_lock_owner | dex_lock_owner) != 0) { 769 os << "Heap lock owner tid: " << heap_lock_owner << "\n" 770 << "ThreadList lock owner tid: " << thread_list_lock_owner << "\n" 771 << "ClassLinker classes lock owner tid: " << classes_lock_owner << "\n" 772 << "ClassLinker dex lock owner tid: " << dex_lock_owner << "\n"; 773 } 774} 775 776void Runtime::SetStatsEnabled(bool new_state) { 777 if (new_state == true) { 778 GetStats()->Clear(~0); 779 // TODO: wouldn't it make more sense to clear _all_ threads' stats? 780 Thread::Current()->GetStats()->Clear(~0); 781 } 782 stats_enabled_ = new_state; 783} 784 785void Runtime::ResetStats(int kinds) { 786 GetStats()->Clear(kinds & 0xffff); 787 // TODO: wouldn't it make more sense to clear _all_ threads' stats? 788 Thread::Current()->GetStats()->Clear(kinds >> 16); 789} 790 791RuntimeStats* Runtime::GetStats() { 792 return &stats_; 793} 794 795int32_t Runtime::GetStat(int kind) { 796 RuntimeStats* stats; 797 if (kind < (1<<16)) { 798 stats = GetStats(); 799 } else { 800 stats = Thread::Current()->GetStats(); 801 kind >>= 16; 802 } 803 switch (kind) { 804 case KIND_ALLOCATED_OBJECTS: 805 return stats->allocated_objects; 806 case KIND_ALLOCATED_BYTES: 807 return stats->allocated_bytes; 808 case KIND_FREED_OBJECTS: 809 return stats->freed_objects; 810 case KIND_FREED_BYTES: 811 return stats->freed_bytes; 812 case KIND_GC_INVOCATIONS: 813 return stats->gc_for_alloc_count; 814 case KIND_CLASS_INIT_COUNT: 815 return stats->class_init_count; 816 case KIND_CLASS_INIT_TIME: 817 // Convert ns to us, reduce to 32 bits. 818 return static_cast<int>(stats->class_init_time_ns / 1000); 819 case KIND_EXT_ALLOCATED_OBJECTS: 820 case KIND_EXT_ALLOCATED_BYTES: 821 case KIND_EXT_FREED_OBJECTS: 822 case KIND_EXT_FREED_BYTES: 823 return 0; // backward compatibility 824 default: 825 LOG(FATAL) << "Unknown statistic " << kind; 826 return -1; // unreachable 827 } 828} 829 830void Runtime::BlockSignals() { 831 SignalSet signals; 832 signals.Add(SIGPIPE); 833 // SIGQUIT is used to dump the runtime's state (including stack traces). 834 signals.Add(SIGQUIT); 835 // SIGUSR1 is used to initiate a GC. 836 signals.Add(SIGUSR1); 837 signals.Block(); 838} 839 840void Runtime::AttachCurrentThread(const char* thread_name, bool as_daemon, Object* thread_group) { 841 Thread::Attach(thread_name, as_daemon, thread_group); 842 if (thread_name == NULL) { 843 LOG(WARNING) << *Thread::Current() << " attached without supplying a name"; 844 } 845} 846 847void Runtime::DetachCurrentThread() { 848 if (Thread::Current()->GetTopOfStack().GetSP() != NULL) { 849 LOG(FATAL) << *Thread::Current() << " attempting to detach while still running code"; 850 } 851 thread_list_->Unregister(); 852} 853 854void Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) const { 855 Dbg::VisitRoots(visitor, arg); 856 class_linker_->VisitRoots(visitor, arg); 857 intern_table_->VisitRoots(visitor, arg); 858 java_vm_->VisitRoots(visitor, arg); 859 thread_list_->VisitRoots(visitor, arg); 860 visitor(jni_stub_array_, arg); 861 visitor(abstract_method_error_stub_array_, arg); 862 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 863 visitor(resolution_stub_array_[i], arg); 864 } 865 visitor(resolution_method_, arg); 866 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 867 visitor(callee_save_method_[i], arg); 868 } 869} 870 871bool Runtime::HasJniDlsymLookupStub() const { 872 return jni_stub_array_ != NULL; 873} 874 875ByteArray* Runtime::GetJniDlsymLookupStub() const { 876 CHECK(jni_stub_array_ != NULL); 877 return jni_stub_array_; 878} 879 880void Runtime::SetJniDlsymLookupStub(ByteArray* jni_stub_array) { 881 CHECK(jni_stub_array != NULL) << " jni_stub_array=" << jni_stub_array; 882 CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array) 883 << "jni_stub_array_=" << jni_stub_array_ << " jni_stub_array=" << jni_stub_array; 884 jni_stub_array_ = jni_stub_array; 885} 886 887bool Runtime::HasAbstractMethodErrorStubArray() const { 888 return abstract_method_error_stub_array_ != NULL; 889} 890 891ByteArray* Runtime::GetAbstractMethodErrorStubArray() const { 892 CHECK(abstract_method_error_stub_array_ != NULL); 893 return abstract_method_error_stub_array_; 894} 895 896void Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) { 897 CHECK(abstract_method_error_stub_array != NULL); 898 CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array); 899 abstract_method_error_stub_array_ = abstract_method_error_stub_array; 900} 901 902 903Runtime::TrampolineType Runtime::GetTrampolineType(Method* method) { 904 if (method == NULL) { 905 return Runtime::kUnknownMethod; 906 } else if (method->IsStatic()) { 907 return Runtime::kStaticMethod; 908 } else { 909 return Runtime::kUnknownMethod; 910 } 911} 912 913bool Runtime::HasResolutionStubArray(TrampolineType type) const { 914 return resolution_stub_array_[type] != NULL; 915} 916 917ByteArray* Runtime::GetResolutionStubArray(TrampolineType type) const { 918 CHECK(HasResolutionStubArray(type)); 919 DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType)); 920 return resolution_stub_array_[type]; 921} 922 923void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) { 924 CHECK(resolution_stub_array != NULL); 925 CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array); 926 resolution_stub_array_[type] = resolution_stub_array; 927} 928 929Method* Runtime::CreateResolutionMethod() { 930 Class* method_class = Method::GetMethodClass(); 931 SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject())); 932 method->SetDeclaringClass(method_class); 933 // TODO: use a special method for resolution method saves 934 method->SetDexMethodIndex(DexFile::kDexNoIndex16); 935 ByteArray* unknown_resolution_stub = GetResolutionStubArray(kUnknownMethod); 936 CHECK(unknown_resolution_stub != NULL); 937 method->SetCode(unknown_resolution_stub->GetData()); 938 return method.get(); 939} 940 941bool Runtime::HasResolutionMethod() const { 942 return resolution_method_ != NULL; 943} 944 945// Returns a special method that calls into a trampoline for runtime method resolution 946Method* Runtime::GetResolutionMethod() const { 947 CHECK(HasResolutionMethod()); 948 return resolution_method_; 949} 950 951void Runtime::SetResolutionMethod(Method* method) { 952 resolution_method_ = method; 953} 954 955Method* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type) { 956 Class* method_class = Method::GetMethodClass(); 957 SirtRef<Method> method(down_cast<Method*>(method_class->AllocObject())); 958 method->SetDeclaringClass(method_class); 959 // TODO: use a special method for callee saves 960 method->SetDexMethodIndex(DexFile::kDexNoIndex16); 961 method->SetCode(NULL); 962 if ((instruction_set == kThumb2) || (instruction_set == kArm)) { 963 uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6) | (1 << art::arm::R7) | 964 (1 << art::arm::R8) | (1 << art::arm::R10) | (1 << art::arm::R11); 965 uint32_t arg_spills = (1 << art::arm::R1) | (1 << art::arm::R2) | (1 << art::arm::R3); 966 uint32_t all_spills = (1 << art::arm::R4) | (1 << art::arm::R9); 967 uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills :0) | 968 (type == kSaveAll ? all_spills :0) | (1 << art::arm::LR); 969 uint32_t fp_all_spills = (1 << art::arm::S0) | (1 << art::arm::S1) | (1 << art::arm::S2) | 970 (1 << art::arm::S3) | (1 << art::arm::S4) | (1 << art::arm::S5) | 971 (1 << art::arm::S6) | (1 << art::arm::S7) | (1 << art::arm::S8) | 972 (1 << art::arm::S9) | (1 << art::arm::S10) | (1 << art::arm::S11) | 973 (1 << art::arm::S12) | (1 << art::arm::S13) | (1 << art::arm::S14) | 974 (1 << art::arm::S15) | (1 << art::arm::S16) | (1 << art::arm::S17) | 975 (1 << art::arm::S18) | (1 << art::arm::S19) | (1 << art::arm::S20) | 976 (1 << art::arm::S21) | (1 << art::arm::S22) | (1 << art::arm::S23) | 977 (1 << art::arm::S24) | (1 << art::arm::S25) | (1 << art::arm::S26) | 978 (1 << art::arm::S27) | (1 << art::arm::S28) | (1 << art::arm::S29) | 979 (1 << art::arm::S30) | (1 << art::arm::S31); 980 uint32_t fp_spills = type == kSaveAll ? fp_all_spills : 0; 981 size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ + 982 __builtin_popcount(fp_spills) /* fprs */ + 983 1 /* Method* */) * kPointerSize, kStackAlignment); 984 method->SetFrameSizeInBytes(frame_size); 985 method->SetCoreSpillMask(core_spills); 986 method->SetFpSpillMask(fp_spills); 987 } else if (instruction_set == kX86) { 988 uint32_t ref_spills = (1 << art::x86::EBP) | (1 << art::x86::ESI) | (1 << art::x86::EDI); 989 uint32_t arg_spills = (1 << art::x86::ECX) | (1 << art::x86::EDX) | (1 << art::x86::EBX); 990 uint32_t core_spills = ref_spills | (type == kRefsAndArgs ? arg_spills : 0) | 991 (1 << art::x86::kNumberOfCpuRegisters); // fake return address callee save 992 size_t frame_size = RoundUp((__builtin_popcount(core_spills) /* gprs */ + 993 1 /* Method* */) * kPointerSize, kStackAlignment); 994 method->SetFrameSizeInBytes(frame_size); 995 method->SetCoreSpillMask(core_spills); 996 method->SetFpSpillMask(0); 997 } else { 998 UNIMPLEMENTED(FATAL); 999 } 1000 return method.get(); 1001} 1002 1003bool Runtime::HasCalleeSaveMethod(CalleeSaveType type) const { 1004 return callee_save_method_[type] != NULL; 1005} 1006 1007// Returns a special method that describes all callee saves being spilled to the stack. 1008Method* Runtime::GetCalleeSaveMethod(CalleeSaveType type) const { 1009 CHECK(HasCalleeSaveMethod(type)); 1010 return callee_save_method_[type]; 1011} 1012 1013void Runtime::SetCalleeSaveMethod(Method* method, CalleeSaveType type) { 1014 DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType)); 1015 callee_save_method_[type] = method; 1016} 1017 1018void Runtime::EnableMethodTracing(Trace* tracer) { 1019 CHECK(!IsMethodTracingActive()); 1020 tracer_ = tracer; 1021} 1022 1023void Runtime::DisableMethodTracing() { 1024 CHECK(IsMethodTracingActive()); 1025 delete tracer_; 1026 tracer_ = NULL; 1027} 1028 1029bool Runtime::IsMethodTracingActive() const { 1030 return (tracer_ != NULL); 1031} 1032 1033Trace* Runtime::GetTracer() const { 1034 CHECK(IsMethodTracingActive()); 1035 return tracer_; 1036} 1037 1038const std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(const ClassLoader* class_loader) { 1039 if (class_loader == NULL) { 1040 return GetClassLinker()->GetBootClassPath(); 1041 } 1042 CHECK(UseCompileTimeClassPath()); 1043 CompileTimeClassPaths::const_iterator it = compile_time_class_paths_.find(class_loader); 1044 CHECK(it != compile_time_class_paths_.end()); 1045 return it->second; 1046} 1047 1048void Runtime::SetCompileTimeClassPath(const ClassLoader* class_loader, std::vector<const DexFile*>& class_path) { 1049 CHECK(!IsStarted()); 1050 use_compile_time_class_path_ = true; 1051 compile_time_class_paths_.Put(class_loader, class_path); 1052} 1053 1054} // namespace art 1055