| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 black_allocation_(false), | 59 black_allocation_(false), |
| 60 have_code_to_deoptimize_(false), | 60 have_code_to_deoptimize_(false), |
| 61 marking_deque_(heap), | 61 marking_deque_(heap), |
| 62 code_flusher_(nullptr), | 62 code_flusher_(nullptr), |
| 63 sweeper_(heap) { | 63 sweeper_(heap) { |
| 64 } | 64 } |
| 65 | 65 |
| 66 #ifdef VERIFY_HEAP | 66 #ifdef VERIFY_HEAP |
| 67 class VerifyMarkingVisitor : public ObjectVisitor { | 67 class VerifyMarkingVisitor : public ObjectVisitor { |
| 68 public: | 68 public: |
| 69 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} | |
| 70 | |
| 71 void VisitPointers(Object** start, Object** end) override { | 69 void VisitPointers(Object** start, Object** end) override { |
| 72 for (Object** current = start; current < end; current++) { | 70 for (Object** current = start; current < end; current++) { |
| 73 if ((*current)->IsHeapObject()) { | 71 if ((*current)->IsHeapObject()) { |
| 74 HeapObject* object = HeapObject::cast(*current); | 72 HeapObject* object = HeapObject::cast(*current); |
| 75 CHECK(heap_->mark_compact_collector()->IsMarked(object)); | 73 CHECK(ObjectMarking::IsBlackOrGrey(object)); |
| 76 } | 74 } |
| 77 } | 75 } |
| 78 } | 76 } |
| 79 | 77 |
| 80 void VisitEmbeddedPointer(RelocInfo* rinfo) override { | 78 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
| 81 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 79 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
| 82 if (!rinfo->host()->IsWeakObject(rinfo->target_object())) { | 80 if (!rinfo->host()->IsWeakObject(rinfo->target_object())) { |
| 83 Object* p = rinfo->target_object(); | 81 Object* p = rinfo->target_object(); |
| 84 VisitPointer(&p); | 82 VisitPointer(&p); |
| 85 } | 83 } |
| 86 } | 84 } |
| 87 | 85 |
| 88 void VisitCell(RelocInfo* rinfo) override { | 86 void VisitCell(RelocInfo* rinfo) override { |
| 89 Code* code = rinfo->host(); | 87 Code* code = rinfo->host(); |
| 90 DCHECK(rinfo->rmode() == RelocInfo::CELL); | 88 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
| 91 if (!code->IsWeakObject(rinfo->target_cell())) { | 89 if (!code->IsWeakObject(rinfo->target_cell())) { |
| 92 ObjectVisitor::VisitCell(rinfo); | 90 ObjectVisitor::VisitCell(rinfo); |
| 93 } | 91 } |
| 94 } | 92 } |
| 95 | |
| 96 private: | |
| 97 Heap* heap_; | |
| 98 }; | 93 }; |
| 99 | 94 |
| 100 | 95 |
| 101 static void VerifyMarking(Heap* heap, Address bottom, Address top) { | 96 static void VerifyMarking(Heap* heap, Address bottom, Address top) { |
| 102 VerifyMarkingVisitor visitor(heap); | 97 VerifyMarkingVisitor visitor; |
| 103 HeapObject* object; | 98 HeapObject* object; |
| 104 Address next_object_must_be_here_or_later = bottom; | 99 Address next_object_must_be_here_or_later = bottom; |
| 105 for (Address current = bottom; current < top;) { | 100 for (Address current = bottom; current < top;) { |
| 106 object = HeapObject::FromAddress(current); | 101 object = HeapObject::FromAddress(current); |
| 107 // One word fillers at the end of a black area can be grey. | 102 // One word fillers at the end of a black area can be grey. |
| 108 if (MarkCompactCollector::IsMarked(object) && | 103 if (ObjectMarking::IsBlackOrGrey(object) && |
| 109 object->map() != heap->one_pointer_filler_map()) { | 104 object->map() != heap->one_pointer_filler_map()) { |
| 110 CHECK(ObjectMarking::IsBlack(object)); | 105 CHECK(ObjectMarking::IsBlack(object)); |
| 111 CHECK(current >= next_object_must_be_here_or_later); | 106 CHECK(current >= next_object_must_be_here_or_later); |
| 112 object->Iterate(&visitor); | 107 object->Iterate(&visitor); |
| 113 next_object_must_be_here_or_later = current + object->Size(); | 108 next_object_must_be_here_or_later = current + object->Size(); |
| 114 // The object is either part of a black area of black allocation or a | 109 // The object is either part of a black area of black allocation or a |
| 115 // regular black object | 110 // regular black object |
| 116 Page* page = Page::FromAddress(current); | 111 Page* page = Page::FromAddress(current); |
| 117 CHECK( | 112 CHECK( |
| 118 page->markbits()->AllBitsSetInRange( | 113 page->markbits()->AllBitsSetInRange( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 } | 145 } |
| 151 } | 146 } |
| 152 | 147 |
| 153 | 148 |
| 154 static void VerifyMarking(Heap* heap) { | 149 static void VerifyMarking(Heap* heap) { |
| 155 VerifyMarking(heap->old_space()); | 150 VerifyMarking(heap->old_space()); |
| 156 VerifyMarking(heap->code_space()); | 151 VerifyMarking(heap->code_space()); |
| 157 VerifyMarking(heap->map_space()); | 152 VerifyMarking(heap->map_space()); |
| 158 VerifyMarking(heap->new_space()); | 153 VerifyMarking(heap->new_space()); |
| 159 | 154 |
| 160 VerifyMarkingVisitor visitor(heap); | 155 VerifyMarkingVisitor visitor; |
| 161 | 156 |
| 162 LargeObjectIterator it(heap->lo_space()); | 157 LargeObjectIterator it(heap->lo_space()); |
| 163 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { | 158 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { |
| 164 if (MarkCompactCollector::IsMarked(obj)) { | 159 if (ObjectMarking::IsBlackOrGrey(obj)) { |
| 165 obj->Iterate(&visitor); | 160 obj->Iterate(&visitor); |
| 166 } | 161 } |
| 167 } | 162 } |
| 168 | 163 |
| 169 heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 164 heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
| 170 } | 165 } |
| 171 | 166 |
| 172 | 167 |
| 173 class VerifyEvacuationVisitor : public ObjectVisitor { | 168 class VerifyEvacuationVisitor : public ObjectVisitor { |
| 174 public: | 169 public: |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 HeapObject* object = HeapObject::cast(obj); | 1089 HeapObject* object = HeapObject::cast(obj); |
| 1095 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); | 1090 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); |
| 1096 heap->mark_compact_collector()->MarkObject(object, mark_bit); | 1091 heap->mark_compact_collector()->MarkObject(object, mark_bit); |
| 1097 } | 1092 } |
| 1098 | 1093 |
| 1099 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { | 1094 inline static bool MarkRecursively(Heap* heap, HeapObject* object) { |
| 1100 StackLimitCheck check(heap->isolate()); | 1095 StackLimitCheck check(heap->isolate()); |
| 1101 if (check.HasOverflowed()) return false; | 1096 if (check.HasOverflowed()) return false; |
| 1102 | 1097 |
| 1103 if (ObjectMarking::IsBlackOrGrey(object)) return true; | 1098 if (ObjectMarking::IsBlackOrGrey(object)) return true; |
| 1104 heap->mark_compact_collector()->SetMark(object); | 1099 ObjectMarking::WhiteToBlack(object); |
| 1105 IterateBody(object->map(), object); | 1100 IterateBody(object->map(), object); |
| 1106 return true; | 1101 return true; |
| 1107 } | 1102 } |
| 1108 }; | 1103 }; |
| 1109 | 1104 |
| 1110 class MarkCompactMarkingVisitor | 1105 class MarkCompactMarkingVisitor |
| 1111 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { | 1106 : public StaticMarkingVisitor<MarkCompactMarkingVisitor> { |
| 1112 public: | 1107 public: |
| 1113 static void Initialize(); | 1108 static void Initialize(); |
| 1114 | 1109 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1133 // Marks the object black and pushes it on the marking stack. | 1128 // Marks the object black and pushes it on the marking stack. |
| 1134 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { | 1129 INLINE(static void MarkObject(Heap* heap, HeapObject* object)) { |
| 1135 MarkBit mark = ObjectMarking::MarkBitFrom(object); | 1130 MarkBit mark = ObjectMarking::MarkBitFrom(object); |
| 1136 heap->mark_compact_collector()->MarkObject(object, mark); | 1131 heap->mark_compact_collector()->MarkObject(object, mark); |
| 1137 } | 1132 } |
| 1138 | 1133 |
| 1139 // Marks the object black without pushing it on the marking stack. | 1134 // Marks the object black without pushing it on the marking stack. |
| 1140 // Returns true if object needed marking and false otherwise. | 1135 // Returns true if object needed marking and false otherwise. |
| 1141 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { | 1136 INLINE(static bool MarkObjectWithoutPush(Heap* heap, HeapObject* object)) { |
| 1142 if (ObjectMarking::IsWhite(object)) { | 1137 if (ObjectMarking::IsWhite(object)) { |
| 1143 heap->mark_compact_collector()->SetMark(object); | 1138 ObjectMarking::WhiteToBlack(object); |
| 1144 return true; | 1139 return true; |
| 1145 } | 1140 } |
| 1146 return false; | 1141 return false; |
| 1147 } | 1142 } |
| 1148 | 1143 |
| 1149 // Mark object pointed to by p. | 1144 // Mark object pointed to by p. |
| 1150 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, | 1145 INLINE(static void MarkObjectByPointer(MarkCompactCollector* collector, |
| 1151 HeapObject* object, Object** p)) { | 1146 HeapObject* object, Object** p)) { |
| 1152 if (!(*p)->IsHeapObject()) return; | 1147 if (!(*p)->IsHeapObject()) return; |
| 1153 HeapObject* target_object = HeapObject::cast(*p); | 1148 HeapObject* target_object = HeapObject::cast(*p); |
| 1154 collector->RecordSlot(object, p, target_object); | 1149 collector->RecordSlot(object, p, target_object); |
| 1155 MarkBit mark = ObjectMarking::MarkBitFrom(target_object); | 1150 MarkBit mark = ObjectMarking::MarkBitFrom(target_object); |
| 1156 collector->MarkObject(target_object, mark); | 1151 collector->MarkObject(target_object, mark); |
| 1157 } | 1152 } |
| 1158 | 1153 |
| 1159 | 1154 |
| 1160 // Visit an unmarked object. | 1155 // Visit an unmarked object. |
| 1161 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, | 1156 INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, |
| 1162 HeapObject* obj)) { | 1157 HeapObject* obj)) { |
| 1163 #ifdef DEBUG | 1158 #ifdef DEBUG |
| 1164 DCHECK(collector->heap()->Contains(obj)); | 1159 DCHECK(collector->heap()->Contains(obj)); |
| 1165 DCHECK(!collector->heap()->mark_compact_collector()->IsMarked(obj)); | 1160 DCHECK(ObjectMarking::IsWhite(obj)); |
| 1166 #endif | 1161 #endif |
| 1167 Map* map = obj->map(); | 1162 Map* map = obj->map(); |
| 1168 Heap* heap = obj->GetHeap(); | 1163 Heap* heap = obj->GetHeap(); |
| 1169 heap->mark_compact_collector()->SetMark(obj); | 1164 ObjectMarking::WhiteToBlack(obj); |
| 1170 // Mark the map pointer and the body. | 1165 // Mark the map pointer and the body. |
| 1171 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); | 1166 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); |
| 1172 heap->mark_compact_collector()->MarkObject(map, map_mark); | 1167 heap->mark_compact_collector()->MarkObject(map, map_mark); |
| 1173 IterateBody(map, obj); | 1168 IterateBody(map, obj); |
| 1174 } | 1169 } |
| 1175 | 1170 |
| 1176 // Visit all unmarked objects pointed to by [start, end). | 1171 // Visit all unmarked objects pointed to by [start, end). |
| 1177 // Returns false if the operation fails (lack of stack space). | 1172 // Returns false if the operation fails (lack of stack space). |
| 1178 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object, | 1173 INLINE(static bool VisitUnmarkedObjects(Heap* heap, HeapObject* object, |
| 1179 Object** start, Object** end)) { | 1174 Object** start, Object** end)) { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1384 HeapObject* object = HeapObject::cast(*p); | 1379 HeapObject* object = HeapObject::cast(*p); |
| 1385 | 1380 |
| 1386 if (mode == MarkCompactMode::YOUNG_GENERATION && | 1381 if (mode == MarkCompactMode::YOUNG_GENERATION && |
| 1387 !collector_->heap()->InNewSpace(object)) | 1382 !collector_->heap()->InNewSpace(object)) |
| 1388 return; | 1383 return; |
| 1389 | 1384 |
| 1390 if (ObjectMarking::IsBlackOrGrey(object)) return; | 1385 if (ObjectMarking::IsBlackOrGrey(object)) return; |
| 1391 | 1386 |
| 1392 Map* map = object->map(); | 1387 Map* map = object->map(); |
| 1393 // Mark the object. | 1388 // Mark the object. |
| 1394 collector_->SetMark(object); | 1389 ObjectMarking::WhiteToBlack(object); |
| 1395 | 1390 |
| 1396 switch (mode) { | 1391 switch (mode) { |
| 1397 case MarkCompactMode::FULL: { | 1392 case MarkCompactMode::FULL: { |
| 1398 // Mark the map pointer and body, and push them on the marking stack. | 1393 // Mark the map pointer and body, and push them on the marking stack. |
| 1399 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); | 1394 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); |
| 1400 collector_->MarkObject(map, map_mark); | 1395 collector_->MarkObject(map, map_mark); |
| 1401 MarkCompactMarkingVisitor::IterateBody(map, object); | 1396 MarkCompactMarkingVisitor::IterateBody(map, object); |
| 1402 } break; | 1397 } break; |
| 1403 case MarkCompactMode::YOUNG_GENERATION: | 1398 case MarkCompactMode::YOUNG_GENERATION: |
| 1404 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); | 1399 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 virtual Object* RetainAs(Object* object) { | 1467 virtual Object* RetainAs(Object* object) { |
| 1473 DCHECK(!ObjectMarking::IsGrey(HeapObject::cast(object))); | 1468 DCHECK(!ObjectMarking::IsGrey(HeapObject::cast(object))); |
| 1474 if (ObjectMarking::IsBlack(HeapObject::cast(object))) { | 1469 if (ObjectMarking::IsBlack(HeapObject::cast(object))) { |
| 1475 return object; | 1470 return object; |
| 1476 } else if (object->IsAllocationSite() && | 1471 } else if (object->IsAllocationSite() && |
| 1477 !(AllocationSite::cast(object)->IsZombie())) { | 1472 !(AllocationSite::cast(object)->IsZombie())) { |
| 1478 // "dead" AllocationSites need to live long enough for a traversal of new | 1473 // "dead" AllocationSites need to live long enough for a traversal of new |
| 1479 // space. These sites get a one-time reprieve. | 1474 // space. These sites get a one-time reprieve. |
| 1480 AllocationSite* site = AllocationSite::cast(object); | 1475 AllocationSite* site = AllocationSite::cast(object); |
| 1481 site->MarkZombie(); | 1476 site->MarkZombie(); |
| 1482 site->GetHeap()->mark_compact_collector()->MarkAllocationSite(site); | 1477 ObjectMarking::WhiteToBlack(site); |
| 1483 return object; | 1478 return object; |
| 1484 } else { | 1479 } else { |
| 1485 return NULL; | 1480 return NULL; |
| 1486 } | 1481 } |
| 1487 } | 1482 } |
| 1488 }; | 1483 }; |
| 1489 | 1484 |
| 1490 | 1485 |
| 1491 // Fill the marking stack with overflowed objects returned by the given | 1486 // Fill the marking stack with overflowed objects returned by the given |
| 1492 // iterator. Stop when the marking stack is filled or the end of the space | 1487 // iterator. Stop when the marking stack is filled or the end of the space |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1973 DCHECK(o->IsHeapObject()); | 1968 DCHECK(o->IsHeapObject()); |
| 1974 return ObjectMarking::IsWhite(HeapObject::cast(o)); | 1969 return ObjectMarking::IsWhite(HeapObject::cast(o)); |
| 1975 } | 1970 } |
| 1976 | 1971 |
| 1977 void MarkCompactCollector::MarkStringTable( | 1972 void MarkCompactCollector::MarkStringTable( |
| 1978 RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { | 1973 RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { |
| 1979 StringTable* string_table = heap()->string_table(); | 1974 StringTable* string_table = heap()->string_table(); |
| 1980 // Mark the string table itself. | 1975 // Mark the string table itself. |
| 1981 if (ObjectMarking::IsWhite(string_table)) { | 1976 if (ObjectMarking::IsWhite(string_table)) { |
| 1982 // String table could have already been marked by visiting the handles list. | 1977 // String table could have already been marked by visiting the handles list. |
| 1983 SetMark(string_table); | 1978 ObjectMarking::WhiteToBlack(string_table); |
| 1984 } | 1979 } |
| 1985 // Explicitly mark the prefix. | 1980 // Explicitly mark the prefix. |
| 1986 string_table->IteratePrefix(visitor); | 1981 string_table->IteratePrefix(visitor); |
| 1987 ProcessMarkingDeque<MarkCompactMode::FULL>(); | 1982 ProcessMarkingDeque<MarkCompactMode::FULL>(); |
| 1988 } | 1983 } |
| 1989 | 1984 |
| 1990 | |
| 1991 void MarkCompactCollector::MarkAllocationSite(AllocationSite* site) { | |
| 1992 SetMark(site); | |
| 1993 } | |
| 1994 | |
| 1995 void MarkCompactCollector::MarkRoots( | 1985 void MarkCompactCollector::MarkRoots( |
| 1996 RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { | 1986 RootMarkingVisitor<MarkCompactMode::FULL>* visitor) { |
| 1997 // Mark the heap roots including global variables, stack variables, | 1987 // Mark the heap roots including global variables, stack variables, |
| 1998 // etc., and all objects reachable from them. | 1988 // etc., and all objects reachable from them. |
| 1999 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); | 1989 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); |
| 2000 | 1990 |
| 2001 // Handle the string table specially. | 1991 // Handle the string table specially. |
| 2002 MarkStringTable(visitor); | 1992 MarkStringTable(visitor); |
| 2003 | 1993 |
| 2004 // There may be overflowed objects in the heap. Visit them now. | 1994 // There may be overflowed objects in the heap. Visit them now. |
| 2005 while (marking_deque()->overflowed()) { | 1995 while (marking_deque()->overflowed()) { |
| 2006 RefillMarkingDeque<MarkCompactMode::FULL>(); | 1996 RefillMarkingDeque<MarkCompactMode::FULL>(); |
| 2007 EmptyMarkingDeque<MarkCompactMode::FULL>(); | 1997 EmptyMarkingDeque<MarkCompactMode::FULL>(); |
| 2008 } | 1998 } |
| 2009 } | 1999 } |
| 2010 | 2000 |
| 2011 | 2001 |
| 2012 void MarkCompactCollector::MarkImplicitRefGroups( | 2002 void MarkCompactCollector::MarkImplicitRefGroups( |
| 2013 MarkObjectFunction mark_object) { | 2003 MarkObjectFunction mark_object) { |
| 2014 List<ImplicitRefGroup*>* ref_groups = | 2004 List<ImplicitRefGroup*>* ref_groups = |
| 2015 isolate()->global_handles()->implicit_ref_groups(); | 2005 isolate()->global_handles()->implicit_ref_groups(); |
| 2016 | 2006 |
| 2017 int last = 0; | 2007 int last = 0; |
| 2018 for (int i = 0; i < ref_groups->length(); i++) { | 2008 for (int i = 0; i < ref_groups->length(); i++) { |
| 2019 ImplicitRefGroup* entry = ref_groups->at(i); | 2009 ImplicitRefGroup* entry = ref_groups->at(i); |
| 2020 DCHECK(entry != NULL); | 2010 DCHECK(entry != NULL); |
| 2021 | 2011 |
| 2022 if (!IsMarked(*entry->parent)) { | 2012 if (ObjectMarking::IsWhite(*entry->parent)) { |
| 2023 (*ref_groups)[last++] = entry; | 2013 (*ref_groups)[last++] = entry; |
| 2024 continue; | 2014 continue; |
| 2025 } | 2015 } |
| 2026 | 2016 |
| 2027 Object*** children = entry->children; | 2017 Object*** children = entry->children; |
| 2028 // A parent object is marked, so mark all child heap objects. | 2018 // A parent object is marked, so mark all child heap objects. |
| 2029 for (size_t j = 0; j < entry->length; ++j) { | 2019 for (size_t j = 0; j < entry->length; ++j) { |
| 2030 if ((*children[j])->IsHeapObject()) { | 2020 if ((*children[j])->IsHeapObject()) { |
| 2031 mark_object(heap(), HeapObject::cast(*children[j])); | 2021 mark_object(heap(), HeapObject::cast(*children[j])); |
| 2032 } | 2022 } |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 Heap* heap, Address slot_address) { | 2308 Heap* heap, Address slot_address) { |
| 2319 Object* object = *reinterpret_cast<Object**>(slot_address); | 2309 Object* object = *reinterpret_cast<Object**>(slot_address); |
| 2320 if (heap->InNewSpace(object)) { | 2310 if (heap->InNewSpace(object)) { |
| 2321 // Marking happens before flipping the young generation, so the object | 2311 // Marking happens before flipping the young generation, so the object |
| 2322 // has to be in ToSpace. | 2312 // has to be in ToSpace. |
| 2323 DCHECK(heap->InToSpace(object)); | 2313 DCHECK(heap->InToSpace(object)); |
| 2324 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); | 2314 HeapObject* heap_object = reinterpret_cast<HeapObject*>(object); |
| 2325 if (ObjectMarking::IsBlackOrGrey(heap_object)) { | 2315 if (ObjectMarking::IsBlackOrGrey(heap_object)) { |
| 2326 return KEEP_SLOT; | 2316 return KEEP_SLOT; |
| 2327 } | 2317 } |
| 2328 heap->mark_compact_collector()->SetMark(heap_object); | 2318 ObjectMarking::WhiteToBlack(heap_object); |
| 2329 StaticYoungGenerationMarkingVisitor::IterateBody(heap_object->map(), | 2319 StaticYoungGenerationMarkingVisitor::IterateBody(heap_object->map(), |
| 2330 heap_object); | 2320 heap_object); |
| 2331 return KEEP_SLOT; | 2321 return KEEP_SLOT; |
| 2332 } | 2322 } |
| 2333 return REMOVE_SLOT; | 2323 return REMOVE_SLOT; |
| 2334 } | 2324 } |
| 2335 | 2325 |
| 2336 static bool IsUnmarkedObject(Heap* heap, Object** p) { | 2326 static bool IsUnmarkedObject(Heap* heap, Object** p) { |
| 2337 DCHECK_IMPLIES(heap->InNewSpace(*p), heap->InToSpace(*p)); | 2327 DCHECK_IMPLIES(heap->InNewSpace(*p), heap->InToSpace(*p)); |
| 2338 return heap->InNewSpace(*p) && !ObjectMarking::IsBlack(HeapObject::cast(*p)); | 2328 return heap->InNewSpace(*p) && !ObjectMarking::IsBlack(HeapObject::cast(*p)); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2770 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); | 2760 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); |
| 2771 heap_->RightTrimFixedArray(enum_indices_cache, to_trim); | 2761 heap_->RightTrimFixedArray(enum_indices_cache, to_trim); |
| 2772 } | 2762 } |
| 2773 | 2763 |
| 2774 | 2764 |
| 2775 void MarkCompactCollector::ProcessWeakCollections() { | 2765 void MarkCompactCollector::ProcessWeakCollections() { |
| 2776 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2766 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
| 2777 while (weak_collection_obj != Smi::kZero) { | 2767 while (weak_collection_obj != Smi::kZero) { |
| 2778 JSWeakCollection* weak_collection = | 2768 JSWeakCollection* weak_collection = |
| 2779 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2769 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
| 2780 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); | 2770 DCHECK(ObjectMarking::IsBlackOrGrey(weak_collection)); |
| 2781 if (weak_collection->table()->IsHashTable()) { | 2771 if (weak_collection->table()->IsHashTable()) { |
| 2782 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2772 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
| 2783 for (int i = 0; i < table->Capacity(); i++) { | 2773 for (int i = 0; i < table->Capacity(); i++) { |
| 2784 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { | 2774 if (ObjectMarking::IsBlackOrGrey(HeapObject::cast(table->KeyAt(i)))) { |
| 2785 Object** key_slot = | 2775 Object** key_slot = |
| 2786 table->RawFieldOfElementAt(ObjectHashTable::EntryToIndex(i)); | 2776 table->RawFieldOfElementAt(ObjectHashTable::EntryToIndex(i)); |
| 2787 RecordSlot(table, key_slot, *key_slot); | 2777 RecordSlot(table, key_slot, *key_slot); |
| 2788 Object** value_slot = | 2778 Object** value_slot = |
| 2789 table->RawFieldOfElementAt(ObjectHashTable::EntryToValueIndex(i)); | 2779 table->RawFieldOfElementAt(ObjectHashTable::EntryToValueIndex(i)); |
| 2790 MarkCompactMarkingVisitor::MarkObjectByPointer(this, table, | 2780 MarkCompactMarkingVisitor::MarkObjectByPointer(this, table, |
| 2791 value_slot); | 2781 value_slot); |
| 2792 } | 2782 } |
| 2793 } | 2783 } |
| 2794 } | 2784 } |
| 2795 weak_collection_obj = weak_collection->next(); | 2785 weak_collection_obj = weak_collection->next(); |
| 2796 } | 2786 } |
| 2797 } | 2787 } |
| 2798 | 2788 |
| 2799 | 2789 |
| 2800 void MarkCompactCollector::ClearWeakCollections() { | 2790 void MarkCompactCollector::ClearWeakCollections() { |
| 2801 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_COLLECTIONS); | 2791 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_COLLECTIONS); |
| 2802 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2792 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
| 2803 while (weak_collection_obj != Smi::kZero) { | 2793 while (weak_collection_obj != Smi::kZero) { |
| 2804 JSWeakCollection* weak_collection = | 2794 JSWeakCollection* weak_collection = |
| 2805 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2795 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
| 2806 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); | 2796 DCHECK(ObjectMarking::IsBlackOrGrey(weak_collection)); |
| 2807 if (weak_collection->table()->IsHashTable()) { | 2797 if (weak_collection->table()->IsHashTable()) { |
| 2808 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2798 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
| 2809 for (int i = 0; i < table->Capacity(); i++) { | 2799 for (int i = 0; i < table->Capacity(); i++) { |
| 2810 HeapObject* key = HeapObject::cast(table->KeyAt(i)); | 2800 HeapObject* key = HeapObject::cast(table->KeyAt(i)); |
| 2811 if (!MarkCompactCollector::IsMarked(key)) { | 2801 if (!ObjectMarking::IsBlackOrGrey(key)) { |
| 2812 table->RemoveEntry(i); | 2802 table->RemoveEntry(i); |
| 2813 } | 2803 } |
| 2814 } | 2804 } |
| 2815 } | 2805 } |
| 2816 weak_collection_obj = weak_collection->next(); | 2806 weak_collection_obj = weak_collection->next(); |
| 2817 weak_collection->set_next(heap()->undefined_value()); | 2807 weak_collection->set_next(heap()->undefined_value()); |
| 2818 } | 2808 } |
| 2819 heap()->set_encountered_weak_collections(Smi::kZero); | 2809 heap()->set_encountered_weak_collections(Smi::kZero); |
| 2820 } | 2810 } |
| 2821 | 2811 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2842 DependentCode::cast(heap->empty_fixed_array()); | 2832 DependentCode::cast(heap->empty_fixed_array()); |
| 2843 Object* non_live_map_head = Smi::kZero; | 2833 Object* non_live_map_head = Smi::kZero; |
| 2844 while (weak_cell_obj != Smi::kZero) { | 2834 while (weak_cell_obj != Smi::kZero) { |
| 2845 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); | 2835 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
| 2846 Object* next_weak_cell = weak_cell->next(); | 2836 Object* next_weak_cell = weak_cell->next(); |
| 2847 bool clear_value = true; | 2837 bool clear_value = true; |
| 2848 bool clear_next = true; | 2838 bool clear_next = true; |
| 2849 // We do not insert cleared weak cells into the list, so the value | 2839 // We do not insert cleared weak cells into the list, so the value |
| 2850 // cannot be a Smi here. | 2840 // cannot be a Smi here. |
| 2851 HeapObject* value = HeapObject::cast(weak_cell->value()); | 2841 HeapObject* value = HeapObject::cast(weak_cell->value()); |
| 2852 if (!MarkCompactCollector::IsMarked(value)) { | 2842 if (!ObjectMarking::IsBlackOrGrey(value)) { |
| 2853 // Cells for new-space objects embedded in optimized code are wrapped in | 2843 // Cells for new-space objects embedded in optimized code are wrapped in |
| 2854 // WeakCell and put into Heap::weak_object_to_code_table. | 2844 // WeakCell and put into Heap::weak_object_to_code_table. |
| 2855 // Such cells do not have any strong references but we want to keep them | 2845 // Such cells do not have any strong references but we want to keep them |
| 2856 // alive as long as the cell value is alive. | 2846 // alive as long as the cell value is alive. |
| 2857 // TODO(ulan): remove this once we remove Heap::weak_object_to_code_table. | 2847 // TODO(ulan): remove this once we remove Heap::weak_object_to_code_table. |
| 2858 if (value->IsCell()) { | 2848 if (value->IsCell()) { |
| 2859 Object* cell_value = Cell::cast(value)->value(); | 2849 Object* cell_value = Cell::cast(value)->value(); |
| 2860 if (cell_value->IsHeapObject() && | 2850 if (cell_value->IsHeapObject() && |
| 2861 MarkCompactCollector::IsMarked(HeapObject::cast(cell_value))) { | 2851 ObjectMarking::IsBlackOrGrey(HeapObject::cast(cell_value))) { |
| 2862 // Resurrect the cell. | 2852 // Resurrect the cell. |
| 2863 SetMark(value); | 2853 ObjectMarking::WhiteToBlack(value); |
| 2864 Object** slot = HeapObject::RawField(value, Cell::kValueOffset); | 2854 Object** slot = HeapObject::RawField(value, Cell::kValueOffset); |
| 2865 RecordSlot(value, slot, *slot); | 2855 RecordSlot(value, slot, *slot); |
| 2866 slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); | 2856 slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); |
| 2867 RecordSlot(weak_cell, slot, *slot); | 2857 RecordSlot(weak_cell, slot, *slot); |
| 2868 clear_value = false; | 2858 clear_value = false; |
| 2869 } | 2859 } |
| 2870 } | 2860 } |
| 2871 if (value->IsMap()) { | 2861 if (value->IsMap()) { |
| 2872 // The map is non-live. | 2862 // The map is non-live. |
| 2873 Map* map = Map::cast(value); | 2863 Map* map = Map::cast(value); |
| (...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4064 // The target is always in old space, we don't have to record the slot in | 4054 // The target is always in old space, we don't have to record the slot in |
| 4065 // the old-to-new remembered set. | 4055 // the old-to-new remembered set. |
| 4066 DCHECK(!heap()->InNewSpace(target)); | 4056 DCHECK(!heap()->InNewSpace(target)); |
| 4067 RecordRelocSlot(host, &rinfo, target); | 4057 RecordRelocSlot(host, &rinfo, target); |
| 4068 } | 4058 } |
| 4069 } | 4059 } |
| 4070 } | 4060 } |
| 4071 | 4061 |
| 4072 } // namespace internal | 4062 } // namespace internal |
| 4073 } // namespace v8 | 4063 } // namespace v8 |
| OLD | NEW |