Use a sentinel when clearing JIT table entries.
This can help diagnosing crashes we see.
bug: 38128052
bug: 37949368
Test: test.py --jit
Change-Id: I7bf70785e8bd93fb0575ac64b1fb5bcb7d462b10
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 81b87f1..2bd1d64 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -322,12 +322,19 @@
return data - ComputeRootTableSize(roots);
}
+// Use a sentinel for marking entries in the JIT table that have been cleared.
+// This helps diagnosing in case the compiled code tries to wrongly access such
+// entries.
+static mirror::Class* const weak_sentinel = reinterpret_cast<mirror::Class*>(0x1);
+
// Helper for the GC to process a weak class in a JIT root table.
-static inline void ProcessWeakClass(GcRoot<mirror::Class>* root_ptr, IsMarkedVisitor* visitor)
+static inline void ProcessWeakClass(GcRoot<mirror::Class>* root_ptr,
+ IsMarkedVisitor* visitor,
+ mirror::Class* update)
REQUIRES_SHARED(Locks::mutator_lock_) {
// This does not need a read barrier because this is called by GC.
mirror::Class* cls = root_ptr->Read<kWithoutReadBarrier>();
- if (cls != nullptr) {
+ if (cls != nullptr && cls != weak_sentinel) {
DCHECK((cls->IsClass<kDefaultVerifyFlags, kWithoutReadBarrier>()));
// Look at the classloader of the class to know if it has been unloaded.
// This does not need a read barrier because this is called by GC.
@@ -342,7 +349,7 @@
}
} else {
// The class loader is not live, clear the entry.
- *root_ptr = GcRoot<mirror::Class>(nullptr);
+ *root_ptr = GcRoot<mirror::Class>(update);
}
}
}
@@ -356,7 +363,7 @@
for (uint32_t i = 0; i < number_of_roots; ++i) {
// This does not need a read barrier because this is called by GC.
mirror::Object* object = roots[i].Read<kWithoutReadBarrier>();
- if (object == nullptr) {
+ if (object == nullptr || object == weak_sentinel) {
// entry got deleted in a previous sweep.
} else if (object->IsString<kDefaultVerifyFlags, kWithoutReadBarrier>()) {
mirror::Object* new_object = visitor->IsMarked(object);
@@ -371,7 +378,8 @@
roots[i] = GcRoot<mirror::Object>(new_object);
}
} else {
- ProcessWeakClass(reinterpret_cast<GcRoot<mirror::Class>*>(&roots[i]), visitor);
+ ProcessWeakClass(
+ reinterpret_cast<GcRoot<mirror::Class>*>(&roots[i]), visitor, weak_sentinel);
}
}
}
@@ -380,7 +388,7 @@
for (size_t i = 0; i < info->number_of_inline_caches_; ++i) {
InlineCache* cache = &info->cache_[i];
for (size_t j = 0; j < InlineCache::kIndividualCacheSize; ++j) {
- ProcessWeakClass(&cache->classes_[j], visitor);
+ ProcessWeakClass(&cache->classes_[j], visitor, nullptr);
}
}
}