diff options
author | Hiroshi Yamauchi <yamauchi@google.com> | 2015-05-05 17:01:33 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-05-05 17:01:37 +0000 |
commit | d117954a3b10aaf2141beabb12762d68d4b945ba (patch) | |
tree | 928f9fd0da2abab35e6ff47747adf31dff06fade /runtime/gc | |
parent | 6985da634653fd825974bdd89cf488c6dd386fd0 (diff) | |
parent | d45c84364db585f2e45a6264ae3116d004858677 (diff) | |
download | art-d117954a3b10aaf2141beabb12762d68d4b945ba.zip art-d117954a3b10aaf2141beabb12762d68d4b945ba.tar.gz art-d117954a3b10aaf2141beabb12762d68d4b945ba.tar.bz2 |
Merge "Request full/partial GC type from VMRuntime.requestConcurrentGC()." into mnc-dev
Diffstat (limited to 'runtime/gc')
-rw-r--r-- | runtime/gc/heap-inl.h | 2 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 30 | ||||
-rw-r--r-- | runtime/gc/heap.h | 6 |
3 files changed, 24 insertions, 14 deletions
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h index 9b5d577..fbf36e8 100644 --- a/runtime/gc/heap-inl.h +++ b/runtime/gc/heap-inl.h @@ -416,7 +416,7 @@ inline bool Heap::IsOutOfMemoryOnAllocation(AllocatorType allocator_type, size_t inline void Heap::CheckConcurrentGC(Thread* self, size_t new_num_bytes_allocated, mirror::Object** obj) { if (UNLIKELY(new_num_bytes_allocated >= concurrent_start_bytes_)) { - RequestConcurrentGCAndSaveObject(self, obj); + RequestConcurrentGCAndSaveObject(self, false, obj); } } diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index b80c4b6..cbbc76c 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -3325,20 +3325,24 @@ void Heap::AddFinalizerReference(Thread* self, mirror::Object** object) { *object = soa.Decode<mirror::Object*>(arg.get()); } -void Heap::RequestConcurrentGCAndSaveObject(Thread* self, mirror::Object** obj) { +void Heap::RequestConcurrentGCAndSaveObject(Thread* self, bool force_full, mirror::Object** obj) { StackHandleScope<1> hs(self); HandleWrapper<mirror::Object> wrapper(hs.NewHandleWrapper(obj)); - RequestConcurrentGC(self); + RequestConcurrentGC(self, force_full); } class Heap::ConcurrentGCTask : public HeapTask { public: - explicit ConcurrentGCTask(uint64_t target_time) : HeapTask(target_time) { } + explicit ConcurrentGCTask(uint64_t target_time, bool force_full) + : HeapTask(target_time), force_full_(force_full) { } virtual void Run(Thread* self) OVERRIDE { gc::Heap* heap = Runtime::Current()->GetHeap(); - heap->ConcurrentGC(self); + heap->ConcurrentGC(self, force_full_); heap->ClearConcurrentGCRequest(); } + + private: + const bool force_full_; // If true, force full (or partial) collection. }; static bool CanAddHeapTask(Thread* self) LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_) { @@ -3351,24 +3355,30 @@ void Heap::ClearConcurrentGCRequest() { concurrent_gc_pending_.StoreRelaxed(false); } -void Heap::RequestConcurrentGC(Thread* self) { +void Heap::RequestConcurrentGC(Thread* self, bool force_full) { if (CanAddHeapTask(self) && concurrent_gc_pending_.CompareExchangeStrongSequentiallyConsistent(false, true)) { - task_processor_->AddTask(self, new ConcurrentGCTask(NanoTime())); // Start straight away. + task_processor_->AddTask(self, new ConcurrentGCTask(NanoTime(), // Start straight away. + force_full)); } } -void Heap::ConcurrentGC(Thread* self) { +void Heap::ConcurrentGC(Thread* self, bool force_full) { if (!Runtime::Current()->IsShuttingDown(self)) { // Wait for any GCs currently running to finish. if (WaitForGcToComplete(kGcCauseBackground, self) == collector::kGcTypeNone) { // If the we can't run the GC type we wanted to run, find the next appropriate one and try that // instead. E.g. can't do partial, so do full instead. - if (CollectGarbageInternal(next_gc_type_, kGcCauseBackground, false) == + collector::GcType next_gc_type = next_gc_type_; + // If forcing full and next gc type is sticky, override with a non-sticky type. + if (force_full && next_gc_type == collector::kGcTypeSticky) { + next_gc_type = HasZygoteSpace() ? collector::kGcTypePartial : collector::kGcTypeFull; + } + if (CollectGarbageInternal(next_gc_type, kGcCauseBackground, false) == collector::kGcTypeNone) { for (collector::GcType gc_type : gc_plan_) { // Attempt to run the collector, if we succeed, we are done. - if (gc_type > next_gc_type_ && + if (gc_type > next_gc_type && CollectGarbageInternal(gc_type, kGcCauseBackground, false) != collector::kGcTypeNone) { break; @@ -3553,7 +3563,7 @@ void Heap::RegisterNativeAllocation(JNIEnv* env, size_t bytes) { UpdateMaxNativeFootprint(); } else if (!IsGCRequestPending()) { if (IsGcConcurrent()) { - RequestConcurrentGC(self); + RequestConcurrentGC(self, true); // Request non-sticky type. } else { CollectGarbageInternal(gc_type, kGcCauseForNativeAlloc, false); } diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 2ce2b3a..90249f9 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -288,7 +288,7 @@ class Heap { // Does a concurrent GC, should only be called by the GC daemon thread // through runtime. - void ConcurrentGC(Thread* self) LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_); + void ConcurrentGC(Thread* self, bool force_full) LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_); // Implements VMDebug.countInstancesOfClass and JDWP VM_InstanceCount. // The boolean decides whether to use IsAssignableFrom or == when comparing classes. @@ -664,7 +664,7 @@ class Heap { void RequestTrim(Thread* self) LOCKS_EXCLUDED(pending_task_lock_); // Request asynchronous GC. - void RequestConcurrentGC(Thread* self) LOCKS_EXCLUDED(pending_task_lock_); + void RequestConcurrentGC(Thread* self, bool force_full) LOCKS_EXCLUDED(pending_task_lock_); // Whether or not we may use a garbage collector, used so that we only create collectors we need. bool MayUseCollector(CollectorType type) const; @@ -786,7 +786,7 @@ class Heap { void RequestCollectorTransition(CollectorType desired_collector_type, uint64_t delta_time) LOCKS_EXCLUDED(pending_task_lock_); - void RequestConcurrentGCAndSaveObject(Thread* self, mirror::Object** obj) + void RequestConcurrentGCAndSaveObject(Thread* self, bool force_full, mirror::Object** obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool IsGCRequestPending() const; |