Index: src/objects-visiting-inl.h |
diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h |
index 925b2562f292558687716cc6be8c0b618d1f7f04..c6299b57b3f53c0785bac0b3d6ca36162b454ed4 100644 |
--- a/src/objects-visiting-inl.h |
+++ b/src/objects-visiting-inl.h |
@@ -261,12 +261,9 @@ void StaticMarkingVisitor<StaticVisitor>::VisitMap( |
map_object->ClearCodeCache(heap); |
} |
- // When map collection is enabled we have to mark through map's |
- // transitions and back pointers in a special way to make these links |
- // weak. Only maps for subclasses of JSReceiver can have transitions. |
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
- if (FLAG_collect_maps && |
- map_object->instance_type() >= FIRST_JS_RECEIVER_TYPE) { |
+ // When map collection is enabled we have to mark through map's transitions |
+ // and back pointers in a special way to make these links weak. |
+ if (FLAG_collect_maps && map_object->CanTransition()) { |
MarkMapContents(heap, map_object); |
} else { |
StaticVisitor::VisitPointers(heap, |
@@ -394,6 +391,15 @@ void StaticMarkingVisitor<StaticVisitor>::MarkMapContents( |
ASSERT(transitions->IsMap() || transitions->IsUndefined()); |
} |
+ // Mark prototype dependent codes array but do not push it onto marking |
+ // stack, this will make references from it weak. We will clean dead |
+ // dead codes when we iterate over maps in ClearNonLiveTransitions. |
+ Object** slot = HeapObject::RawField(reinterpret_cast<HeapObject*>(map), |
+ Map::kDependentCodesOffset); |
+ HeapObject* obj = HeapObject::cast(*slot); |
+ heap->mark_compact_collector()->RecordSlot(slot, slot, obj); |
+ StaticVisitor::MarkObjectWithoutPush(heap, obj); |
+ |
// Mark the pointer fields of the Map. Since the transitions array has |
// been marked already, it is fine that one of these fields contains a |
// pointer to it. |
@@ -645,8 +651,20 @@ void Code::CodeIterateBody(ObjectVisitor* v) { |
IteratePointer(v, kTypeFeedbackInfoOffset); |
RelocIterator it(this, mode_mask); |
- for (; !it.done(); it.next()) { |
- it.rinfo()->Visit(v); |
+ if (kind() == OPTIMIZED_FUNCTION) { |
+ // Treat embedded maps in optimized code as weak. |
Michael Starzinger
2012/12/14 14:15:26
I think this is the wrong place to skip embedded m
ulan
2013/01/17 09:35:10
Done.
|
+ for (; !it.done(); it.next()) { |
+ RelocInfo* info = it.rinfo(); |
+ if (!RelocInfo::IsEmbeddedObject(info->rmode()) || |
+ !info->target_object()->IsMap() || |
+ !Map::cast(info->target_object())->CanTransition()) { |
+ info->Visit(v); |
+ } |
+ } |
+ } else { |
+ for (; !it.done(); it.next()) { |
+ it.rinfo()->Visit(v); |
+ } |
} |
} |
@@ -677,8 +695,20 @@ void Code::CodeIterateBody(Heap* heap) { |
reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset)); |
RelocIterator it(this, mode_mask); |
- for (; !it.done(); it.next()) { |
- it.rinfo()->template Visit<StaticVisitor>(heap); |
+ if (kind() == OPTIMIZED_FUNCTION) { |
+ // Treat embedded maps in optimized code as weak. |
Michael Starzinger
2012/12/14 14:15:26
Likewise.
ulan
2013/01/17 09:35:10
Done.
|
+ for (; !it.done(); it.next()) { |
+ RelocInfo* info = it.rinfo(); |
+ if (!RelocInfo::IsEmbeddedObject(info->rmode()) || |
+ !info->target_object()->IsMap() || |
+ !Map::cast(info->target_object())->CanTransition()) { |
+ it.rinfo()->template Visit<StaticVisitor>(heap); |
+ } |
+ } |
+ } else { |
+ for (; !it.done(); it.next()) { |
+ it.rinfo()->template Visit<StaticVisitor>(heap); |
+ } |
} |
} |