Change IsMovingGCDisabled to take into account GC critical sections
Fixes CC test 130.
Test: test-art-host
Change-Id: I39a0d6b88a7e651a5fb2320fd34c5a8bdc615345
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index a78de37..e4f3dff 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -188,6 +188,7 @@
disable_thread_flip_count_(0),
thread_flip_running_(false),
collector_type_running_(kCollectorTypeNone),
+ thread_running_gc_(nullptr),
last_gc_type_(collector::kGcTypeNone),
next_gc_type_(collector::kGcTypePartial),
capacity_(capacity),
@@ -1386,6 +1387,7 @@
// Ensure there is only one GC at a time.
WaitForGcToCompleteLocked(cause, self);
collector_type_running_ = collector_type;
+ thread_running_gc_ = self;
}
void Heap::TrimSpaces(Thread* self) {
@@ -2785,6 +2787,7 @@
}
// Reset.
running_collection_is_blocking_ = false;
+ thread_running_gc_ = nullptr;
// Wake anyone who may have been waiting for the GC to complete.
gc_complete_cond_->Broadcast(self);
}
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index a4d300b..0d56213 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -736,7 +736,9 @@
bool IsMovingGCDisabled(Thread* self) REQUIRES(!*gc_complete_lock_) {
MutexLock mu(self, *gc_complete_lock_);
- return disable_moving_gc_count_ > 0;
+ // If we are in a GC critical section or the disable moving GC count is non zero then moving
+ // GC is guaranteed to not start.
+ return disable_moving_gc_count_ > 0 || thread_running_gc_ == self;
}
// Request an asynchronous trim.
@@ -1189,6 +1191,9 @@
// True while the garbage collector is running.
volatile CollectorType collector_type_running_ GUARDED_BY(gc_complete_lock_);
+ // The thread currently running the GC.
+ volatile Thread* thread_running_gc_ GUARDED_BY(gc_complete_lock_);
+
// Last Gc type we ran. Used by WaitForConcurrentGc to know which Gc was waited on.
volatile collector::GcType last_gc_type_ GUARDED_BY(gc_complete_lock_);
collector::GcType next_gc_type_;