diff options
| -rw-r--r-- | runtime/gc/heap.cc | 26 | ||||
| -rw-r--r-- | runtime/gc/heap.h | 8 | ||||
| -rw-r--r-- | runtime/native/dalvik_system_VMRuntime.cc | 9 | ||||
| -rw-r--r-- | runtime/well_known_classes.cc | 2 | ||||
| -rw-r--r-- | runtime/well_known_classes.h | 1 |
5 files changed, 37 insertions, 9 deletions
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 10fe64e1e0..d420500592 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -142,6 +142,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max zygote_creation_lock_("zygote creation lock", kZygoteCreationLock), zygote_space_(nullptr), large_object_threshold_(large_object_threshold), + gc_request_pending_(false), collector_type_running_(kCollectorTypeNone), last_gc_type_(collector::kGcTypeNone), next_gc_type_(collector::kGcTypePartial), @@ -409,6 +410,8 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max gc_complete_lock_ = new Mutex("GC complete lock"); gc_complete_cond_.reset(new ConditionVariable("GC complete condition variable", *gc_complete_lock_)); + gc_request_lock_ = new Mutex("GC request lock"); + gc_request_cond_.reset(new ConditionVariable("GC request condition variable", *gc_request_lock_)); heap_trim_request_lock_ = new Mutex("Heap trim request lock"); last_gc_size_ = GetBytesAllocated(); if (ignore_max_footprint_) { @@ -3038,12 +3041,7 @@ void Heap::RequestConcurrentGC(Thread* self) { self->IsHandlingStackOverflow()) { return; } - JNIEnv* env = self->GetJniEnv(); - DCHECK(WellKnownClasses::java_lang_Daemons != nullptr); - DCHECK(WellKnownClasses::java_lang_Daemons_requestGC != nullptr); - env->CallStaticVoidMethod(WellKnownClasses::java_lang_Daemons, - WellKnownClasses::java_lang_Daemons_requestGC); - CHECK(!env->ExceptionCheck()); + NotifyConcurrentGCRequest(self); } void Heap::ConcurrentGC(Thread* self) { @@ -3276,5 +3274,21 @@ void Heap::ClearMarkedObjects() { } } +void Heap::WaitForConcurrentGCRequest(Thread* self) { + ScopedThreadStateChange tsc(self, kBlocked); + MutexLock mu(self, *gc_request_lock_); + while (!gc_request_pending_) { + gc_request_cond_->Wait(self); + } + gc_request_pending_ = false; +} + +void Heap::NotifyConcurrentGCRequest(Thread* self) { + ScopedThreadStateChange tsc(self, kBlocked); + MutexLock mu(self, *gc_request_lock_); + gc_request_pending_ = true; + gc_request_cond_->Signal(self); +} + } // namespace gc } // namespace art diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 4e1a0ff242..529af9539e 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -611,6 +611,9 @@ class Heap { return zygote_space_ != nullptr; } + void WaitForConcurrentGCRequest(Thread* self) LOCKS_EXCLUDED(gc_request_lock_); + void NotifyConcurrentGCRequest(Thread* self) LOCKS_EXCLUDED(gc_request_lock_); + private: // Compact source space to target space. void Compact(space::ContinuousMemMapAllocSpace* target_space, @@ -874,6 +877,11 @@ class Heap { Mutex* gc_complete_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; std::unique_ptr<ConditionVariable> gc_complete_cond_ GUARDED_BY(gc_complete_lock_); + // Guards concurrent GC requests. + Mutex* gc_request_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + std::unique_ptr<ConditionVariable> gc_request_cond_ GUARDED_BY(gc_request_lock_); + bool gc_request_pending_ GUARDED_BY(gc_request_lock_); + // Reference processor; ReferenceProcessor reference_processor_; diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index d40d64b437..a348432340 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -221,6 +221,13 @@ static void VMRuntime_concurrentGC(JNIEnv* env, jobject) { Runtime::Current()->GetHeap()->ConcurrentGC(ThreadForEnv(env)); } +static void VMRuntime_requestConcurrentGC(JNIEnv* env, jobject) { + Runtime::Current()->GetHeap()->NotifyConcurrentGCRequest(ThreadForEnv(env)); +} +static void VMRuntime_waitForConcurrentGCRequest(JNIEnv* env, jobject) { + Runtime::Current()->GetHeap()->WaitForConcurrentGCRequest(ThreadForEnv(env)); +} + typedef std::map<std::string, mirror::String*> StringTable; static void PreloadDexCachesStringsCallback(mirror::Object** root, void* arg, @@ -559,6 +566,8 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(VMRuntime, classPath, "()Ljava/lang/String;"), NATIVE_METHOD(VMRuntime, clearGrowthLimit, "()V"), NATIVE_METHOD(VMRuntime, concurrentGC, "()V"), + NATIVE_METHOD(VMRuntime, requestConcurrentGC, "()V"), + NATIVE_METHOD(VMRuntime, waitForConcurrentGCRequest, "()V"), NATIVE_METHOD(VMRuntime, disableJitCompilation, "()V"), NATIVE_METHOD(VMRuntime, getTargetHeapUtilization, "()F"), NATIVE_METHOD(VMRuntime, isDebuggerActive, "!()Z"), diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 80bed23b77..e368d2c08c 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -66,7 +66,6 @@ jmethodID WellKnownClasses::java_lang_Byte_valueOf; jmethodID WellKnownClasses::java_lang_Character_valueOf; jmethodID WellKnownClasses::java_lang_ClassLoader_loadClass; jmethodID WellKnownClasses::java_lang_ClassNotFoundException_init; -jmethodID WellKnownClasses::java_lang_Daemons_requestGC; jmethodID WellKnownClasses::java_lang_Daemons_requestHeapTrim; jmethodID WellKnownClasses::java_lang_Daemons_start; jmethodID WellKnownClasses::java_lang_Daemons_stop; @@ -205,7 +204,6 @@ void WellKnownClasses::Init(JNIEnv* env) { java_lang_ClassNotFoundException_init = CacheMethod(env, java_lang_ClassNotFoundException, false, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V"); java_lang_ClassLoader_loadClass = CacheMethod(env, java_lang_ClassLoader, false, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); - java_lang_Daemons_requestGC = CacheMethod(env, java_lang_Daemons, true, "requestGC", "()V"); java_lang_Daemons_requestHeapTrim = CacheMethod(env, java_lang_Daemons, true, "requestHeapTrim", "()V"); java_lang_Daemons_start = CacheMethod(env, java_lang_Daemons, true, "start", "()V"); java_lang_Daemons_stop = CacheMethod(env, java_lang_Daemons, true, "stop", "()V"); diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index cb75e6ed7d..1a4f0f8b85 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -77,7 +77,6 @@ struct WellKnownClasses { static jmethodID java_lang_Character_valueOf; static jmethodID java_lang_ClassLoader_loadClass; static jmethodID java_lang_ClassNotFoundException_init; - static jmethodID java_lang_Daemons_requestGC; static jmethodID java_lang_Daemons_requestHeapTrim; static jmethodID java_lang_Daemons_start; static jmethodID java_lang_Daemons_stop; |