runtime.cc revision 7624d25dad2d1ba25969ae704fccf68649103ae5
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// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc 20#include <sys/mount.h> 21#include <linux/fs.h> 22 23#include <signal.h> 24#include <sys/syscall.h> 25#include <valgrind.h> 26 27#include <cstdio> 28#include <cstdlib> 29#include <limits> 30#include <vector> 31#include <fcntl.h> 32 33#include "arch/arm/quick_method_frame_info_arm.h" 34#include "arch/arm/registers_arm.h" 35#include "arch/arm64/quick_method_frame_info_arm64.h" 36#include "arch/arm64/registers_arm64.h" 37#include "arch/mips/quick_method_frame_info_mips.h" 38#include "arch/mips/registers_mips.h" 39#include "arch/x86/quick_method_frame_info_x86.h" 40#include "arch/x86/registers_x86.h" 41#include "arch/x86_64/quick_method_frame_info_x86_64.h" 42#include "arch/x86_64/registers_x86_64.h" 43#include "atomic.h" 44#include "class_linker.h" 45#include "debugger.h" 46#include "gc/accounting/card_table-inl.h" 47#include "gc/heap.h" 48#include "gc/space/space.h" 49#include "image.h" 50#include "instrumentation.h" 51#include "intern_table.h" 52#include "jni_internal.h" 53#include "mirror/art_field-inl.h" 54#include "mirror/art_method-inl.h" 55#include "mirror/array.h" 56#include "mirror/class-inl.h" 57#include "mirror/class_loader.h" 58#include "mirror/stack_trace_element.h" 59#include "mirror/throwable.h" 60#include "monitor.h" 61#include "parsed_options.h" 62#include "oat_file.h" 63#include "quick/quick_method_frame_info.h" 64#include "reflection.h" 65#include "ScopedLocalRef.h" 66#include "scoped_thread_state_change.h" 67#include "signal_catcher.h" 68#include "signal_set.h" 69#include "sirt_ref.h" 70#include "thread.h" 71#include "thread_list.h" 72#include "trace.h" 73#include "transaction.h" 74#include "profiler.h" 75#include "UniquePtr.h" 76#include "verifier/method_verifier.h" 77#include "well_known_classes.h" 78 79#include "JniConstants.h" // Last to avoid LOG redefinition in ics-mr1-plus-art. 80 81#ifdef HAVE_ANDROID_OS 82#include "cutils/properties.h" 83#endif 84 85namespace art { 86 87static constexpr bool kEnableJavaStackTraceHandler = true; 88const char* Runtime::kDefaultInstructionSetFeatures = 89 STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES); 90Runtime* Runtime::instance_ = NULL; 91 92Runtime::Runtime() 93 : pre_allocated_OutOfMemoryError_(nullptr), 94 resolution_method_(nullptr), 95 imt_conflict_method_(nullptr), 96 default_imt_(nullptr), 97 instruction_set_(kNone), 98 compiler_callbacks_(nullptr), 99 is_zygote_(false), 100 is_concurrent_gc_enabled_(true), 101 is_explicit_gc_disabled_(false), 102 default_stack_size_(0), 103 heap_(nullptr), 104 max_spins_before_thin_lock_inflation_(Monitor::kDefaultMaxSpinsBeforeThinLockInflation), 105 monitor_list_(nullptr), 106 monitor_pool_(nullptr), 107 thread_list_(nullptr), 108 intern_table_(nullptr), 109 class_linker_(nullptr), 110 signal_catcher_(nullptr), 111 java_vm_(nullptr), 112 fault_message_lock_("Fault message lock"), 113 fault_message_(""), 114 method_verifier_lock_("Method verifiers lock"), 115 threads_being_born_(0), 116 shutdown_cond_(new ConditionVariable("Runtime shutdown", *Locks::runtime_shutdown_lock_)), 117 shutting_down_(false), 118 shutting_down_started_(false), 119 started_(false), 120 finished_starting_(false), 121 vfprintf_(nullptr), 122 exit_(nullptr), 123 abort_(nullptr), 124 stats_enabled_(false), 125 running_on_valgrind_(RUNNING_ON_VALGRIND > 0), 126 profile_(false), 127 profile_period_s_(0), 128 profile_duration_s_(0), 129 profile_interval_us_(0), 130 profile_backoff_coefficient_(0), 131 profile_start_immediately_(true), 132 method_trace_(false), 133 method_trace_file_size_(0), 134 instrumentation_(), 135 use_compile_time_class_path_(false), 136 main_thread_group_(nullptr), 137 system_thread_group_(nullptr), 138 system_class_loader_(nullptr), 139 dump_gc_performance_on_shutdown_(false), 140 preinitialization_transaction_(nullptr), 141 null_pointer_handler_(nullptr), 142 suspend_handler_(nullptr), 143 stack_overflow_handler_(nullptr), 144 verify_(false) { 145 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 146 callee_save_methods_[i] = nullptr; 147 } 148} 149 150Runtime::~Runtime() { 151 if (dump_gc_performance_on_shutdown_) { 152 // This can't be called from the Heap destructor below because it 153 // could call RosAlloc::InspectAll() which needs the thread_list 154 // to be still alive. 155 heap_->DumpGcPerformanceInfo(LOG(INFO)); 156 } 157 158 Thread* self = Thread::Current(); 159 { 160 MutexLock mu(self, *Locks::runtime_shutdown_lock_); 161 shutting_down_started_ = true; 162 while (threads_being_born_ > 0) { 163 shutdown_cond_->Wait(self); 164 } 165 shutting_down_ = true; 166 } 167 Trace::Shutdown(); 168 169 // Make sure to let the GC complete if it is running. 170 heap_->WaitForGcToComplete(gc::kGcCauseBackground, self); 171 heap_->DeleteThreadPool(); 172 173 // Make sure our internal threads are dead before we start tearing down things they're using. 174 Dbg::StopJdwp(); 175 delete signal_catcher_; 176 177 // Make sure all other non-daemon threads have terminated, and all daemon threads are suspended. 178 delete thread_list_; 179 delete monitor_list_; 180 delete monitor_pool_; 181 delete class_linker_; 182 delete heap_; 183 delete intern_table_; 184 delete java_vm_; 185 Thread::Shutdown(); 186 QuasiAtomic::Shutdown(); 187 verifier::MethodVerifier::Shutdown(); 188 // TODO: acquire a static mutex on Runtime to avoid racing. 189 CHECK(instance_ == nullptr || instance_ == this); 190 instance_ = nullptr; 191 192 delete null_pointer_handler_; 193 delete suspend_handler_; 194 delete stack_overflow_handler_; 195} 196 197struct AbortState { 198 void Dump(std::ostream& os) NO_THREAD_SAFETY_ANALYSIS { 199 if (gAborting > 1) { 200 os << "Runtime aborting --- recursively, so no thread-specific detail!\n"; 201 return; 202 } 203 gAborting++; 204 os << "Runtime aborting...\n"; 205 if (Runtime::Current() == NULL) { 206 os << "(Runtime does not yet exist!)\n"; 207 return; 208 } 209 Thread* self = Thread::Current(); 210 if (self == nullptr) { 211 os << "(Aborting thread was not attached to runtime!)\n"; 212 } else { 213 os << "Aborting thread:\n"; 214 if (Locks::mutator_lock_->IsExclusiveHeld(self) || Locks::mutator_lock_->IsSharedHeld(self)) { 215 DumpThread(os, self); 216 } else { 217 if (Locks::mutator_lock_->SharedTryLock(self)) { 218 DumpThread(os, self); 219 Locks::mutator_lock_->SharedUnlock(self); 220 } 221 } 222 } 223 DumpAllThreads(os, self); 224 } 225 226 void DumpThread(std::ostream& os, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 227 self->Dump(os); 228 if (self->IsExceptionPending()) { 229 ThrowLocation throw_location; 230 mirror::Throwable* exception = self->GetException(&throw_location); 231 os << "Pending exception " << PrettyTypeOf(exception) 232 << " thrown by '" << throw_location.Dump() << "'\n" 233 << exception->Dump(); 234 } 235 } 236 237 void DumpAllThreads(std::ostream& os, Thread* self) NO_THREAD_SAFETY_ANALYSIS { 238 bool tll_already_held = Locks::thread_list_lock_->IsExclusiveHeld(self); 239 bool ml_already_held = Locks::mutator_lock_->IsSharedHeld(self); 240 if (!tll_already_held || !ml_already_held) { 241 os << "Dumping all threads without appropriate locks held:" 242 << (!tll_already_held ? " thread list lock" : "") 243 << (!ml_already_held ? " mutator lock" : "") 244 << "\n"; 245 } 246 os << "All threads:\n"; 247 Runtime::Current()->GetThreadList()->DumpLocked(os); 248 } 249}; 250 251void Runtime::Abort() { 252 gAborting++; // set before taking any locks 253 254 // Ensure that we don't have multiple threads trying to abort at once, 255 // which would result in significantly worse diagnostics. 256 MutexLock mu(Thread::Current(), *Locks::abort_lock_); 257 258 // Get any pending output out of the way. 259 fflush(NULL); 260 261 // Many people have difficulty distinguish aborts from crashes, 262 // so be explicit. 263 AbortState state; 264 LOG(INTERNAL_FATAL) << Dumpable<AbortState>(state); 265 266 // Call the abort hook if we have one. 267 if (Runtime::Current() != NULL && Runtime::Current()->abort_ != NULL) { 268 LOG(INTERNAL_FATAL) << "Calling abort hook..."; 269 Runtime::Current()->abort_(); 270 // notreached 271 LOG(INTERNAL_FATAL) << "Unexpectedly returned from abort hook!"; 272 } 273 274#if defined(__GLIBC__) 275 // TODO: we ought to be able to use pthread_kill(3) here (or abort(3), 276 // which POSIX defines in terms of raise(3), which POSIX defines in terms 277 // of pthread_kill(3)). On Linux, though, libcorkscrew can't unwind through 278 // libpthread, which means the stacks we dump would be useless. Calling 279 // tgkill(2) directly avoids that. 280 syscall(__NR_tgkill, getpid(), GetTid(), SIGABRT); 281 // TODO: LLVM installs it's own SIGABRT handler so exit to be safe... Can we disable that in LLVM? 282 // If not, we could use sigaction(3) before calling tgkill(2) and lose this call to exit(3). 283 exit(1); 284#else 285 abort(); 286#endif 287 // notreached 288} 289 290void Runtime::PreZygoteFork() { 291 heap_->PreZygoteFork(); 292} 293 294void Runtime::CallExitHook(jint status) { 295 if (exit_ != NULL) { 296 ScopedThreadStateChange tsc(Thread::Current(), kNative); 297 exit_(status); 298 LOG(WARNING) << "Exit hook returned instead of exiting!"; 299 } 300} 301 302void Runtime::SweepSystemWeaks(IsMarkedCallback* visitor, void* arg) { 303 GetInternTable()->SweepInternTableWeaks(visitor, arg); 304 GetMonitorList()->SweepMonitorList(visitor, arg); 305 GetJavaVM()->SweepJniWeakGlobals(visitor, arg); 306 Dbg::UpdateObjectPointers(visitor, arg); 307} 308 309bool Runtime::Create(const Options& options, bool ignore_unrecognized) { 310 // TODO: acquire a static mutex on Runtime to avoid racing. 311 if (Runtime::instance_ != NULL) { 312 return false; 313 } 314 InitLogging(NULL); // Calls Locks::Init() as a side effect. 315 instance_ = new Runtime; 316 if (!instance_->Init(options, ignore_unrecognized)) { 317 delete instance_; 318 instance_ = NULL; 319 return false; 320 } 321 return true; 322} 323 324jobject CreateSystemClassLoader() { 325 if (Runtime::Current()->UseCompileTimeClassPath()) { 326 return NULL; 327 } 328 329 ScopedObjectAccess soa(Thread::Current()); 330 ClassLinker* cl = Runtime::Current()->GetClassLinker(); 331 332 SirtRef<mirror::Class> class_loader_class( 333 soa.Self(), soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader)); 334 CHECK(cl->EnsureInitialized(class_loader_class, true, true)); 335 336 mirror::ArtMethod* getSystemClassLoader = 337 class_loader_class->FindDirectMethod("getSystemClassLoader", "()Ljava/lang/ClassLoader;"); 338 CHECK(getSystemClassLoader != NULL); 339 340 JValue result = InvokeWithJValues(soa, nullptr, soa.EncodeMethod(getSystemClassLoader), nullptr); 341 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), 342 down_cast<mirror::ClassLoader*>(result.GetL())); 343 CHECK(class_loader.get() != nullptr); 344 JNIEnv* env = soa.Self()->GetJniEnv(); 345 ScopedLocalRef<jobject> system_class_loader(env, 346 soa.AddLocalReference<jobject>(class_loader.get())); 347 CHECK(system_class_loader.get() != nullptr); 348 349 soa.Self()->SetClassLoaderOverride(class_loader.get()); 350 351 SirtRef<mirror::Class> thread_class( 352 soa.Self(), 353 soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread)); 354 CHECK(cl->EnsureInitialized(thread_class, true, true)); 355 356 mirror::ArtField* contextClassLoader = 357 thread_class->FindDeclaredInstanceField("contextClassLoader", "Ljava/lang/ClassLoader;"); 358 CHECK(contextClassLoader != NULL); 359 360 // We can't run in a transaction yet. 361 contextClassLoader->SetObject<false>(soa.Self()->GetPeer(), class_loader.get()); 362 363 return env->NewGlobalRef(system_class_loader.get()); 364} 365 366bool Runtime::Start() { 367 VLOG(startup) << "Runtime::Start entering"; 368 369 // Restore main thread state to kNative as expected by native code. 370 Thread* self = Thread::Current(); 371 self->TransitionFromRunnableToSuspended(kNative); 372 373 started_ = true; 374 375 // InitNativeMethods needs to be after started_ so that the classes 376 // it touches will have methods linked to the oat file if necessary. 377 InitNativeMethods(); 378 379 // Initialize well known thread group values that may be accessed threads while attaching. 380 InitThreadGroups(self); 381 382 Thread::FinishStartup(); 383 384 if (is_zygote_) { 385 if (!InitZygote()) { 386 return false; 387 } 388 } else { 389 DidForkFromZygote(); 390 } 391 392 StartDaemonThreads(); 393 394 system_class_loader_ = CreateSystemClassLoader(); 395 396 self->GetJniEnv()->locals.AssertEmpty(); 397 398 VLOG(startup) << "Runtime::Start exiting"; 399 400 finished_starting_ = true; 401 402 if (profile_) { 403 // User has asked for a profile using -Xprofile 404 // Create the profile file if it doesn't exist. 405 int fd = open(profile_output_filename_.c_str(), O_RDWR|O_CREAT|O_EXCL, 0660); 406 if (fd >= 0) { 407 close(fd); 408 } 409 StartProfiler(profile_output_filename_.c_str(), ""); 410 } 411 412 return true; 413} 414 415void Runtime::EndThreadBirth() EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) { 416 DCHECK_GT(threads_being_born_, 0U); 417 threads_being_born_--; 418 if (shutting_down_started_ && threads_being_born_ == 0) { 419 shutdown_cond_->Broadcast(Thread::Current()); 420 } 421} 422 423// Do zygote-mode-only initialization. 424bool Runtime::InitZygote() { 425 // zygote goes into its own process group 426 setpgid(0, 0); 427 428 // See storage config details at http://source.android.com/tech/storage/ 429 // Create private mount namespace shared by all children 430 if (unshare(CLONE_NEWNS) == -1) { 431 PLOG(WARNING) << "Failed to unshare()"; 432 return false; 433 } 434 435 // Mark rootfs as being a slave so that changes from default 436 // namespace only flow into our children. 437 if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) { 438 PLOG(WARNING) << "Failed to mount() rootfs as MS_SLAVE"; 439 return false; 440 } 441 442 // Create a staging tmpfs that is shared by our children; they will 443 // bind mount storage into their respective private namespaces, which 444 // are isolated from each other. 445 const char* target_base = getenv("EMULATED_STORAGE_TARGET"); 446 if (target_base != NULL) { 447 if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV, 448 "uid=0,gid=1028,mode=0751") == -1) { 449 LOG(WARNING) << "Failed to mount tmpfs to " << target_base; 450 return false; 451 } 452 } 453 454 return true; 455} 456 457void Runtime::DidForkFromZygote() { 458 is_zygote_ = false; 459 460 // Create the thread pool. 461 heap_->CreateThreadPool(); 462 463 StartSignalCatcher(); 464 465 // Start the JDWP thread. If the command-line debugger flags specified "suspend=y", 466 // this will pause the runtime, so we probably want this to come last. 467 Dbg::StartJdwp(); 468} 469 470void Runtime::StartSignalCatcher() { 471 if (!is_zygote_) { 472 signal_catcher_ = new SignalCatcher(stack_trace_file_); 473 } 474} 475 476bool Runtime::IsShuttingDown(Thread* self) { 477 MutexLock mu(self, *Locks::runtime_shutdown_lock_); 478 return IsShuttingDownLocked(); 479} 480 481void Runtime::StartDaemonThreads() { 482 VLOG(startup) << "Runtime::StartDaemonThreads entering"; 483 484 Thread* self = Thread::Current(); 485 486 // Must be in the kNative state for calling native methods. 487 CHECK_EQ(self->GetState(), kNative); 488 489 JNIEnv* env = self->GetJniEnv(); 490 env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons, 491 WellKnownClasses::java_lang_Daemons_start); 492 if (env->ExceptionCheck()) { 493 env->ExceptionDescribe(); 494 LOG(FATAL) << "Error starting java.lang.Daemons"; 495 } 496 497 VLOG(startup) << "Runtime::StartDaemonThreads exiting"; 498} 499 500bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { 501 CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize); 502 503 UniquePtr<ParsedOptions> options(ParsedOptions::Create(raw_options, ignore_unrecognized)); 504 if (options.get() == NULL) { 505 LOG(ERROR) << "Failed to parse options"; 506 return false; 507 } 508 VLOG(startup) << "Runtime::Init -verbose:startup enabled"; 509 510 QuasiAtomic::Startup(); 511 512 Monitor::Init(options->lock_profiling_threshold_, options->hook_is_sensitive_thread_); 513 514 boot_class_path_string_ = options->boot_class_path_string_; 515 class_path_string_ = options->class_path_string_; 516 properties_ = options->properties_; 517 518 compiler_callbacks_ = options->compiler_callbacks_; 519 is_zygote_ = options->is_zygote_; 520 is_explicit_gc_disabled_ = options->is_explicit_gc_disabled_; 521 522 vfprintf_ = options->hook_vfprintf_; 523 exit_ = options->hook_exit_; 524 abort_ = options->hook_abort_; 525 526 default_stack_size_ = options->stack_size_; 527 stack_trace_file_ = options->stack_trace_file_; 528 529 compiler_options_ = options->compiler_options_; 530 image_compiler_options_ = options->image_compiler_options_; 531 532 max_spins_before_thin_lock_inflation_ = options->max_spins_before_thin_lock_inflation_; 533 534 monitor_list_ = new MonitorList; 535 monitor_pool_ = MonitorPool::Create(); 536 thread_list_ = new ThreadList; 537 intern_table_ = new InternTable; 538 539 verify_ = options->verify_; 540 541 if (options->interpreter_only_) { 542 GetInstrumentation()->ForceInterpretOnly(); 543 } 544 545 if (options->explicit_checks_ != (ParsedOptions::kExplicitSuspendCheck | 546 ParsedOptions::kExplicitNullCheck | 547 ParsedOptions::kExplicitStackOverflowCheck) || kEnableJavaStackTraceHandler) { 548 fault_manager.Init(); 549 550 // These need to be in a specific order. The null point check handler must be 551 // after the suspend check and stack overflow check handlers. 552 if ((options->explicit_checks_ & ParsedOptions::kExplicitSuspendCheck) == 0) { 553 suspend_handler_ = new SuspensionHandler(&fault_manager); 554 } 555 556 if ((options->explicit_checks_ & ParsedOptions::kExplicitStackOverflowCheck) == 0) { 557 stack_overflow_handler_ = new StackOverflowHandler(&fault_manager); 558 } 559 560 if ((options->explicit_checks_ & ParsedOptions::kExplicitNullCheck) == 0) { 561 null_pointer_handler_ = new NullPointerHandler(&fault_manager); 562 } 563 564 if (kEnableJavaStackTraceHandler) { 565 new JavaStackTraceHandler(&fault_manager); 566 } 567 } 568 569 heap_ = new gc::Heap(options->heap_initial_size_, 570 options->heap_growth_limit_, 571 options->heap_min_free_, 572 options->heap_max_free_, 573 options->heap_target_utilization_, 574 options->foreground_heap_growth_multiplier_, 575 options->heap_maximum_size_, 576 options->image_, 577 options->image_isa_, 578 options->collector_type_, 579 options->background_collector_type_, 580 options->parallel_gc_threads_, 581 options->conc_gc_threads_, 582 options->low_memory_mode_, 583 options->long_pause_log_threshold_, 584 options->long_gc_log_threshold_, 585 options->ignore_max_footprint_, 586 options->use_tlab_, 587 options->verify_pre_gc_heap_, 588 options->verify_pre_sweeping_heap_, 589 options->verify_post_gc_heap_, 590 options->verify_pre_gc_rosalloc_, 591 options->verify_pre_sweeping_rosalloc_, 592 options->verify_post_gc_rosalloc_); 593 594 dump_gc_performance_on_shutdown_ = options->dump_gc_performance_on_shutdown_; 595 596 BlockSignals(); 597 InitPlatformSignalHandlers(); 598 599 java_vm_ = new JavaVMExt(this, options.get()); 600 601 Thread::Startup(); 602 603 // ClassLinker needs an attached thread, but we can't fully attach a thread without creating 604 // objects. We can't supply a thread group yet; it will be fixed later. Since we are the main 605 // thread, we do not get a java peer. 606 Thread* self = Thread::Attach("main", false, NULL, false); 607 CHECK_EQ(self->GetThreadId(), ThreadList::kMainThreadId); 608 CHECK(self != NULL); 609 610 // Set us to runnable so tools using a runtime can allocate and GC by default 611 self->TransitionFromSuspendedToRunnable(); 612 613 // Now we're attached, we can take the heap locks and validate the heap. 614 GetHeap()->EnableObjectValidation(); 615 616 CHECK_GE(GetHeap()->GetContinuousSpaces().size(), 1U); 617 class_linker_ = new ClassLinker(intern_table_); 618 if (GetHeap()->HasImageSpace()) { 619 class_linker_->InitFromImage(); 620 } else { 621 CHECK(options->boot_class_path_ != NULL); 622 CHECK_NE(options->boot_class_path_->size(), 0U); 623 class_linker_->InitFromCompiler(*options->boot_class_path_); 624 } 625 CHECK(class_linker_ != NULL); 626 verifier::MethodVerifier::Init(); 627 628 method_trace_ = options->method_trace_; 629 method_trace_file_ = options->method_trace_file_; 630 method_trace_file_size_ = options->method_trace_file_size_; 631 632 // Extract the profile options. 633 // TODO: move into a Trace options struct? 634 profile_period_s_ = options->profile_period_s_; 635 profile_duration_s_ = options->profile_duration_s_; 636 profile_interval_us_ = options->profile_interval_us_; 637 profile_backoff_coefficient_ = options->profile_backoff_coefficient_; 638 profile_start_immediately_ = options->profile_start_immediately_; 639 profile_ = options->profile_; 640 profile_output_filename_ = options->profile_output_filename_; 641 // TODO: move this to just be an Trace::Start argument 642 Trace::SetDefaultClockSource(options->profile_clock_source_); 643 644 if (options->method_trace_) { 645 Trace::Start(options->method_trace_file_.c_str(), -1, options->method_trace_file_size_, 0, 646 false, false, 0); 647 } 648 649 // Pre-allocate an OutOfMemoryError for the double-OOME case. 650 self->ThrowNewException(ThrowLocation(), "Ljava/lang/OutOfMemoryError;", 651 "OutOfMemoryError thrown while trying to throw OutOfMemoryError; " 652 "no stack available"); 653 pre_allocated_OutOfMemoryError_ = self->GetException(NULL); 654 self->ClearException(); 655 656 VLOG(startup) << "Runtime::Init exiting"; 657 return true; 658} 659 660void Runtime::InitNativeMethods() { 661 VLOG(startup) << "Runtime::InitNativeMethods entering"; 662 Thread* self = Thread::Current(); 663 JNIEnv* env = self->GetJniEnv(); 664 665 // Must be in the kNative state for calling native methods (JNI_OnLoad code). 666 CHECK_EQ(self->GetState(), kNative); 667 668 // First set up JniConstants, which is used by both the runtime's built-in native 669 // methods and libcore. 670 JniConstants::init(env); 671 WellKnownClasses::Init(env); 672 673 // Then set up the native methods provided by the runtime itself. 674 RegisterRuntimeNativeMethods(env); 675 676 // Then set up libcore, which is just a regular JNI library with a regular JNI_OnLoad. 677 // Most JNI libraries can just use System.loadLibrary, but libcore can't because it's 678 // the library that implements System.loadLibrary! 679 { 680 std::string mapped_name(StringPrintf(OS_SHARED_LIB_FORMAT_STR, "javacore")); 681 std::string reason; 682 self->TransitionFromSuspendedToRunnable(); 683 SirtRef<mirror::ClassLoader> class_loader(self, nullptr); 684 if (!instance_->java_vm_->LoadNativeLibrary(mapped_name, class_loader, &reason)) { 685 LOG(FATAL) << "LoadNativeLibrary failed for \"" << mapped_name << "\": " << reason; 686 } 687 self->TransitionFromRunnableToSuspended(kNative); 688 } 689 690 // Initialize well known classes that may invoke runtime native methods. 691 WellKnownClasses::LateInit(env); 692 693 VLOG(startup) << "Runtime::InitNativeMethods exiting"; 694} 695 696void Runtime::InitThreadGroups(Thread* self) { 697 JNIEnvExt* env = self->GetJniEnv(); 698 ScopedJniEnvLocalRefState env_state(env); 699 main_thread_group_ = 700 env->NewGlobalRef(env->GetStaticObjectField( 701 WellKnownClasses::java_lang_ThreadGroup, 702 WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup)); 703 CHECK(main_thread_group_ != NULL || IsCompiler()); 704 system_thread_group_ = 705 env->NewGlobalRef(env->GetStaticObjectField( 706 WellKnownClasses::java_lang_ThreadGroup, 707 WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup)); 708 CHECK(system_thread_group_ != NULL || IsCompiler()); 709} 710 711jobject Runtime::GetMainThreadGroup() const { 712 CHECK(main_thread_group_ != NULL || IsCompiler()); 713 return main_thread_group_; 714} 715 716jobject Runtime::GetSystemThreadGroup() const { 717 CHECK(system_thread_group_ != NULL || IsCompiler()); 718 return system_thread_group_; 719} 720 721jobject Runtime::GetSystemClassLoader() const { 722 CHECK(system_class_loader_ != NULL || IsCompiler()); 723 return system_class_loader_; 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_ZygoteHooks); 735 REGISTER(register_java_lang_Class); 736 REGISTER(register_java_lang_DexCache); 737 REGISTER(register_java_lang_Object); 738 REGISTER(register_java_lang_Runtime); 739 REGISTER(register_java_lang_String); 740 REGISTER(register_java_lang_System); 741 REGISTER(register_java_lang_Thread); 742 REGISTER(register_java_lang_VMClassLoader); 743 REGISTER(register_java_lang_ref_Reference); 744 REGISTER(register_java_lang_reflect_Array); 745 REGISTER(register_java_lang_reflect_Constructor); 746 REGISTER(register_java_lang_reflect_Field); 747 REGISTER(register_java_lang_reflect_Method); 748 REGISTER(register_java_lang_reflect_Proxy); 749 REGISTER(register_java_util_concurrent_atomic_AtomicLong); 750 REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer); 751 REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmVmInternal); 752 REGISTER(register_sun_misc_Unsafe); 753#undef REGISTER 754} 755 756void Runtime::DumpForSigQuit(std::ostream& os) { 757 GetClassLinker()->DumpForSigQuit(os); 758 GetInternTable()->DumpForSigQuit(os); 759 GetJavaVM()->DumpForSigQuit(os); 760 GetHeap()->DumpForSigQuit(os); 761 os << "\n"; 762 763 thread_list_->DumpForSigQuit(os); 764 BaseMutex::DumpAll(os); 765} 766 767void Runtime::DumpLockHolders(std::ostream& os) { 768 uint64_t mutator_lock_owner = Locks::mutator_lock_->GetExclusiveOwnerTid(); 769 pid_t thread_list_lock_owner = GetThreadList()->GetLockOwner(); 770 pid_t classes_lock_owner = GetClassLinker()->GetClassesLockOwner(); 771 pid_t dex_lock_owner = GetClassLinker()->GetDexLockOwner(); 772 if ((thread_list_lock_owner | classes_lock_owner | dex_lock_owner) != 0) { 773 os << "Mutator lock exclusive owner tid: " << mutator_lock_owner << "\n" 774 << "ThreadList lock owner tid: " << thread_list_lock_owner << "\n" 775 << "ClassLinker classes lock owner tid: " << classes_lock_owner << "\n" 776 << "ClassLinker dex lock owner tid: " << dex_lock_owner << "\n"; 777 } 778} 779 780void Runtime::SetStatsEnabled(bool new_state) { 781 if (new_state == true) { 782 GetStats()->Clear(~0); 783 // TODO: wouldn't it make more sense to clear _all_ threads' stats? 784 Thread::Current()->GetStats()->Clear(~0); 785 GetInstrumentation()->InstrumentQuickAllocEntryPoints(); 786 } else { 787 GetInstrumentation()->UninstrumentQuickAllocEntryPoints(); 788 } 789 stats_enabled_ = new_state; 790} 791 792void Runtime::ResetStats(int kinds) { 793 GetStats()->Clear(kinds & 0xffff); 794 // TODO: wouldn't it make more sense to clear _all_ threads' stats? 795 Thread::Current()->GetStats()->Clear(kinds >> 16); 796} 797 798int32_t Runtime::GetStat(int kind) { 799 RuntimeStats* stats; 800 if (kind < (1<<16)) { 801 stats = GetStats(); 802 } else { 803 stats = Thread::Current()->GetStats(); 804 kind >>= 16; 805 } 806 switch (kind) { 807 case KIND_ALLOCATED_OBJECTS: 808 return stats->allocated_objects; 809 case KIND_ALLOCATED_BYTES: 810 return stats->allocated_bytes; 811 case KIND_FREED_OBJECTS: 812 return stats->freed_objects; 813 case KIND_FREED_BYTES: 814 return stats->freed_bytes; 815 case KIND_GC_INVOCATIONS: 816 return stats->gc_for_alloc_count; 817 case KIND_CLASS_INIT_COUNT: 818 return stats->class_init_count; 819 case KIND_CLASS_INIT_TIME: 820 // Convert ns to us, reduce to 32 bits. 821 return static_cast<int>(stats->class_init_time_ns / 1000); 822 case KIND_EXT_ALLOCATED_OBJECTS: 823 case KIND_EXT_ALLOCATED_BYTES: 824 case KIND_EXT_FREED_OBJECTS: 825 case KIND_EXT_FREED_BYTES: 826 return 0; // backward compatibility 827 default: 828 LOG(FATAL) << "Unknown statistic " << kind; 829 return -1; // unreachable 830 } 831} 832 833void Runtime::BlockSignals() { 834 SignalSet signals; 835 signals.Add(SIGPIPE); 836 // SIGQUIT is used to dump the runtime's state (including stack traces). 837 signals.Add(SIGQUIT); 838 // SIGUSR1 is used to initiate a GC. 839 signals.Add(SIGUSR1); 840 signals.Block(); 841} 842 843bool Runtime::AttachCurrentThread(const char* thread_name, bool as_daemon, jobject thread_group, 844 bool create_peer) { 845 bool success = Thread::Attach(thread_name, as_daemon, thread_group, create_peer) != NULL; 846 if (thread_name == NULL) { 847 LOG(WARNING) << *Thread::Current() << " attached without supplying a name"; 848 } 849 return success; 850} 851 852void Runtime::DetachCurrentThread() { 853 Thread* self = Thread::Current(); 854 if (self == NULL) { 855 LOG(FATAL) << "attempting to detach thread that is not attached"; 856 } 857 if (self->HasManagedStack()) { 858 LOG(FATAL) << *Thread::Current() << " attempting to detach while still running code"; 859 } 860 thread_list_->Unregister(self); 861} 862 863 mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryError() const { 864 if (pre_allocated_OutOfMemoryError_ == NULL) { 865 LOG(ERROR) << "Failed to return pre-allocated OOME"; 866 } 867 return pre_allocated_OutOfMemoryError_; 868} 869 870void Runtime::VisitConstantRoots(RootCallback* callback, void* arg) { 871 // Visit the classes held as static in mirror classes, these can be visited concurrently and only 872 // need to be visited once per GC since they never change. 873 mirror::ArtField::VisitRoots(callback, arg); 874 mirror::ArtMethod::VisitRoots(callback, arg); 875 mirror::Class::VisitRoots(callback, arg); 876 mirror::StackTraceElement::VisitRoots(callback, arg); 877 mirror::String::VisitRoots(callback, arg); 878 mirror::Throwable::VisitRoots(callback, arg); 879 // Visit all the primitive array types classes. 880 mirror::PrimitiveArray<uint8_t>::VisitRoots(callback, arg); // BooleanArray 881 mirror::PrimitiveArray<int8_t>::VisitRoots(callback, arg); // ByteArray 882 mirror::PrimitiveArray<uint16_t>::VisitRoots(callback, arg); // CharArray 883 mirror::PrimitiveArray<double>::VisitRoots(callback, arg); // DoubleArray 884 mirror::PrimitiveArray<float>::VisitRoots(callback, arg); // FloatArray 885 mirror::PrimitiveArray<int32_t>::VisitRoots(callback, arg); // IntArray 886 mirror::PrimitiveArray<int64_t>::VisitRoots(callback, arg); // LongArray 887 mirror::PrimitiveArray<int16_t>::VisitRoots(callback, arg); // ShortArray 888} 889 890void Runtime::VisitConcurrentRoots(RootCallback* callback, void* arg, VisitRootFlags flags) { 891 intern_table_->VisitRoots(callback, arg, flags); 892 class_linker_->VisitRoots(callback, arg, flags); 893 Dbg::VisitRoots(callback, arg); 894 if ((flags & kVisitRootFlagNewRoots) == 0) { 895 // Guaranteed to have no new roots in the constant roots. 896 VisitConstantRoots(callback, arg); 897 } 898} 899 900void Runtime::VisitNonThreadRoots(RootCallback* callback, void* arg) { 901 java_vm_->VisitRoots(callback, arg); 902 if (pre_allocated_OutOfMemoryError_ != nullptr) { 903 callback(reinterpret_cast<mirror::Object**>(&pre_allocated_OutOfMemoryError_), arg, 0, 904 kRootVMInternal); 905 DCHECK(pre_allocated_OutOfMemoryError_ != nullptr); 906 } 907 callback(reinterpret_cast<mirror::Object**>(&resolution_method_), arg, 0, kRootVMInternal); 908 DCHECK(resolution_method_ != nullptr); 909 if (HasImtConflictMethod()) { 910 callback(reinterpret_cast<mirror::Object**>(&imt_conflict_method_), arg, 0, kRootVMInternal); 911 } 912 if (HasDefaultImt()) { 913 callback(reinterpret_cast<mirror::Object**>(&default_imt_), arg, 0, kRootVMInternal); 914 } 915 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 916 if (callee_save_methods_[i] != nullptr) { 917 callback(reinterpret_cast<mirror::Object**>(&callee_save_methods_[i]), arg, 0, 918 kRootVMInternal); 919 } 920 } 921 { 922 MutexLock mu(Thread::Current(), method_verifier_lock_); 923 for (verifier::MethodVerifier* verifier : method_verifiers_) { 924 verifier->VisitRoots(callback, arg); 925 } 926 } 927 if (preinitialization_transaction_ != nullptr) { 928 preinitialization_transaction_->VisitRoots(callback, arg); 929 } 930 instrumentation_.VisitRoots(callback, arg); 931} 932 933void Runtime::VisitNonConcurrentRoots(RootCallback* callback, void* arg) { 934 thread_list_->VisitRoots(callback, arg); 935 VisitNonThreadRoots(callback, arg); 936} 937 938void Runtime::VisitRoots(RootCallback* callback, void* arg, VisitRootFlags flags) { 939 VisitConcurrentRoots(callback, arg, flags); 940 VisitNonConcurrentRoots(callback, arg); 941} 942 943mirror::ObjectArray<mirror::ArtMethod>* Runtime::CreateDefaultImt(ClassLinker* cl) { 944 Thread* self = Thread::Current(); 945 SirtRef<mirror::ObjectArray<mirror::ArtMethod> > imtable(self, cl->AllocArtMethodArray(self, 64)); 946 mirror::ArtMethod* imt_conflict_method = Runtime::Current()->GetImtConflictMethod(); 947 for (size_t i = 0; i < static_cast<size_t>(imtable->GetLength()); i++) { 948 imtable->Set<false>(i, imt_conflict_method); 949 } 950 return imtable.get(); 951} 952 953mirror::ArtMethod* Runtime::CreateImtConflictMethod() { 954 Thread* self = Thread::Current(); 955 Runtime* runtime = Runtime::Current(); 956 ClassLinker* class_linker = runtime->GetClassLinker(); 957 SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self)); 958 method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod()); 959 // TODO: use a special method for imt conflict method saves. 960 method->SetDexMethodIndex(DexFile::kDexNoIndex); 961 // When compiling, the code pointer will get set later when the image is loaded. 962 if (runtime->IsCompiler()) { 963 method->SetEntryPointFromPortableCompiledCode(nullptr); 964 method->SetEntryPointFromQuickCompiledCode(nullptr); 965 } else { 966 method->SetEntryPointFromPortableCompiledCode(GetPortableImtConflictTrampoline(class_linker)); 967 method->SetEntryPointFromQuickCompiledCode(GetQuickImtConflictTrampoline(class_linker)); 968 } 969 return method.get(); 970} 971 972mirror::ArtMethod* Runtime::CreateResolutionMethod() { 973 Thread* self = Thread::Current(); 974 Runtime* runtime = Runtime::Current(); 975 ClassLinker* class_linker = runtime->GetClassLinker(); 976 SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self)); 977 method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod()); 978 // TODO: use a special method for resolution method saves 979 method->SetDexMethodIndex(DexFile::kDexNoIndex); 980 // When compiling, the code pointer will get set later when the image is loaded. 981 if (runtime->IsCompiler()) { 982 method->SetEntryPointFromPortableCompiledCode(nullptr); 983 method->SetEntryPointFromQuickCompiledCode(nullptr); 984 } else { 985 method->SetEntryPointFromPortableCompiledCode(GetPortableResolutionTrampoline(class_linker)); 986 method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionTrampoline(class_linker)); 987 } 988 return method.get(); 989} 990 991mirror::ArtMethod* Runtime::CreateCalleeSaveMethod(CalleeSaveType type) { 992 Thread* self = Thread::Current(); 993 Runtime* runtime = Runtime::Current(); 994 ClassLinker* class_linker = runtime->GetClassLinker(); 995 SirtRef<mirror::ArtMethod> method(self, class_linker->AllocArtMethod(self)); 996 method->SetDeclaringClass(mirror::ArtMethod::GetJavaLangReflectArtMethod()); 997 // TODO: use a special method for callee saves 998 method->SetDexMethodIndex(DexFile::kDexNoIndex); 999 method->SetEntryPointFromPortableCompiledCode(nullptr); 1000 method->SetEntryPointFromQuickCompiledCode(nullptr); 1001 DCHECK_NE(instruction_set_, kNone); 1002 return method.get(); 1003} 1004 1005void Runtime::DisallowNewSystemWeaks() { 1006 monitor_list_->DisallowNewMonitors(); 1007 intern_table_->DisallowNewInterns(); 1008 java_vm_->DisallowNewWeakGlobals(); 1009 Dbg::DisallowNewObjectRegistryObjects(); 1010} 1011 1012void Runtime::AllowNewSystemWeaks() { 1013 monitor_list_->AllowNewMonitors(); 1014 intern_table_->AllowNewInterns(); 1015 java_vm_->AllowNewWeakGlobals(); 1016 Dbg::AllowNewObjectRegistryObjects(); 1017} 1018 1019void Runtime::SetInstructionSet(InstructionSet instruction_set) { 1020 instruction_set_ = instruction_set; 1021 if ((instruction_set_ == kThumb2) || (instruction_set_ == kArm)) { 1022 for (int i = 0; i != kLastCalleeSaveType; ++i) { 1023 CalleeSaveType type = static_cast<CalleeSaveType>(i); 1024 callee_save_method_frame_infos_[i] = arm::ArmCalleeSaveMethodFrameInfo(type); 1025 } 1026 } else if (instruction_set_ == kMips) { 1027 for (int i = 0; i != kLastCalleeSaveType; ++i) { 1028 CalleeSaveType type = static_cast<CalleeSaveType>(i); 1029 callee_save_method_frame_infos_[i] = mips::MipsCalleeSaveMethodFrameInfo(type); 1030 } 1031 } else if (instruction_set_ == kX86) { 1032 for (int i = 0; i != kLastCalleeSaveType; ++i) { 1033 CalleeSaveType type = static_cast<CalleeSaveType>(i); 1034 callee_save_method_frame_infos_[i] = x86::X86CalleeSaveMethodFrameInfo(type); 1035 } 1036 } else if (instruction_set_ == kX86_64) { 1037 for (int i = 0; i != kLastCalleeSaveType; ++i) { 1038 CalleeSaveType type = static_cast<CalleeSaveType>(i); 1039 callee_save_method_frame_infos_[i] = x86_64::X86_64CalleeSaveMethodFrameInfo(type); 1040 } 1041 } else if (instruction_set_ == kArm64) { 1042 for (int i = 0; i != kLastCalleeSaveType; ++i) { 1043 CalleeSaveType type = static_cast<CalleeSaveType>(i); 1044 callee_save_method_frame_infos_[i] = arm64::Arm64CalleeSaveMethodFrameInfo(type); 1045 } 1046 } else { 1047 UNIMPLEMENTED(FATAL) << instruction_set_; 1048 } 1049} 1050 1051void Runtime::SetCalleeSaveMethod(mirror::ArtMethod* method, CalleeSaveType type) { 1052 DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType)); 1053 callee_save_methods_[type] = method; 1054} 1055 1056const std::vector<const DexFile*>& Runtime::GetCompileTimeClassPath(jobject class_loader) { 1057 if (class_loader == NULL) { 1058 return GetClassLinker()->GetBootClassPath(); 1059 } 1060 CHECK(UseCompileTimeClassPath()); 1061 CompileTimeClassPaths::const_iterator it = compile_time_class_paths_.find(class_loader); 1062 CHECK(it != compile_time_class_paths_.end()); 1063 return it->second; 1064} 1065 1066void Runtime::SetCompileTimeClassPath(jobject class_loader, 1067 std::vector<const DexFile*>& class_path) { 1068 CHECK(!IsStarted()); 1069 use_compile_time_class_path_ = true; 1070 compile_time_class_paths_.Put(class_loader, class_path); 1071} 1072 1073void Runtime::AddMethodVerifier(verifier::MethodVerifier* verifier) { 1074 DCHECK(verifier != nullptr); 1075 MutexLock mu(Thread::Current(), method_verifier_lock_); 1076 method_verifiers_.insert(verifier); 1077} 1078 1079void Runtime::RemoveMethodVerifier(verifier::MethodVerifier* verifier) { 1080 DCHECK(verifier != nullptr); 1081 MutexLock mu(Thread::Current(), method_verifier_lock_); 1082 auto it = method_verifiers_.find(verifier); 1083 CHECK(it != method_verifiers_.end()); 1084 method_verifiers_.erase(it); 1085} 1086 1087void Runtime::StartProfiler(const char* appDir, const char* procName) { 1088 BackgroundMethodSamplingProfiler::Start(profile_period_s_, profile_duration_s_, appDir, 1089 procName, profile_interval_us_, profile_backoff_coefficient_, profile_start_immediately_); 1090} 1091 1092// Transaction support. 1093void Runtime::EnterTransactionMode(Transaction* transaction) { 1094 DCHECK(IsCompiler()); 1095 DCHECK(transaction != nullptr); 1096 DCHECK(!IsActiveTransaction()); 1097 preinitialization_transaction_ = transaction; 1098} 1099 1100void Runtime::ExitTransactionMode() { 1101 DCHECK(IsCompiler()); 1102 DCHECK(IsActiveTransaction()); 1103 preinitialization_transaction_ = nullptr; 1104} 1105 1106void Runtime::RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, 1107 uint32_t value, bool is_volatile) const { 1108 DCHECK(IsCompiler()); 1109 DCHECK(IsActiveTransaction()); 1110 preinitialization_transaction_->RecordWriteField32(obj, field_offset, value, is_volatile); 1111} 1112 1113void Runtime::RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, 1114 uint64_t value, bool is_volatile) const { 1115 DCHECK(IsCompiler()); 1116 DCHECK(IsActiveTransaction()); 1117 preinitialization_transaction_->RecordWriteField64(obj, field_offset, value, is_volatile); 1118} 1119 1120void Runtime::RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset, 1121 mirror::Object* value, bool is_volatile) const { 1122 DCHECK(IsCompiler()); 1123 DCHECK(IsActiveTransaction()); 1124 preinitialization_transaction_->RecordWriteFieldReference(obj, field_offset, value, is_volatile); 1125} 1126 1127void Runtime::RecordWriteArray(mirror::Array* array, size_t index, uint64_t value) const { 1128 DCHECK(IsCompiler()); 1129 DCHECK(IsActiveTransaction()); 1130 preinitialization_transaction_->RecordWriteArray(array, index, value); 1131} 1132 1133void Runtime::RecordStrongStringInsertion(mirror::String* s, uint32_t hash_code) const { 1134 DCHECK(IsCompiler()); 1135 DCHECK(IsActiveTransaction()); 1136 preinitialization_transaction_->RecordStrongStringInsertion(s, hash_code); 1137} 1138 1139void Runtime::RecordWeakStringInsertion(mirror::String* s, uint32_t hash_code) const { 1140 DCHECK(IsCompiler()); 1141 DCHECK(IsActiveTransaction()); 1142 preinitialization_transaction_->RecordWeakStringInsertion(s, hash_code); 1143} 1144 1145void Runtime::RecordStrongStringRemoval(mirror::String* s, uint32_t hash_code) const { 1146 DCHECK(IsCompiler()); 1147 DCHECK(IsActiveTransaction()); 1148 preinitialization_transaction_->RecordStrongStringRemoval(s, hash_code); 1149} 1150 1151void Runtime::RecordWeakStringRemoval(mirror::String* s, uint32_t hash_code) const { 1152 DCHECK(IsCompiler()); 1153 DCHECK(IsActiveTransaction()); 1154 preinitialization_transaction_->RecordWeakStringRemoval(s, hash_code); 1155} 1156 1157void Runtime::SetFaultMessage(const std::string& message) { 1158 MutexLock mu(Thread::Current(), fault_message_lock_); 1159 fault_message_ = message; 1160} 1161 1162void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* argv) 1163 const { 1164 if (GetInstrumentation()->InterpretOnly()) { 1165 argv->push_back("--compiler-filter=interpret-only"); 1166 } 1167 1168 argv->push_back("--runtime-arg"); 1169 std::string checkstr = "-implicit-checks"; 1170 1171 int nchecks = 0; 1172 char checksep = ':'; 1173 1174 if (!ExplicitNullChecks()) { 1175 checkstr += checksep; 1176 checksep = ','; 1177 checkstr += "null"; 1178 ++nchecks; 1179 } 1180 if (!ExplicitSuspendChecks()) { 1181 checkstr += checksep; 1182 checksep = ','; 1183 checkstr += "suspend"; 1184 ++nchecks; 1185 } 1186 1187 if (!ExplicitStackOverflowChecks()) { 1188 checkstr += checksep; 1189 checksep = ','; 1190 checkstr += "stack"; 1191 ++nchecks; 1192 } 1193 1194 if (nchecks == 0) { 1195 checkstr += ":none"; 1196 } 1197 argv->push_back(checkstr); 1198 1199 // Make the dex2oat instruction set match that of the launching runtime. If we have multiple 1200 // architecture support, dex2oat may be compiled as a different instruction-set than that 1201 // currently being executed. 1202#if defined(__arm__) 1203 argv->push_back("--instruction-set=arm"); 1204#elif defined(__aarch64__) 1205 argv->push_back("--instruction-set=arm64"); 1206#elif defined(__i386__) 1207 argv->push_back("--instruction-set=x86"); 1208#elif defined(__x86_64__) 1209 argv->push_back("--instruction-set=x86_64"); 1210#elif defined(__mips__) 1211 argv->push_back("--instruction-set=mips"); 1212#endif 1213 1214 std::string features("--instruction-set-features="); 1215 features += GetDefaultInstructionSetFeatures(); 1216 argv->push_back(features); 1217} 1218 1219void Runtime::UpdateProfilerState(int state) { 1220 VLOG(profiler) << "Profiler state updated to " << state; 1221} 1222} // namespace art 1223