Fix cases where we miss instrumentation changes
Moved allocation stack push to after we record the allocation since
it can cause thread suspension.
Added handling in entrypoint utils for thread suspension cases.
Keep the AllocRecordObjectMap around since we do not want to delete
it if there are any threads waiting on new_record_condition_. The
condition guards adding stack traces while the GC is running. If we
delete the map and there are still waiters that did not resume, it
caused a CHECK failure. This could happen in cases where one thread
disables allocation tracking while other threads are about to
resume from the condition.
Bug: 27506909
(cherry picked from commit 0f394021d6abfdf9ebea6c7f405ec936a812ea62)
Change-Id: I1dc51e9f000684b4032b57beab59d317ece26f06
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 7e7d904..3e6b453 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -173,7 +173,10 @@
if (klass == nullptr) {
return nullptr;
}
- return klass->Alloc<kInstrumented>(self, Runtime::Current()->GetHeap()->GetCurrentAllocator());
+ // CheckObjectAlloc can cause thread suspension which means we may now be instrumented.
+ return klass->Alloc</*kInstrumented*/true>(
+ self,
+ Runtime::Current()->GetHeap()->GetCurrentAllocator());
}
DCHECK(klass != nullptr);
return klass->Alloc<kInstrumented>(self, allocator_type);
@@ -194,7 +197,9 @@
}
gc::Heap* heap = Runtime::Current()->GetHeap();
// Pass in false since the object cannot be finalizable.
- return klass->Alloc<kInstrumented, false>(self, heap->GetCurrentAllocator());
+ // CheckClassInitializedForObjectAlloc can cause thread suspension which means we may now be
+ // instrumented.
+ return klass->Alloc</*kInstrumented*/true, false>(self, heap->GetCurrentAllocator());
}
// Pass in false since the object cannot be finalizable.
return klass->Alloc<kInstrumented, false>(self, allocator_type);
@@ -265,9 +270,12 @@
return nullptr;
}
gc::Heap* heap = Runtime::Current()->GetHeap();
- return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
- klass->GetComponentSizeShift(),
- heap->GetCurrentAllocator());
+ // CheckArrayAlloc can cause thread suspension which means we may now be instrumented.
+ return mirror::Array::Alloc</*kInstrumented*/true>(self,
+ klass,
+ component_count,
+ klass->GetComponentSizeShift(),
+ heap->GetCurrentAllocator());
}
return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
klass->GetComponentSizeShift(), allocator_type);