diff options
| author | 2012-08-07 18:44:40 -0700 | |
|---|---|---|
| committer | 2012-08-08 09:47:05 -0700 | |
| commit | 46a23638436afdf17330870ef150f5b8eb66410c (patch) | |
| tree | d9dec192977e0bf75a1bc7ada5b3a90ec9333345 | |
| parent | 77ae36b35d47393335bf5399cab9c91ccf08e88f (diff) | |
Fix SweepSystemWeaks not checking the correct bitmaps due to bitmap swapping.
This error was causing GCs to occasionally free weak objects which were still in use (Monitors, etc..).
Change-Id: I2f4cfee1e76f2bb01d745ec8316774205f69c42f
| -rw-r--r-- | src/mark_sweep.cc | 20 | ||||
| -rw-r--r-- | src/mark_sweep.h | 10 |
2 files changed, 19 insertions, 11 deletions
diff --git a/src/mark_sweep.cc b/src/mark_sweep.cc index df394db90a..7adc34436f 100644 --- a/src/mark_sweep.cc +++ b/src/mark_sweep.cc @@ -294,23 +294,26 @@ void MarkSweep::ReMarkRoots() { Runtime::Current()->VisitRoots(ReMarkObjectVisitor, this); } -void MarkSweep::SweepJniWeakGlobals() { +void MarkSweep::SweepJniWeakGlobals(HeapBitmap* bitmap) { JavaVMExt* vm = Runtime::Current()->GetJavaVM(); MutexLock mu(vm->weak_globals_lock); IndirectReferenceTable* table = &vm->weak_globals; typedef IndirectReferenceTable::iterator It; // TODO: C++0x auto for (It it = table->begin(), end = table->end(); it != end; ++it) { const Object** entry = *it; - if (!heap_->GetMarkBitmap()->Test(*entry)) { + if (!bitmap->Test(*entry)) { *entry = kClearedJniWeakGlobal; } } } -void MarkSweep::SweepSystemWeaks() { - Runtime::Current()->GetInternTable()->SweepInternTableWeaks(IsMarked, this); - Runtime::Current()->GetMonitorList()->SweepMonitorList(IsMarked, this); - SweepJniWeakGlobals(); +void MarkSweep::SweepSystemWeaks(bool swap_bitmaps) { + Runtime* runtime = Runtime::Current(); + runtime->GetInternTable()->SweepInternTableWeaks(swap_bitmaps ? IsLiveCallback : IsMarkedCallback, + this); + runtime->GetMonitorList()->SweepMonitorList(swap_bitmaps ? IsLiveCallback : IsMarkedCallback, + this); + SweepJniWeakGlobals(swap_bitmaps ? GetHeap()->GetLiveBitmap() : GetHeap()->GetMarkBitmap()); } struct SweepCallbackContext { @@ -361,11 +364,12 @@ void MarkSweep::ZygoteSweepCallback(size_t num_ptrs, Object** ptrs, void* arg) { } void MarkSweep::Sweep(bool partial) { - SweepSystemWeaks(); + // If we don't swap bitmaps then we can not do this concurrently. + SweepSystemWeaks(true); DCHECK(mark_stack_->IsEmpty()); - const std::vector<Space*>& spaces = heap_->GetSpaces(); + const Spaces& spaces = heap_->GetSpaces(); SweepCallbackContext scc; scc.heap = heap_; for (size_t i = 0; i < spaces.size(); ++i) { diff --git a/src/mark_sweep.h b/src/mark_sweep.h index 108da877e2..189462f5d3 100644 --- a/src/mark_sweep.h +++ b/src/mark_sweep.h @@ -99,10 +99,14 @@ class MarkSweep { return heap_->GetMarkBitmap()->Test(object); } - static bool IsMarked(const Object* object, void* arg) { + static bool IsMarkedCallback(const Object* object, void* arg) { return reinterpret_cast<MarkSweep*>(arg)->IsMarked(object); } + static bool IsLiveCallback(const Object* object, void* arg) { + return reinterpret_cast<MarkSweep*>(arg)->GetHeap()->GetLiveBitmap()->Test(object); + } + static void MarkObjectVisitor(const Object* root, void* arg); static void ReMarkObjectVisitor(const Object* root, void* arg); @@ -250,8 +254,8 @@ class MarkSweep { Object** finalizer_references, Object** phantom_references); - void SweepSystemWeaks(); - void SweepJniWeakGlobals(); + void SweepSystemWeaks(bool swap_bitmaps); + void SweepJniWeakGlobals(HeapBitmap* bitmap); // Current space, we check this space first to avoid searching for the appropriate space for an object. SpaceBitmap* current_mark_bitmap_; |