ART: heap counter check
Avoid potential CHECK failure updating num_bytes_freed_revoke_.
Bug: 31023171
Test: art/test.py --host --64 -j32
Change-Id: Ic3fb621c88f5b858f7b4a3ed1aaa1eef36b1e481
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 52afb38..a64a1e7 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -3727,13 +3727,21 @@
task_processor_->AddTask(self, added_task);
}
+void Heap::IncrementNumberOfBytesFreedRevoke(size_t freed_bytes_revoke) {
+ size_t previous_num_bytes_freed_revoke =
+ num_bytes_freed_revoke_.fetch_add(freed_bytes_revoke, std::memory_order_seq_cst);
+ // Check the updated value is less than the number of bytes allocated. There is a risk of
+ // execution being suspended between the increment above and the CHECK below, leading to
+ // the use of previous_num_bytes_freed_revoke in the comparison.
+ CHECK_GE(num_bytes_allocated_.load(std::memory_order_relaxed),
+ previous_num_bytes_freed_revoke + freed_bytes_revoke);
+}
+
void Heap::RevokeThreadLocalBuffers(Thread* thread) {
if (rosalloc_space_ != nullptr) {
size_t freed_bytes_revoke = rosalloc_space_->RevokeThreadLocalBuffers(thread);
if (freed_bytes_revoke > 0U) {
- num_bytes_freed_revoke_.fetch_add(freed_bytes_revoke, std::memory_order_seq_cst);
- CHECK_GE(num_bytes_allocated_.load(std::memory_order_relaxed),
- num_bytes_freed_revoke_.load(std::memory_order_relaxed));
+ IncrementNumberOfBytesFreedRevoke(freed_bytes_revoke);
}
}
if (bump_pointer_space_ != nullptr) {
@@ -3748,9 +3756,7 @@
if (rosalloc_space_ != nullptr) {
size_t freed_bytes_revoke = rosalloc_space_->RevokeThreadLocalBuffers(thread);
if (freed_bytes_revoke > 0U) {
- num_bytes_freed_revoke_.fetch_add(freed_bytes_revoke, std::memory_order_seq_cst);
- CHECK_GE(num_bytes_allocated_.load(std::memory_order_relaxed),
- num_bytes_freed_revoke_.load(std::memory_order_relaxed));
+ IncrementNumberOfBytesFreedRevoke(freed_bytes_revoke);
}
}
}
@@ -3759,9 +3765,7 @@
if (rosalloc_space_ != nullptr) {
size_t freed_bytes_revoke = rosalloc_space_->RevokeAllThreadLocalBuffers();
if (freed_bytes_revoke > 0U) {
- num_bytes_freed_revoke_.fetch_add(freed_bytes_revoke, std::memory_order_seq_cst);
- CHECK_GE(num_bytes_allocated_.load(std::memory_order_relaxed),
- num_bytes_freed_revoke_.load(std::memory_order_relaxed));
+ IncrementNumberOfBytesFreedRevoke(freed_bytes_revoke);
}
}
if (bump_pointer_space_ != nullptr) {