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 |