Revision: 22844
Author: [email protected]
Date: Tue Aug 5 07:29:13 2014 UTC
Log: Remove all encountered weak maps from the list of weak
collections when incremental marking is aborted.
BUG=399527
LOG=n
[email protected]
Review URL: https://codereview.chromium.org/439233002
http://code.google.com/p/v8/source/detail?r=22844
Modified:
/branches/bleeding_edge/src/gc-tracer.cc
/branches/bleeding_edge/src/gc-tracer.h
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/src/mark-compact.h
/branches/bleeding_edge/test/cctest/cctest.h
/branches/bleeding_edge/test/cctest/test-heap.cc
/branches/bleeding_edge/test/cctest/test-weakmaps.cc
=======================================
--- /branches/bleeding_edge/src/gc-tracer.cc Fri Aug 1 07:41:46 2014 UTC
+++ /branches/bleeding_edge/src/gc-tracer.cc Tue Aug 5 07:29:13 2014 UTC
@@ -258,6 +258,8 @@
current_.scopes[Scope::MC_WEAKCOLLECTION_PROCESS]);
PrintF("weakcollection_clear=%.1f ",
current_.scopes[Scope::MC_WEAKCOLLECTION_CLEAR]);
+ PrintF("weakcollection_abort=%.1f ",
+ current_.scopes[Scope::MC_WEAKCOLLECTION_ABORT]);
PrintF("total_size_before=%" V8_PTR_PREFIX "d ",
current_.start_object_size);
PrintF("total_size_after=%" V8_PTR_PREFIX "d ",
current_.end_object_size);
=======================================
--- /branches/bleeding_edge/src/gc-tracer.h Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/gc-tracer.h Tue Aug 5 07:29:13 2014 UTC
@@ -103,6 +103,7 @@
MC_UPDATE_MISC_POINTERS,
MC_WEAKCOLLECTION_PROCESS,
MC_WEAKCOLLECTION_CLEAR,
+ MC_WEAKCOLLECTION_ABORT,
MC_FLUSH_CODE,
NUMBER_OF_SCOPES
};
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/mark-compact.cc Tue Aug 5 07:29:13 2014 UTC
@@ -968,6 +968,7 @@
if (was_marked_incrementally_ && abort_incremental_marking_) {
heap()->incremental_marking()->Abort();
ClearMarkbits();
+ AbortWeakCollections();
AbortCompaction();
was_marked_incrementally_ = false;
}
@@ -2798,6 +2799,20 @@
}
heap()->set_encountered_weak_collections(Smi::FromInt(0));
}
+
+
+void MarkCompactCollector::AbortWeakCollections() {
+ GCTracer::Scope gc_scope(heap()->tracer(),
+ GCTracer::Scope::MC_WEAKCOLLECTION_ABORT);
+ Object* weak_collection_obj = heap()->encountered_weak_collections();
+ while (weak_collection_obj != Smi::FromInt(0)) {
+ JSWeakCollection* weak_collection =
+ reinterpret_cast<JSWeakCollection*>(weak_collection_obj);
+ weak_collection_obj = weak_collection->next();
+ weak_collection->set_next(heap()->undefined_value());
+ }
+ heap()->set_encountered_weak_collections(Smi::FromInt(0));
+}
void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot)
{
=======================================
--- /branches/bleeding_edge/src/mark-compact.h Mon Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/mark-compact.h Tue Aug 5 07:29:13 2014 UTC
@@ -858,6 +858,10 @@
// The linked list of all encountered weak maps is destroyed.
void ClearWeakCollections();
+ // We have to remove all encountered weak maps from the list of weak
+ // collections when incremental marking is aborted.
+ void AbortWeakCollections();
+
//
-----------------------------------------------------------------------
// Phase 2: Sweeping to clear mark bits and free non-live objects for
// a non-compacting collection.
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.h Wed Jul 30 13:54:45 2014
UTC
+++ /branches/bleeding_edge/test/cctest/cctest.h Tue Aug 5 07:29:13 2014
UTC
@@ -493,6 +493,26 @@
space->ResetFreeList();
space->ClearStats();
}
+
+
+// Helper function that simulates many incremental marking steps until
+// marking is completed.
+static inline void SimulateIncrementalMarking(i::Heap* heap) {
+ i::MarkCompactCollector* collector = heap->mark_compact_collector();
+ i::IncrementalMarking* marking = heap->incremental_marking();
+ if (collector->sweeping_in_progress()) {
+ collector->EnsureSweepingCompleted();
+ }
+ CHECK(marking->IsMarking() || marking->IsStopped());
+ if (marking->IsStopped()) {
+ marking->Start();
+ }
+ CHECK(marking->IsMarking());
+ while (!marking->IsComplete()) {
+ marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+ }
+ CHECK(marking->IsComplete());
+}
// Helper class for new allocations tracking and checking.
=======================================
--- /branches/bleeding_edge/test/cctest/test-heap.cc Mon Aug 4 11:34:54
2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-heap.cc Tue Aug 5 07:29:13
2014 UTC
@@ -40,25 +40,6 @@
using namespace v8::internal;
-// Go through all incremental marking steps in one swoop.
-static void SimulateIncrementalMarking() {
- MarkCompactCollector* collector =
CcTest::heap()->mark_compact_collector();
- IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (collector->sweeping_in_progress()) {
- collector->EnsureSweepingCompleted();
- }
- CHECK(marking->IsMarking() || marking->IsStopped());
- if (marking->IsStopped()) {
- marking->Start();
- }
- CHECK(marking->IsMarking());
- while (!marking->IsComplete()) {
- marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
- }
- CHECK(marking->IsComplete());
-}
-
-
static void CheckMap(Map* map, int type, int instance_size) {
CHECK(map->IsHeapObject());
#ifdef DEBUG
@@ -1223,7 +1204,7 @@
// Simulate several GCs that use incremental marking.
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
}
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
@@ -1237,7 +1218,7 @@
// Simulate several GCs that use incremental marking but make sure
// the loop breaks once the function is enqueued as a candidate.
for (int i = 0; i < kAgingThreshold; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
if (!function->next_function_link()->IsUndefined()) break;
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
}
@@ -1313,7 +1294,7 @@
// Simulate incremental marking so that the functions are enqueued as
// code flushing candidates. Then kill one of the functions. Finally
// perform a scavenge while incremental marking is still running.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
*function2.location() = NULL;
CcTest::heap()->CollectGarbage(NEW_SPACE, "test scavenge while marking");
@@ -1367,7 +1348,7 @@
// Simulate incremental marking so that the function is enqueued as
// code flushing candidate.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Enable the debugger and add a breakpoint while incremental marking
// is running so that incremental marking aborts and code flushing is
@@ -2758,7 +2739,7 @@
CompileRun("%DebugPrint(root);");
CHECK_EQ(transitions_count, transitions_before);
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
// Count number of live transitions after marking. Note that one
transition
@@ -2923,7 +2904,7 @@
"root.foo = 0;"
"root = new Object;");
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
// Compile a StoreIC that performs the prepared map transition. This
// will restart incremental marking and should make sure the root is
@@ -2964,7 +2945,7 @@
"root.foo = 0;"
"root = new Object;");
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
// Compile an optimized LStoreNamedField that performs the prepared
// map transition. This will restart incremental marking and should
@@ -3167,7 +3148,7 @@
}
}
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(expected_length, feedback_vector->length());
@@ -3210,7 +3191,7 @@
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
CHECK(ic_before->ic_state() == MONOMORPHIC);
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3244,7 +3225,7 @@
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3285,7 +3266,7 @@
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
@@ -3446,7 +3427,7 @@
// Simulate incremental marking so that the functions are enqueued as
// code flushing candidates. Then optimize one function. Finally
// finish the GC to complete code flushing.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
CompileRun("%OptimizeFunctionOnNextCall(g); g(3);");
heap->CollectAllGarbage(Heap::kNoGCFlags);
@@ -3493,7 +3474,7 @@
// Simulate incremental marking so that unoptimized code is flushed
// even though it still is cached in the optimized code map.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
heap->CollectAllGarbage(Heap::kNoGCFlags);
// Make a new closure that will get code installed from the code map.
@@ -3561,7 +3542,7 @@
}
// Simulate incremental marking and collect code flushing candidates.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
CHECK(shared1->code()->gc_metadata() != NULL);
// Optimize function and make sure the unoptimized code is replaced.
@@ -3707,7 +3688,7 @@
// Simulate incremental marking so that unoptimized function is enqueued
as a
// candidate for code flushing. The shared function info however will
not be
// explicitly enqueued.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Now optimize the function so that it is taken off the candidate list.
{
@@ -3764,7 +3745,7 @@
// Simulate incremental marking so that unoptimized function is enqueued
as a
// candidate for code flushing. The shared function info however will
not be
// explicitly enqueued.
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
// Now enable the debugger which in turn will disable code flushing.
CHECK(isolate->debug()->Load());
@@ -4012,7 +3993,7 @@
if (!isolate->use_crankshaft()) return;
HandleScope outer_scope(heap->isolate());
for (int i = 0; i < 3; i++) {
- SimulateIncrementalMarking();
+ SimulateIncrementalMarking(heap);
{
LocalContext context;
HandleScope scope(heap->isolate());
=======================================
--- /branches/bleeding_edge/test/cctest/test-weakmaps.cc Mon Aug 4
11:34:54 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-weakmaps.cc Tue Aug 5
07:29:13 2014 UTC
@@ -255,3 +255,20 @@
heap->CollectAllGarbage(Heap::kNoGCFlags);
heap->CollectAllGarbage(Heap::kNoGCFlags);
}
+
+
+TEST(Regress399527) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ {
+ HandleScope scope(isolate);
+ AllocateJSWeakMap(isolate);
+ SimulateIncrementalMarking(heap);
+ }
+ // The weak map is marked black here but leaving the handle scope will
make
+ // the object unreachable. Aborting incremental marking will clear all
the
+ // marking bits which makes the weak map garbage.
+ heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.