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.

Reply via email to