summaryrefslogtreecommitdiff
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc43
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);