summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2012-08-07 18:44:40 -0700
committer Mathieu Chartier <mathieuc@google.com> 2012-08-08 09:47:05 -0700
commit46a23638436afdf17330870ef150f5b8eb66410c (patch)
treed9dec192977e0bf75a1bc7ada5b3a90ec9333345
parent77ae36b35d47393335bf5399cab9c91ccf08e88f (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.cc20
-rw-r--r--src/mark_sweep.h10
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_;