Reviewers: Erik Corry,

Description:
Make incremental marking clear type feedback cells.

This extends the existing clearing of type feedback cells during GC to
incremental marking in order to prevent cross-context retention that
would last until the next non-incremental GC.

[email protected]
TEST=cctest/test-heap/IncrementalMarkingClearsTypeFeedbackCells


Please review this at https://chromiumcodereview.appspot.com/10823082/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/incremental-marking.cc
  M src/mark-compact.cc
  M src/objects-visiting-inl.h
  M src/objects-visiting.h
  M test/cctest/test-heap.cc


Index: src/incremental-marking.cc
diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc
index ebbee25ac02d749551ea1c1de200db32987bd276..e3040eea6b712cda81a26f60b3a12ca4a47dd048 100644
--- a/src/incremental-marking.cc
+++ b/src/incremental-marking.cc
@@ -196,12 +196,6 @@ class IncrementalMarkingMarkingVisitor
     MarkObject(heap, target);
   }

-  static void VisitCode(Map* map, HeapObject* object) {
-    Heap* heap = map->GetHeap();
-    Code* code = reinterpret_cast<Code*>(object);
-    code->CodeIterateBody<IncrementalMarkingMarkingVisitor>(heap);
-  }
-
   static void VisitJSWeakMap(Map* map, HeapObject* object) {
     Heap* heap = map->GetHeap();
     VisitPointers(heap,
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index ccaaab8257b6971cf6029d9c086e21a109a52d4a..0ba8a24913e90ab9d1189f6532a6e6e563c455a6 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1153,15 +1153,6 @@ class MarkCompactMarkingVisitor
     return true;
   }

-  static void VisitCode(Map* map, HeapObject* object) {
-    Heap* heap = map->GetHeap();
-    Code* code = reinterpret_cast<Code*>(object);
-    if (FLAG_cleanup_code_caches_at_gc) {
-      code->ClearTypeFeedbackCells(heap);
-    }
-    code->CodeIterateBody<MarkCompactMarkingVisitor>(heap);
-  }
-
   static void VisitJSWeakMap(Map* map, HeapObject* object) {
MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
     JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object);
Index: src/objects-visiting-inl.h
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h
index 30a7ad460b01222931a8a0defe744bf96958a31c..80662cc745e1c3715cc3bb53ecb4e66d1d578ce2 100644
--- a/src/objects-visiting-inl.h
+++ b/src/objects-visiting-inl.h
@@ -216,6 +216,18 @@ void StaticMarkingVisitor<StaticVisitor>::VisitGlobalContext(


 template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitCode(
+    Map* map, HeapObject* object) {
+  Heap* heap = map->GetHeap();
+  Code* code = Code::cast(object);
+  if (FLAG_cleanup_code_caches_at_gc) {
+    code->ClearTypeFeedbackCells(heap);
+  }
+  code->CodeIterateBody<StaticVisitor>(heap);
+}
+
+
+template<typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
     Map* map, HeapObject* object) {
   int last_property_offset =
Index: src/objects-visiting.h
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index 7415101743f81dcd6b5da41aac727e25fa8a7741..fa81978f731b0637cd01edd4b138c8fa208be216 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -396,6 +396,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
   static inline void VisitGlobalContext(Map* map, HeapObject* object);

  protected:
+  static inline void VisitCode(Map* map, HeapObject* object);
   static inline void VisitJSRegExp(Map* map, HeapObject* object);

   class DataObjectVisitor {
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 22a382078675bca973eba71f84209696d1f75753..ccc73f7aae2adf778139065b889a6759c1ba29e2 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1985,3 +1985,55 @@ TEST(PrintSharedFunctionInfo) {
   g->shared()->PrintLn();
 }
 #endif  // OBJECT_PRINT
+
+
+TEST(IncrementalMarkingClearsTypeFeedbackCells) {
+  if (i::FLAG_always_opt) return;
+  InitializeVM();
+  v8::HandleScope scope;
+  v8::Local<v8::Value> fun1, fun2;
+
+  {
+    LocalContext env;
+    CompileRun("function fun() {};");
+    fun1 = env->Global()->Get(v8_str("fun"));
+  }
+
+  {
+    LocalContext env;
+    CompileRun("function fun() {};");
+    fun2 = env->Global()->Get(v8_str("fun"));
+  }
+
+  // Prepare function f that contains type feedback for closures
+  // originating from two different global contexts.
+  v8::Context::GetCurrent()->Global()->Set(v8_str("fun1"), fun1);
+  v8::Context::GetCurrent()->Global()->Set(v8_str("fun2"), fun2);
+  CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
+  Handle<JSFunction> f =
+      v8::Utils::OpenHandle(
+          *v8::Handle<v8::Function>::Cast(
+              v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+  Handle<TypeFeedbackCells> cells(TypeFeedbackInfo::cast(
+      f->shared()->code()->type_feedback_info())->type_feedback_cells());
+
+  CHECK_EQ(2, cells->CellCount());
+  CHECK(cells->Cell(0)->value()->IsJSFunction());
+  CHECK(cells->Cell(1)->value()->IsJSFunction());
+
+  // Go through all incremental marking steps in one swoop.
+  IncrementalMarking* marking = HEAP->incremental_marking();
+  CHECK(marking->IsStopped());
+  marking->Start();
+  CHECK(marking->IsMarking());
+  while (!marking->IsComplete()) {
+    marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+  }
+  CHECK(marking->IsComplete());
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK(marking->IsStopped());
+
+  CHECK_EQ(2, cells->CellCount());
+  CHECK(cells->Cell(0)->value()->IsTheHole());
+  CHECK(cells->Cell(1)->value()->IsTheHole());
+}


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to