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