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