Chromium Code Reviews| Index: src/objects-visiting-inl.h |
| diff --git a/src/objects-visiting-inl.h b/src/objects-visiting-inl.h |
| index 856ae06b7b133bb126371b40fbc42b9eed43b176..523a0983323e6fb2da5b9a571c8ae130345644be 100644 |
| --- a/src/objects-visiting-inl.h |
| +++ b/src/objects-visiting-inl.h |
| @@ -134,12 +134,9 @@ void StaticMarkingVisitor<StaticVisitor>::Initialize() { |
| Oddball::BodyDescriptor, |
| void>::Visit); |
| - table_.Register(kVisitMap, |
| - &FixedBodyVisitor<StaticVisitor, |
| - Map::BodyDescriptor, |
| - void>::Visit); |
| + table_.Register(kVisitMap, &VisitMap); |
| - table_.Register(kVisitCode, &StaticVisitor::VisitCode); |
| + table_.Register(kVisitCode, &VisitCode); |
| // Registration for kVisitSharedFunctionInfo is done by StaticVisitor. |
| @@ -247,6 +244,32 @@ void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext( |
| template<typename StaticVisitor> |
| +void StaticMarkingVisitor<StaticVisitor>::VisitMap( |
| + Map* map, HeapObject* object) { |
| + Heap* heap = map->GetHeap(); |
| + Map* map_object = Map::cast(object); |
| + |
| + // Clears the cache of ICs related to this map. |
| + if (FLAG_cleanup_code_caches_at_gc) { |
| + 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) { |
| + MarkMapContents(heap, map_object); |
| + } else { |
| + StaticVisitor::VisitPointers(heap, |
| + HeapObject::RawField(object, Map::kPointerFieldsBeginOffset), |
| + HeapObject::RawField(object, Map::kPointerFieldsEndOffset)); |
| + } |
| +} |
| + |
| + |
| +template<typename StaticVisitor> |
| void StaticMarkingVisitor<StaticVisitor>::VisitCode( |
| Map* map, HeapObject* object) { |
| Heap* heap = map->GetHeap(); |
| @@ -269,6 +292,60 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp( |
| } |
| +template<typename StaticVisitor> |
| +void StaticMarkingVisitor<StaticVisitor>::MarkMapContents( |
| + Heap* heap, Map* map) { |
| + // Make sure that the back pointer stored either in the map itself or |
| + // inside its transitions array is marked. Skip recording the back |
| + // pointer slot since map space is not compacted. |
| + StaticVisitor::MarkObject(heap, HeapObject::cast(map->GetBackPointer())); |
| + |
| + // Treat pointers in the transitions array as weak and also mark that |
| + // array to prevent visiting it later. Skip recording the transition |
| + // array slot, since it will be implicitly recorded when the pointer |
| + // fields of this map are visited. |
| + TransitionArray* transitions = map->unchecked_transition_array(); |
| + if (transitions->IsTransitionArray()) { |
| + MarkTransitionArray(heap, transitions); |
| + } else { |
| + // Already marked by marking map->GetBackPointer() above. |
| + ASSERT(transitions->IsMap() || transitions->IsUndefined()); |
| + } |
| + |
| + // 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. |
| + StaticVisitor::VisitPointers(heap, |
| + HeapObject::RawField(map, Map::kPointerFieldsBeginOffset), |
| + HeapObject::RawField(map, Map::kPointerFieldsEndOffset)); |
| +} |
| + |
| + |
| +template<typename StaticVisitor> |
| +void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray( |
| + Heap* heap, TransitionArray* transitions) { |
| + if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return; |
| + |
| + // Skip recording the descriptors_pointer slot since the cell space |
| + // is not compacted and descriptors are reference through a cell. |
|
Toon Verwaest
2012/09/17 09:06:36
*referenced
Michael Starzinger
2012/09/17 09:59:36
Done.
|
| + StaticVisitor::MarkObject(heap, transitions->descriptors_pointer()); |
| + |
| + if (transitions->HasPrototypeTransitions()) { |
| + // Mark prototype transitions array but do not push it onto marking |
| + // stack, this will make references from it weak. We will clean dead |
| + // prototype transitions in ClearNonLiveTransitions. |
| + Object** slot = transitions->GetPrototypeTransitionsSlot(); |
| + HeapObject* obj = HeapObject::cast(*slot); |
| + heap->mark_compact_collector()->RecordSlot(slot, slot, obj); |
| + StaticVisitor::MarkObjectWithoutPush(heap, obj); |
| + } |
| + |
| + for (int i = 0; i < transitions->number_of_transitions(); ++i) { |
| + StaticVisitor::VisitPointer(heap, transitions->GetKeySlot(i)); |
| + } |
| +} |
| + |
| + |
| void Code::CodeIterateBody(ObjectVisitor* v) { |
| int mode_mask = RelocInfo::kCodeTargetMask | |
| RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |