diff options
Diffstat (limited to 'runtime/runtime.cc')
| -rw-r--r-- | runtime/runtime.cc | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 6177ef91d7..ee4d669fe0 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -81,6 +81,7 @@ #include "intern_table.h" #include "interpreter/interpreter.h" #include "jit/jit.h" +#include "jit/jit_code_cache.h" #include "jni_internal.h" #include "linear_alloc.h" #include "mirror/array.h" @@ -372,6 +373,7 @@ struct AbortState { void Dump(std::ostream& os) const { if (gAborting > 1) { os << "Runtime aborting --- recursively, so no thread-specific detail!\n"; + DumpRecursiveAbort(os); return; } gAborting++; @@ -428,6 +430,21 @@ struct AbortState { } } } + + // For recursive aborts. + void DumpRecursiveAbort(std::ostream& os) const NO_THREAD_SAFETY_ANALYSIS { + // The only thing we'll attempt is dumping the native stack of the current thread. We will only + // try this if we haven't exceeded an arbitrary amount of recursions, to recover and actually + // die. + // Note: as we're using a global counter for the recursive abort detection, there is a potential + // race here and it is not OK to just print when the counter is "2" (one from + // Runtime::Abort(), one from previous Dump() call). Use a number that seems large enough. + static constexpr size_t kOnlyPrintWhenRecursionLessThan = 100u; + if (gAborting < kOnlyPrintWhenRecursionLessThan) { + gAborting++; + DumpNativeStack(os, GetTid()); + } + } }; void Runtime::Abort(const char* msg) { @@ -442,8 +459,16 @@ void Runtime::Abort(const char* msg) { // Many people have difficulty distinguish aborts from crashes, // so be explicit. + // Note: use cerr on the host to print log lines immediately, so we get at least some output + // in case of recursive aborts. We lose annotation with the source file and line number + // here, which is a minor issue. The same is significantly more complicated on device, + // which is why we ignore the issue there. AbortState state; - LOG(FATAL_WITHOUT_ABORT) << Dumpable<AbortState>(state); + if (kIsTargetBuild) { + LOG(FATAL_WITHOUT_ABORT) << Dumpable<AbortState>(state); + } else { + std::cerr << Dumpable<AbortState>(state); + } // Sometimes we dump long messages, and the Android abort message only retains the first line. // In those cases, just log the message again, to avoid logcat limits. @@ -492,6 +517,14 @@ void Runtime::SweepSystemWeaks(IsMarkedVisitor* visitor) { GetMonitorList()->SweepMonitorList(visitor); GetJavaVM()->SweepJniWeakGlobals(visitor); GetHeap()->SweepAllocationRecords(visitor); + if (GetJit() != nullptr) { + // Visit JIT literal tables. Objects in these tables are classes and strings + // and only classes can be affected by class unloading. The strings always + // stay alive as they are strongly interned. + // TODO: Move this closer to CleanupClassLoaders, to avoid blocking weak accesses + // from mutators. See b/32167580. + GetJit()->GetCodeCache()->SweepRootTables(visitor); + } // All other generic system-weak holders. for (gc::AbstractSystemWeakHolder* holder : system_weak_holders_) { @@ -1029,8 +1062,10 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity), runtime_options.GetOrDefault(Opt::Image), runtime_options.GetOrDefault(Opt::ImageInstructionSet), - xgc_option.collector_type_, - runtime_options.GetOrDefault(Opt::BackgroundGc), + // Override the collector type to CC if the read barrier config. + kUseReadBarrier ? gc::kCollectorTypeCC : xgc_option.collector_type_, + kUseReadBarrier ? BackgroundGcOption(gc::kCollectorTypeCCBackground) + : runtime_options.GetOrDefault(Opt::BackgroundGc), runtime_options.GetOrDefault(Opt::LargeObjectSpace), runtime_options.GetOrDefault(Opt::LargeObjectThreshold), runtime_options.GetOrDefault(Opt::ParallelGCThreads), @@ -2148,7 +2183,7 @@ void Runtime::RemoveSystemWeakHolder(gc::AbstractSystemWeakHolder* holder) { NO_RETURN void Runtime::Aborter(const char* abort_message) { -#ifdef __ANDROID__ +#ifdef ART_TARGET_ANDROID android_set_abort_message(abort_message); #endif Runtime::Abort(abort_message); |