Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index 16e51468cb81390bcb1aeb8b5c89064e392e2fc2..3b0415f2f7a58f6c12008e60eb8b36493f415a9b 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -2310,88 +2310,92 @@ void MarkCompactCollector::ClearNonLiveTransitions() { |
map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); |
} |
- // Clear dead prototype transitions. |
- int number_of_transitions = map->NumberOfProtoTransitions(); |
- FixedArray* prototype_transitions = map->prototype_transitions(); |
- |
- int new_number_of_transitions = 0; |
- const int header = Map::kProtoTransitionHeaderSize; |
- const int proto_offset = |
- header + Map::kProtoTransitionPrototypeOffset; |
- const int map_offset = header + Map::kProtoTransitionMapOffset; |
- const int step = Map::kProtoTransitionElementsPerEntry; |
- for (int i = 0; i < number_of_transitions; i++) { |
- Object* prototype = prototype_transitions->get(proto_offset + i * step); |
- Object* cached_map = prototype_transitions->get(map_offset + i * step); |
- if (IsMarked(prototype) && IsMarked(cached_map)) { |
- int proto_index = proto_offset + new_number_of_transitions * step; |
- int map_index = map_offset + new_number_of_transitions * step; |
- if (new_number_of_transitions != i) { |
- prototype_transitions->set_unchecked( |
- heap_, |
- proto_index, |
- prototype, |
- UPDATE_WRITE_BARRIER); |
- prototype_transitions->set_unchecked( |
- heap_, |
- map_index, |
- cached_map, |
- SKIP_WRITE_BARRIER); |
- } |
- Object** slot = |
- HeapObject::RawField(prototype_transitions, |
- FixedArray::OffsetOfElementAt(proto_index)); |
- RecordSlot(slot, slot, prototype); |
- new_number_of_transitions++; |
+ ClearNonLivePrototypeTransitions(map); |
+ ClearNonLiveMapTransitions(map, map_mark); |
+ } |
+} |
+ |
+ |
+void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { |
+ int number_of_transitions = map->NumberOfProtoTransitions(); |
+ FixedArray* prototype_transitions = map->prototype_transitions(); |
+ |
+ int new_number_of_transitions = 0; |
+ const int header = Map::kProtoTransitionHeaderSize; |
+ const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; |
+ const int map_offset = header + Map::kProtoTransitionMapOffset; |
+ const int step = Map::kProtoTransitionElementsPerEntry; |
+ for (int i = 0; i < number_of_transitions; i++) { |
+ Object* prototype = prototype_transitions->get(proto_offset + i * step); |
+ Object* cached_map = prototype_transitions->get(map_offset + i * step); |
+ if (IsMarked(prototype) && IsMarked(cached_map)) { |
+ int proto_index = proto_offset + new_number_of_transitions * step; |
+ int map_index = map_offset + new_number_of_transitions * step; |
+ if (new_number_of_transitions != i) { |
+ prototype_transitions->set_unchecked( |
+ heap_, |
+ proto_index, |
+ prototype, |
+ UPDATE_WRITE_BARRIER); |
+ prototype_transitions->set_unchecked( |
+ heap_, |
+ map_index, |
+ cached_map, |
+ SKIP_WRITE_BARRIER); |
} |
+ Object** slot = |
+ HeapObject::RawField(prototype_transitions, |
+ FixedArray::OffsetOfElementAt(proto_index)); |
+ RecordSlot(slot, slot, prototype); |
+ new_number_of_transitions++; |
} |
+ } |
- if (new_number_of_transitions != number_of_transitions) { |
- map->SetNumberOfProtoTransitions(new_number_of_transitions); |
- } |
+ if (new_number_of_transitions != number_of_transitions) { |
+ map->SetNumberOfProtoTransitions(new_number_of_transitions); |
+ } |
- // Fill slots that became free with undefined value. |
- for (int i = new_number_of_transitions * step; |
- i < number_of_transitions * step; |
- i++) { |
- prototype_transitions->set_undefined(heap_, header + i); |
- } |
+ // Fill slots that became free with undefined value. |
+ for (int i = new_number_of_transitions * step; |
+ i < number_of_transitions * step; |
+ i++) { |
+ prototype_transitions->set_undefined(heap_, header + i); |
+ } |
+} |
- // Follow the chain of back pointers to find the prototype. |
- Map* current = map; |
- while (current->IsMap()) { |
- current = reinterpret_cast<Map*>(current->prototype()); |
- ASSERT(current->IsHeapObject()); |
- } |
- Object* real_prototype = current; |
- // Follow back pointers, setting them to prototype, |
- // clearing map transitions when necessary. |
- current = map; |
- bool on_dead_path = !map_mark.Get(); |
- Object* next; |
- while (current->IsMap()) { |
- next = current->prototype(); |
- // There should never be a dead map above a live map. |
- MarkBit current_mark = Marking::MarkBitFrom(current); |
- bool is_alive = current_mark.Get(); |
- ASSERT(on_dead_path || is_alive); |
+void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map, |
+ MarkBit map_mark) { |
+ // Follow the chain of back pointers to find the prototype. |
+ Map* real_prototype = map; |
+ while (real_prototype->IsMap()) { |
+ real_prototype = reinterpret_cast<Map*>(real_prototype->prototype()); |
+ ASSERT(real_prototype->IsHeapObject()); |
+ } |
- // A live map above a dead map indicates a dead transition. |
- // This test will always be false on the first iteration. |
- if (on_dead_path && is_alive) { |
- on_dead_path = false; |
- current->ClearNonLiveTransitions(heap(), real_prototype); |
- } |
- *HeapObject::RawField(current, Map::kPrototypeOffset) = |
- real_prototype; |
+ // Follow back pointers, setting them to prototype, clearing map transitions |
+ // when necessary. |
+ Map* current = map; |
+ bool current_is_alive = map_mark.Get(); |
+ bool on_dead_path = !current_is_alive; |
+ while (current->IsMap()) { |
+ Object* next = current->prototype(); |
+ // There should never be a dead map above a live map. |
+ ASSERT(on_dead_path || current_is_alive); |
- if (is_alive) { |
- Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset); |
- RecordSlot(slot, slot, real_prototype); |
- } |
- current = reinterpret_cast<Map*>(next); |
+ // A live map above a dead map indicates a dead transition. This test will |
+ // always be false on the first iteration. |
+ if (on_dead_path && current_is_alive) { |
+ on_dead_path = false; |
+ current->ClearNonLiveTransitions(heap(), real_prototype); |
} |
+ |
+ Object** slot = HeapObject::RawField(current, Map::kPrototypeOffset); |
+ *slot = real_prototype; |
+ if (current_is_alive) RecordSlot(slot, slot, real_prototype); |
+ |
+ current = reinterpret_cast<Map*>(next); |
+ current_is_alive = Marking::MarkBitFrom(current).Get(); |
} |
} |