Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index ce4d6ac655887e638848ca06229502e20e6f3deb..b857c793798a4f91a8f87ff9830acf465f9898a5 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -417,6 +417,8 @@ void MarkCompactCollector::CollectGarbage() { |
SweepSpaces(); |
+ if (!FLAG_collect_maps) ReattachInitialMaps(); |
+ |
#ifdef DEBUG |
if (FLAG_verify_native_context_separation) { |
VerifyNativeContextSeparation(heap_); |
@@ -2532,6 +2534,23 @@ void MarkCompactCollector::ProcessMapCaches() { |
} |
+void MarkCompactCollector::ReattachInitialMaps() { |
+ HeapObjectIterator map_iterator(heap()->map_space()); |
+ for (HeapObject* obj = map_iterator.Next(); |
+ obj != NULL; |
+ obj = map_iterator.Next()) { |
+ Map* map = Map::cast(obj); |
+ |
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
+ if (map->instance_type() < FIRST_JS_RECEIVER_TYPE) continue; |
+ |
+ if (map->attached_to_shared_function_info()) { |
+ JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); |
+ } |
+ } |
+} |
+ |
+ |
void MarkCompactCollector::ClearNonLiveReferences() { |
// Iterate over the map space, setting map transitions that go from |
// a marked map to an unmarked map to null transitions. This action |
@@ -2545,6 +2564,13 @@ void MarkCompactCollector::ClearNonLiveReferences() { |
if (!map->CanTransition()) continue; |
MarkBit map_mark = Marking::MarkBitFrom(map); |
+ if (map_mark.Get() && map->attached_to_shared_function_info()) { |
+ // This map is used for inobject slack tracking and has been detached |
+ // from SharedFunctionInfo during the mark phase. |
+ // Since it survived the GC, reattach it now. |
+ JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); |
+ } |
+ |
ClearNonLivePrototypeTransitions(map); |
ClearNonLiveMapTransitions(map, map_mark); |