summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/gc/allocation_record.cc6
-rw-r--r--runtime/gc/heap.cc30
2 files changed, 21 insertions, 15 deletions
diff --git a/runtime/gc/allocation_record.cc b/runtime/gc/allocation_record.cc
index 73190455cf..e3714bbde6 100644
--- a/runtime/gc/allocation_record.cc
+++ b/runtime/gc/allocation_record.cc
@@ -288,6 +288,12 @@ void AllocRecordObjectMap::RecordAllocation(Thread* self, mirror::Object* obj, m
records->new_record_condition_.WaitHoldingLocks(self);
}
+ if (!heap->IsAllocTrackingEnabled()) {
+ // Return if the allocation tracking has been disabled while waiting for system weak access
+ // above.
+ return;
+ }
+
DCHECK_LE(records->Size(), records->alloc_record_max_);
// Get stack trace.
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index f4fccee034..4ff0c6bfbd 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -3960,31 +3960,31 @@ void Heap::SweepAllocationRecords(IsMarkedVisitor* visitor) const {
void Heap::AllowNewAllocationRecords() const {
CHECK(!kUseReadBarrier);
- if (IsAllocTrackingEnabled()) {
- MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
- if (IsAllocTrackingEnabled()) {
- GetAllocationRecords()->AllowNewAllocationRecords();
- }
+ MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
+ AllocRecordObjectMap* allocation_records = GetAllocationRecords();
+ if (allocation_records != nullptr) {
+ allocation_records->AllowNewAllocationRecords();
}
}
void Heap::DisallowNewAllocationRecords() const {
CHECK(!kUseReadBarrier);
- if (IsAllocTrackingEnabled()) {
- MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
- if (IsAllocTrackingEnabled()) {
- GetAllocationRecords()->DisallowNewAllocationRecords();
- }
+ MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
+ AllocRecordObjectMap* allocation_records = GetAllocationRecords();
+ if (allocation_records != nullptr) {
+ allocation_records->DisallowNewAllocationRecords();
}
}
void Heap::BroadcastForNewAllocationRecords() const {
CHECK(kUseReadBarrier);
- if (IsAllocTrackingEnabled()) {
- MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
- if (IsAllocTrackingEnabled()) {
- GetAllocationRecords()->BroadcastForNewAllocationRecords();
- }
+ // Always broadcast without checking IsAllocTrackingEnabled() because IsAllocTrackingEnabled() may
+ // be set to false while some threads are waiting for system weak access in
+ // AllocRecordObjectMap::RecordAllocation() and we may fail to wake them up. b/27467554.
+ MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
+ AllocRecordObjectMap* allocation_records = GetAllocationRecords();
+ if (allocation_records != nullptr) {
+ allocation_records->BroadcastForNewAllocationRecords();
}
}