Synchronize JNI critical calls with the CC collector thread flip.
JNI critical calls (like GetArrayElementsCritical) would need to block
for the whole GC run to finish if the CC collector GC is ongoing. This
CL changes it so that they don't need to block for the GC run, but
only for the duration of the thread flip operation, which is much
shorter. This is valid due to the to-space invariant.
Bug: 12687968
Bug: 19235243
Change-Id: I1b6b4ae4fa539ddc0ec50b10ae8c8709f2a12fe8
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index d94f109..85688ae 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -300,6 +300,12 @@
void IncrementDisableMovingGC(Thread* self) REQUIRES(!*gc_complete_lock_);
void DecrementDisableMovingGC(Thread* self) REQUIRES(!*gc_complete_lock_);
+ // Temporarily disable thread flip for JNI critical calls.
+ void IncrementDisableThreadFlip(Thread* self) REQUIRES(!*thread_flip_lock_);
+ void DecrementDisableThreadFlip(Thread* self) REQUIRES(!*thread_flip_lock_);
+ void ThreadFlipBegin(Thread* self) REQUIRES(!*thread_flip_lock_);
+ void ThreadFlipEnd(Thread* self) REQUIRES(!*thread_flip_lock_);
+
// Clear all of the mark bits, doesn't clear bitmaps which have the same live bits as mark bits.
void ClearMarkedObjects() REQUIRES(Locks::heap_bitmap_lock_);
@@ -1065,6 +1071,12 @@
Mutex* gc_complete_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
std::unique_ptr<ConditionVariable> gc_complete_cond_ GUARDED_BY(gc_complete_lock_);
+ // Used to synchronize between JNI critical calls and the thread flip of the CC collector.
+ Mutex* thread_flip_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ std::unique_ptr<ConditionVariable> thread_flip_cond_ GUARDED_BY(thread_flip_lock_);
+ size_t disable_thread_flip_count_ GUARDED_BY(thread_flip_lock_);
+ bool thread_flip_running_ GUARDED_BY(thread_flip_lock_);
+
// Reference processor;
std::unique_ptr<ReferenceProcessor> reference_processor_;