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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. | 44 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. |
45 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); | 45 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); |
46 | 46 |
47 // ============================================================================= | 47 // ============================================================================= |
48 // Verifiers | 48 // Verifiers |
49 // ============================================================================= | 49 // ============================================================================= |
50 | 50 |
51 #ifdef VERIFY_HEAP | 51 #ifdef VERIFY_HEAP |
52 namespace { | 52 namespace { |
53 | 53 |
54 class MarkingVerifier : public ObjectVisitor { | 54 class MarkingVerifier : public ObjectVisitor, public RootVisitor { |
55 public: | 55 public: |
56 virtual void Run() = 0; | 56 virtual void Run() = 0; |
57 | 57 |
58 protected: | 58 protected: |
59 explicit MarkingVerifier(Heap* heap) : heap_(heap) {} | 59 explicit MarkingVerifier(Heap* heap) : heap_(heap) {} |
60 | 60 |
61 virtual MarkingState marking_state(MemoryChunk* chunk) = 0; | 61 virtual MarkingState marking_state(MemoryChunk* chunk) = 0; |
62 | 62 |
| 63 virtual void VerifyPointers(Object** start, Object** end) = 0; |
| 64 |
| 65 void VisitPointers(Object** start, Object** end) override { |
| 66 VerifyPointers(start, end); |
| 67 } |
| 68 |
| 69 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 70 VerifyPointers(start, end); |
| 71 } |
| 72 |
63 void VerifyRoots(VisitMode mode); | 73 void VerifyRoots(VisitMode mode); |
64 void VerifyMarkingOnPage(const Page& page, const MarkingState& state, | 74 void VerifyMarkingOnPage(const Page& page, const MarkingState& state, |
65 Address start, Address end); | 75 Address start, Address end); |
66 void VerifyMarking(NewSpace* new_space); | 76 void VerifyMarking(NewSpace* new_space); |
67 void VerifyMarking(PagedSpace* paged_space); | 77 void VerifyMarking(PagedSpace* paged_space); |
68 | 78 |
69 Heap* heap_; | 79 Heap* heap_; |
70 }; | 80 }; |
71 | 81 |
72 void MarkingVerifier::VerifyRoots(VisitMode mode) { | 82 void MarkingVerifier::VerifyRoots(VisitMode mode) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 155 |
146 protected: | 156 protected: |
147 MarkingState marking_state(MemoryChunk* chunk) override { | 157 MarkingState marking_state(MemoryChunk* chunk) override { |
148 return MarkingState::Internal(chunk); | 158 return MarkingState::Internal(chunk); |
149 } | 159 } |
150 | 160 |
151 MarkingState marking_state(HeapObject* object) { | 161 MarkingState marking_state(HeapObject* object) { |
152 return MarkingState::Internal(object); | 162 return MarkingState::Internal(object); |
153 } | 163 } |
154 | 164 |
155 void VisitPointers(Object** start, Object** end) override { | 165 void VerifyPointers(Object** start, Object** end) override { |
156 for (Object** current = start; current < end; current++) { | 166 for (Object** current = start; current < end; current++) { |
157 if ((*current)->IsHeapObject()) { | 167 if ((*current)->IsHeapObject()) { |
158 HeapObject* object = HeapObject::cast(*current); | 168 HeapObject* object = HeapObject::cast(*current); |
159 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); | 169 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); |
160 } | 170 } |
161 } | 171 } |
162 } | 172 } |
163 | 173 |
164 void VisitEmbeddedPointer(RelocInfo* rinfo) override { | 174 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
165 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 175 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
(...skipping 22 matching lines...) Expand all Loading... |
188 | 198 |
189 MarkingState marking_state(HeapObject* object) { | 199 MarkingState marking_state(HeapObject* object) { |
190 return MarkingState::External(object); | 200 return MarkingState::External(object); |
191 } | 201 } |
192 | 202 |
193 void Run() override { | 203 void Run() override { |
194 VerifyRoots(VISIT_ALL_IN_SCAVENGE); | 204 VerifyRoots(VISIT_ALL_IN_SCAVENGE); |
195 VerifyMarking(heap_->new_space()); | 205 VerifyMarking(heap_->new_space()); |
196 } | 206 } |
197 | 207 |
198 void VisitPointers(Object** start, Object** end) override { | 208 void VerifyPointers(Object** start, Object** end) override { |
199 for (Object** current = start; current < end; current++) { | 209 for (Object** current = start; current < end; current++) { |
200 if ((*current)->IsHeapObject()) { | 210 if ((*current)->IsHeapObject()) { |
201 HeapObject* object = HeapObject::cast(*current); | 211 HeapObject* object = HeapObject::cast(*current); |
202 if (!heap_->InNewSpace(object)) return; | 212 if (!heap_->InNewSpace(object)) return; |
203 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); | 213 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); |
204 } | 214 } |
205 } | 215 } |
206 } | 216 } |
207 }; | 217 }; |
208 | 218 |
209 class EvacuationVerifier : public ObjectVisitor { | 219 class EvacuationVerifier : public ObjectVisitor, public RootVisitor { |
210 public: | 220 public: |
211 virtual void Run() = 0; | 221 virtual void Run() = 0; |
212 | 222 |
213 void VisitPointers(Object** start, Object** end) override { | 223 void VisitPointers(Object** start, Object** end) override { |
| 224 VerifyPointers(start, end); |
| 225 } |
| 226 |
| 227 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 228 VerifyPointers(start, end); |
| 229 } |
| 230 |
| 231 protected: |
| 232 explicit EvacuationVerifier(Heap* heap) : heap_(heap) {} |
| 233 |
| 234 void VerifyPointers(Object** start, Object** end) { |
214 for (Object** current = start; current < end; current++) { | 235 for (Object** current = start; current < end; current++) { |
215 if ((*current)->IsHeapObject()) { | 236 if ((*current)->IsHeapObject()) { |
216 HeapObject* object = HeapObject::cast(*current); | 237 HeapObject* object = HeapObject::cast(*current); |
217 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); | 238 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); |
218 } | 239 } |
219 } | 240 } |
220 } | 241 } |
221 | 242 |
222 protected: | |
223 explicit EvacuationVerifier(Heap* heap) : heap_(heap) {} | |
224 | |
225 void VerifyRoots(VisitMode mode); | 243 void VerifyRoots(VisitMode mode); |
226 void VerifyEvacuationOnPage(Address start, Address end); | 244 void VerifyEvacuationOnPage(Address start, Address end); |
227 void VerifyEvacuation(NewSpace* new_space); | 245 void VerifyEvacuation(NewSpace* new_space); |
228 void VerifyEvacuation(PagedSpace* paged_space); | 246 void VerifyEvacuation(PagedSpace* paged_space); |
229 | 247 |
230 Heap* heap_; | 248 Heap* heap_; |
231 }; | 249 }; |
232 | 250 |
233 void EvacuationVerifier::VerifyRoots(VisitMode mode) { | 251 void EvacuationVerifier::VerifyRoots(VisitMode mode) { |
234 heap_->IterateStrongRoots(this, mode); | 252 heap_->IterateStrongRoots(this, mode); |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 : collector_(collector) {} | 1368 : collector_(collector) {} |
1351 | 1369 |
1352 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1370 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
1353 collector_->PrepareThreadForCodeFlushing(isolate, top); | 1371 collector_->PrepareThreadForCodeFlushing(isolate, top); |
1354 } | 1372 } |
1355 | 1373 |
1356 private: | 1374 private: |
1357 MarkCompactCollector* collector_; | 1375 MarkCompactCollector* collector_; |
1358 }; | 1376 }; |
1359 | 1377 |
1360 | 1378 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor, |
1361 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 1379 public RootVisitor { |
1362 public: | 1380 public: |
1363 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 1381 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) |
1364 : collector_(collector) {} | 1382 : collector_(collector) {} |
1365 | 1383 |
1366 void VisitPointers(Object** start, Object** end) override { | 1384 void VisitPointers(Object** start, Object** end) override { |
1367 for (Object** p = start; p < end; p++) VisitPointer(p); | 1385 for (Object** p = start; p < end; p++) MarkObject(p); |
1368 } | 1386 } |
1369 | 1387 |
1370 void VisitPointer(Object** slot) override { | 1388 void VisitPointer(Object** slot) override { MarkObject(slot); } |
| 1389 |
| 1390 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 1391 for (Object** p = start; p < end; p++) MarkObject(p); |
| 1392 } |
| 1393 |
| 1394 void VisitRootPointer(Root root, Object** slot) override { MarkObject(slot); } |
| 1395 |
| 1396 private: |
| 1397 void MarkObject(Object** slot) { |
1371 Object* obj = *slot; | 1398 Object* obj = *slot; |
1372 if (obj->IsSharedFunctionInfo()) { | 1399 if (obj->IsSharedFunctionInfo()) { |
1373 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 1400 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); |
1374 collector_->MarkObject(shared->code()); | 1401 collector_->MarkObject(shared->code()); |
1375 collector_->MarkObject(shared); | 1402 collector_->MarkObject(shared); |
1376 } | 1403 } |
1377 } | 1404 } |
1378 | |
1379 private: | |
1380 MarkCompactCollector* collector_; | 1405 MarkCompactCollector* collector_; |
1381 }; | 1406 }; |
1382 | 1407 |
1383 | 1408 |
1384 void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, | 1409 void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, |
1385 ThreadLocalTop* top) { | 1410 ThreadLocalTop* top) { |
1386 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1411 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
1387 // Note: for the frame that has a pending lazy deoptimization | 1412 // Note: for the frame that has a pending lazy deoptimization |
1388 // StackFrame::unchecked_code will return a non-optimized code object for | 1413 // StackFrame::unchecked_code will return a non-optimized code object for |
1389 // the outermost function and StackFrame::LookupCode will return | 1414 // the outermost function and StackFrame::LookupCode will return |
(...skipping 24 matching lines...) Expand all Loading... |
1414 heap()->isolate()->thread_manager()->IterateArchivedThreads( | 1439 heap()->isolate()->thread_manager()->IterateArchivedThreads( |
1415 &code_marking_visitor); | 1440 &code_marking_visitor); |
1416 | 1441 |
1417 SharedFunctionInfoMarkingVisitor visitor(this); | 1442 SharedFunctionInfoMarkingVisitor visitor(this); |
1418 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); | 1443 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); |
1419 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); | 1444 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); |
1420 | 1445 |
1421 ProcessMarkingDeque(); | 1446 ProcessMarkingDeque(); |
1422 } | 1447 } |
1423 | 1448 |
1424 class MinorMarkCompactCollector::RootMarkingVisitor : public ObjectVisitor { | 1449 class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor { |
1425 public: | 1450 public: |
1426 explicit RootMarkingVisitor(MinorMarkCompactCollector* collector) | 1451 explicit RootMarkingVisitor(MinorMarkCompactCollector* collector) |
1427 : collector_(collector) {} | 1452 : collector_(collector) {} |
1428 | 1453 |
1429 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } | 1454 void VisitRootPointer(Root root, Object** p) override { |
| 1455 MarkObjectByPointer(p); |
| 1456 } |
1430 | 1457 |
1431 void VisitPointers(Object** start, Object** end) override { | 1458 void VisitRootPointers(Root root, Object** start, Object** end) override { |
1432 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 1459 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
1433 } | 1460 } |
1434 | 1461 |
1435 // Skip the weak next code link in a code object, which is visited in | |
1436 // ProcessTopOptimizedFrame. | |
1437 void VisitNextCodeLink(Object** p) override {} | |
1438 | |
1439 private: | 1462 private: |
1440 void MarkObjectByPointer(Object** p) { | 1463 void MarkObjectByPointer(Object** p) { |
1441 if (!(*p)->IsHeapObject()) return; | 1464 if (!(*p)->IsHeapObject()) return; |
1442 | 1465 |
1443 HeapObject* object = HeapObject::cast(*p); | 1466 HeapObject* object = HeapObject::cast(*p); |
1444 | 1467 |
1445 if (!collector_->heap()->InNewSpace(object)) return; | 1468 if (!collector_->heap()->InNewSpace(object)) return; |
1446 | 1469 |
1447 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( | 1470 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( |
1448 object, MarkingState::External(object))) | 1471 object, MarkingState::External(object))) |
1449 return; | 1472 return; |
1450 | 1473 |
1451 Map* map = object->map(); | 1474 Map* map = object->map(); |
1452 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( | 1475 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( |
1453 object, MarkingState::External(object)); | 1476 object, MarkingState::External(object)); |
1454 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); | 1477 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); |
1455 | 1478 |
1456 collector_->EmptyMarkingDeque(); | 1479 collector_->EmptyMarkingDeque(); |
1457 } | 1480 } |
1458 | 1481 |
1459 MinorMarkCompactCollector* collector_; | 1482 MinorMarkCompactCollector* collector_; |
1460 }; | 1483 }; |
1461 | 1484 |
1462 // Visitor class for marking heap roots. | 1485 // Visitor class for marking heap roots. |
1463 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor { | 1486 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of |
| 1487 // the string table and the top optimized code. |
| 1488 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor, |
| 1489 public RootVisitor { |
1464 public: | 1490 public: |
1465 explicit RootMarkingVisitor(Heap* heap) | 1491 explicit RootMarkingVisitor(Heap* heap) |
1466 : collector_(heap->mark_compact_collector()) {} | 1492 : collector_(heap->mark_compact_collector()) {} |
1467 | 1493 |
1468 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } | 1494 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } |
1469 | 1495 |
1470 void VisitPointers(Object** start, Object** end) override { | 1496 void VisitPointers(Object** start, Object** end) override { |
1471 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 1497 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
1472 } | 1498 } |
1473 | 1499 |
| 1500 void VisitRootPointer(Root root, Object** p) override { |
| 1501 MarkObjectByPointer(p); |
| 1502 } |
| 1503 |
| 1504 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 1505 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
| 1506 } |
| 1507 |
1474 // Skip the weak next code link in a code object, which is visited in | 1508 // Skip the weak next code link in a code object, which is visited in |
1475 // ProcessTopOptimizedFrame. | 1509 // ProcessTopOptimizedFrame. |
1476 void VisitNextCodeLink(Object** p) override {} | 1510 void VisitNextCodeLink(Object** p) override {} |
1477 | 1511 |
1478 private: | 1512 private: |
1479 void MarkObjectByPointer(Object** p) { | 1513 void MarkObjectByPointer(Object** p) { |
1480 if (!(*p)->IsHeapObject()) return; | 1514 if (!(*p)->IsHeapObject()) return; |
1481 | 1515 |
1482 HeapObject* object = HeapObject::cast(*p); | 1516 HeapObject* object = HeapObject::cast(*p); |
1483 | 1517 |
(...skipping 11 matching lines...) Expand all Loading... |
1495 MarkCompactMarkingVisitor::IterateBody(map, object); | 1529 MarkCompactMarkingVisitor::IterateBody(map, object); |
1496 | 1530 |
1497 // Mark all the objects reachable from the map and body. May leave | 1531 // Mark all the objects reachable from the map and body. May leave |
1498 // overflowed objects in the heap. | 1532 // overflowed objects in the heap. |
1499 collector_->EmptyMarkingDeque(); | 1533 collector_->EmptyMarkingDeque(); |
1500 } | 1534 } |
1501 | 1535 |
1502 MarkCompactCollector* collector_; | 1536 MarkCompactCollector* collector_; |
1503 }; | 1537 }; |
1504 | 1538 |
1505 | 1539 class InternalizedStringTableCleaner : public ObjectVisitor { |
1506 // Helper class for pruning the string table. | |
1507 template <bool finalize_external_strings, bool record_slots> | |
1508 class StringTableCleaner : public ObjectVisitor { | |
1509 public: | 1540 public: |
1510 StringTableCleaner(Heap* heap, HeapObject* table) | 1541 InternalizedStringTableCleaner(Heap* heap, HeapObject* table) |
1511 : heap_(heap), pointers_removed_(0), table_(table) { | 1542 : heap_(heap), pointers_removed_(0), table_(table) {} |
1512 DCHECK(!record_slots || table != nullptr); | |
1513 } | |
1514 | 1543 |
1515 void VisitPointers(Object** start, Object** end) override { | 1544 void VisitPointers(Object** start, Object** end) override { |
1516 // Visit all HeapObject pointers in [start, end). | 1545 // Visit all HeapObject pointers in [start, end). |
1517 MarkCompactCollector* collector = heap_->mark_compact_collector(); | 1546 MarkCompactCollector* collector = heap_->mark_compact_collector(); |
| 1547 Object* the_hole = heap_->the_hole_value(); |
1518 for (Object** p = start; p < end; p++) { | 1548 for (Object** p = start; p < end; p++) { |
1519 Object* o = *p; | 1549 Object* o = *p; |
1520 if (o->IsHeapObject()) { | 1550 if (o->IsHeapObject()) { |
1521 HeapObject* heap_object = HeapObject::cast(o); | 1551 HeapObject* heap_object = HeapObject::cast(o); |
1522 if (ObjectMarking::IsWhite(heap_object, | 1552 if (ObjectMarking::IsWhite(heap_object, |
1523 MarkingState::Internal(heap_object))) { | 1553 MarkingState::Internal(heap_object))) { |
1524 if (finalize_external_strings) { | 1554 pointers_removed_++; |
1525 if (o->IsExternalString()) { | |
1526 heap_->FinalizeExternalString(String::cast(*p)); | |
1527 } else { | |
1528 // The original external string may have been internalized. | |
1529 DCHECK(o->IsThinString()); | |
1530 } | |
1531 } else { | |
1532 pointers_removed_++; | |
1533 } | |
1534 // Set the entry to the_hole_value (as deleted). | 1555 // Set the entry to the_hole_value (as deleted). |
1535 *p = heap_->the_hole_value(); | 1556 *p = the_hole; |
1536 } else if (record_slots) { | 1557 } else { |
1537 // StringTable contains only old space strings. | 1558 // StringTable contains only old space strings. |
1538 DCHECK(!heap_->InNewSpace(o)); | 1559 DCHECK(!heap_->InNewSpace(o)); |
1539 collector->RecordSlot(table_, p, o); | 1560 collector->RecordSlot(table_, p, o); |
1540 } | 1561 } |
1541 } | 1562 } |
1542 } | 1563 } |
1543 } | 1564 } |
1544 | 1565 |
1545 int PointersRemoved() { | 1566 int PointersRemoved() { |
1546 DCHECK(!finalize_external_strings); | |
1547 return pointers_removed_; | 1567 return pointers_removed_; |
1548 } | 1568 } |
1549 | 1569 |
1550 private: | 1570 private: |
1551 Heap* heap_; | 1571 Heap* heap_; |
1552 int pointers_removed_; | 1572 int pointers_removed_; |
1553 HeapObject* table_; | 1573 HeapObject* table_; |
1554 }; | 1574 }; |
1555 | 1575 |
1556 typedef StringTableCleaner<false, true> InternalizedStringTableCleaner; | 1576 class ExternalStringTableCleaner : public RootVisitor { |
1557 typedef StringTableCleaner<true, false> ExternalStringTableCleaner; | 1577 public: |
| 1578 explicit ExternalStringTableCleaner(Heap* heap) : heap_(heap) {} |
| 1579 |
| 1580 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 1581 // Visit all HeapObject pointers in [start, end). |
| 1582 Object* the_hole = heap_->the_hole_value(); |
| 1583 for (Object** p = start; p < end; p++) { |
| 1584 Object* o = *p; |
| 1585 if (o->IsHeapObject()) { |
| 1586 HeapObject* heap_object = HeapObject::cast(o); |
| 1587 if (ObjectMarking::IsWhite(heap_object, |
| 1588 MarkingState::Internal(heap_object))) { |
| 1589 if (o->IsExternalString()) { |
| 1590 heap_->FinalizeExternalString(String::cast(*p)); |
| 1591 } else { |
| 1592 // The original external string may have been internalized. |
| 1593 DCHECK(o->IsThinString()); |
| 1594 } |
| 1595 // Set the entry to the_hole_value (as deleted). |
| 1596 *p = the_hole; |
| 1597 } |
| 1598 } |
| 1599 } |
| 1600 } |
| 1601 |
| 1602 private: |
| 1603 Heap* heap_; |
| 1604 }; |
1558 | 1605 |
1559 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects | 1606 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects |
1560 // are retained. | 1607 // are retained. |
1561 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { | 1608 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { |
1562 public: | 1609 public: |
1563 virtual Object* RetainAs(Object* object) { | 1610 virtual Object* RetainAs(Object* object) { |
1564 HeapObject* heap_object = HeapObject::cast(object); | 1611 HeapObject* heap_object = HeapObject::cast(object); |
1565 DCHECK(!ObjectMarking::IsGrey(heap_object, | 1612 DCHECK(!ObjectMarking::IsGrey(heap_object, |
1566 MarkingState::Internal(heap_object))); | 1613 MarkingState::Internal(heap_object))); |
1567 if (ObjectMarking::IsBlack(heap_object, | 1614 if (ObjectMarking::IsBlack(heap_object, |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 while (marking_deque()->overflowed()) { | 2191 while (marking_deque()->overflowed()) { |
2145 RefillMarkingDeque(); | 2192 RefillMarkingDeque(); |
2146 EmptyMarkingDeque(); | 2193 EmptyMarkingDeque(); |
2147 } | 2194 } |
2148 DCHECK(marking_deque()->IsEmpty()); | 2195 DCHECK(marking_deque()->IsEmpty()); |
2149 } | 2196 } |
2150 | 2197 |
2151 // Mark all objects reachable (transitively) from objects on the marking | 2198 // Mark all objects reachable (transitively) from objects on the marking |
2152 // stack including references only considered in the atomic marking pause. | 2199 // stack including references only considered in the atomic marking pause. |
2153 void MarkCompactCollector::ProcessEphemeralMarking( | 2200 void MarkCompactCollector::ProcessEphemeralMarking( |
2154 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { | 2201 bool only_process_harmony_weak_collections) { |
2155 DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed()); | 2202 DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed()); |
2156 bool work_to_do = true; | 2203 bool work_to_do = true; |
2157 while (work_to_do) { | 2204 while (work_to_do) { |
2158 if (!only_process_harmony_weak_collections) { | 2205 if (!only_process_harmony_weak_collections) { |
2159 if (heap_->local_embedder_heap_tracer()->InUse()) { | 2206 if (heap_->local_embedder_heap_tracer()->InUse()) { |
2160 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING); | 2207 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING); |
2161 heap_->local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer(); | 2208 heap_->local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer(); |
2162 heap_->local_embedder_heap_tracer()->Trace( | 2209 heap_->local_embedder_heap_tracer()->Trace( |
2163 0, | 2210 0, |
2164 EmbedderHeapTracer::AdvanceTracingActions( | 2211 EmbedderHeapTracer::AdvanceTracingActions( |
2165 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); | 2212 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); |
2166 } | 2213 } |
2167 } else { | 2214 } else { |
2168 // TODO(mlippautz): We currently do not trace through blink when | 2215 // TODO(mlippautz): We currently do not trace through blink when |
2169 // discovering new objects reachable from weak roots (that have been made | 2216 // discovering new objects reachable from weak roots (that have been made |
2170 // strong). This is a limitation of not having a separate handle type | 2217 // strong). This is a limitation of not having a separate handle type |
2171 // that doesn't require zapping before this phase. See crbug.com/668060. | 2218 // that doesn't require zapping before this phase. See crbug.com/668060. |
2172 heap_->local_embedder_heap_tracer()->ClearCachedWrappersToTrace(); | 2219 heap_->local_embedder_heap_tracer()->ClearCachedWrappersToTrace(); |
2173 } | 2220 } |
2174 ProcessWeakCollections(); | 2221 ProcessWeakCollections(); |
2175 work_to_do = !marking_deque()->IsEmpty(); | 2222 work_to_do = !marking_deque()->IsEmpty(); |
2176 ProcessMarkingDeque(); | 2223 ProcessMarkingDeque(); |
2177 } | 2224 } |
2178 CHECK(marking_deque()->IsEmpty()); | 2225 CHECK(marking_deque()->IsEmpty()); |
2179 CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace()); | 2226 CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace()); |
2180 } | 2227 } |
2181 | 2228 |
2182 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { | 2229 void MarkCompactCollector::ProcessTopOptimizedFrame( |
| 2230 RootMarkingVisitor* visitor) { |
2183 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); | 2231 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); |
2184 !it.done(); it.Advance()) { | 2232 !it.done(); it.Advance()) { |
2185 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { | 2233 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { |
2186 return; | 2234 return; |
2187 } | 2235 } |
2188 if (it.frame()->type() == StackFrame::OPTIMIZED) { | 2236 if (it.frame()->type() == StackFrame::OPTIMIZED) { |
2189 Code* code = it.frame()->LookupCode(); | 2237 Code* code = it.frame()->LookupCode(); |
2190 if (!code->CanDeoptAt(it.frame()->pc())) { | 2238 if (!code->CanDeoptAt(it.frame()->pc())) { |
2191 Code::BodyDescriptor::IterateBody(code, visitor); | 2239 Code::BodyDescriptor::IterateBody(code, visitor); |
2192 } | 2240 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2402 isolate(), type, addr, [this](Object** addr) { | 2450 isolate(), type, addr, [this](Object** addr) { |
2403 return CheckAndMarkObject(heap(), | 2451 return CheckAndMarkObject(heap(), |
2404 reinterpret_cast<Address>(addr)); | 2452 reinterpret_cast<Address>(addr)); |
2405 }); | 2453 }); |
2406 }); | 2454 }); |
2407 ProcessMarkingDeque(); | 2455 ProcessMarkingDeque(); |
2408 } | 2456 } |
2409 | 2457 |
2410 { | 2458 { |
2411 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK); | 2459 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK); |
2412 heap()->VisitEncounteredWeakCollections(&root_visitor); | 2460 heap()->IterateEncounteredWeakCollections(&root_visitor); |
2413 ProcessMarkingDeque(); | 2461 ProcessMarkingDeque(); |
2414 } | 2462 } |
2415 | 2463 |
2416 { | 2464 { |
2417 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES); | 2465 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES); |
2418 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( | 2466 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( |
2419 &IsUnmarkedObject); | 2467 &IsUnmarkedObject); |
2420 isolate() | 2468 isolate() |
2421 ->global_handles() | 2469 ->global_handles() |
2422 ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>( | 2470 ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>( |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 | 2551 |
2504 { | 2552 { |
2505 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); | 2553 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); |
2506 | 2554 |
2507 // The objects reachable from the roots are marked, yet unreachable | 2555 // The objects reachable from the roots are marked, yet unreachable |
2508 // objects are unmarked. Mark objects reachable due to host | 2556 // objects are unmarked. Mark objects reachable due to host |
2509 // application specific logic or through Harmony weak maps. | 2557 // application specific logic or through Harmony weak maps. |
2510 { | 2558 { |
2511 TRACE_GC(heap()->tracer(), | 2559 TRACE_GC(heap()->tracer(), |
2512 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); | 2560 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); |
2513 ProcessEphemeralMarking(&root_visitor, false); | 2561 ProcessEphemeralMarking(false); |
2514 } | 2562 } |
2515 | 2563 |
2516 // The objects reachable from the roots, weak maps or object groups | 2564 // The objects reachable from the roots, weak maps or object groups |
2517 // are marked. Objects pointed to only by weak global handles cannot be | 2565 // are marked. Objects pointed to only by weak global handles cannot be |
2518 // immediately reclaimed. Instead, we have to mark them as pending and mark | 2566 // immediately reclaimed. Instead, we have to mark them as pending and mark |
2519 // objects reachable from them. | 2567 // objects reachable from them. |
2520 // | 2568 // |
2521 // First we identify nonlive weak handles and mark them as pending | 2569 // First we identify nonlive weak handles and mark them as pending |
2522 // destruction. | 2570 // destruction. |
2523 { | 2571 { |
(...skipping 12 matching lines...) Expand all Loading... |
2536 ProcessMarkingDeque(); | 2584 ProcessMarkingDeque(); |
2537 } | 2585 } |
2538 | 2586 |
2539 // Repeat Harmony weak maps marking to mark unmarked objects reachable from | 2587 // Repeat Harmony weak maps marking to mark unmarked objects reachable from |
2540 // the weak roots we just marked as pending destruction. | 2588 // the weak roots we just marked as pending destruction. |
2541 // | 2589 // |
2542 // We only process harmony collections, as all object groups have been fully | 2590 // We only process harmony collections, as all object groups have been fully |
2543 // processed and no weakly reachable node can discover new objects groups. | 2591 // processed and no weakly reachable node can discover new objects groups. |
2544 { | 2592 { |
2545 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); | 2593 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); |
2546 ProcessEphemeralMarking(&root_visitor, true); | 2594 ProcessEphemeralMarking(true); |
2547 { | 2595 { |
2548 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_EPILOGUE); | 2596 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_EPILOGUE); |
2549 heap()->local_embedder_heap_tracer()->TraceEpilogue(); | 2597 heap()->local_embedder_heap_tracer()->TraceEpilogue(); |
2550 } | 2598 } |
2551 } | 2599 } |
2552 } | 2600 } |
2553 } | 2601 } |
2554 | 2602 |
2555 | 2603 |
2556 void MarkCompactCollector::ClearNonLiveReferences() { | 2604 void MarkCompactCollector::ClearNonLiveReferences() { |
2557 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); | 2605 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); |
2558 | 2606 |
2559 { | 2607 { |
2560 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_STRING_TABLE); | 2608 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_STRING_TABLE); |
2561 | 2609 |
2562 // Prune the string table removing all strings only pointed to by the | 2610 // Prune the string table removing all strings only pointed to by the |
2563 // string table. Cannot use string_table() here because the string | 2611 // string table. Cannot use string_table() here because the string |
2564 // table is marked. | 2612 // table is marked. |
2565 StringTable* string_table = heap()->string_table(); | 2613 StringTable* string_table = heap()->string_table(); |
2566 InternalizedStringTableCleaner internalized_visitor(heap(), string_table); | 2614 InternalizedStringTableCleaner internalized_visitor(heap(), string_table); |
2567 string_table->IterateElements(&internalized_visitor); | 2615 string_table->IterateElements(&internalized_visitor); |
2568 string_table->ElementsRemoved(internalized_visitor.PointersRemoved()); | 2616 string_table->ElementsRemoved(internalized_visitor.PointersRemoved()); |
2569 | 2617 |
2570 ExternalStringTableCleaner external_visitor(heap(), nullptr); | 2618 ExternalStringTableCleaner external_visitor(heap()); |
2571 heap()->external_string_table_.IterateAll(&external_visitor); | 2619 heap()->external_string_table_.IterateAll(&external_visitor); |
2572 heap()->external_string_table_.CleanUpAll(); | 2620 heap()->external_string_table_.CleanUpAll(); |
2573 } | 2621 } |
2574 | 2622 |
2575 { | 2623 { |
2576 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_LISTS); | 2624 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_LISTS); |
2577 // Process the weak references. | 2625 // Process the weak references. |
2578 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 2626 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
2579 heap()->ProcessAllWeakReferences(&mark_compact_object_retainer); | 2627 heap()->ProcessAllWeakReferences(&mark_compact_object_retainer); |
2580 } | 2628 } |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3031 reinterpret_cast<base::AtomicWord*>(slot), | 3079 reinterpret_cast<base::AtomicWord*>(slot), |
3032 reinterpret_cast<base::AtomicWord>(obj), | 3080 reinterpret_cast<base::AtomicWord>(obj), |
3033 reinterpret_cast<base::AtomicWord>(target)); | 3081 reinterpret_cast<base::AtomicWord>(target)); |
3034 DCHECK(!heap_obj->GetHeap()->InFromSpace(target)); | 3082 DCHECK(!heap_obj->GetHeap()->InFromSpace(target)); |
3035 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(target)); | 3083 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(target)); |
3036 } | 3084 } |
3037 } | 3085 } |
3038 return REMOVE_SLOT; | 3086 return REMOVE_SLOT; |
3039 } | 3087 } |
3040 | 3088 |
3041 // Visitor for updating pointers from live objects in old spaces to new space. | 3089 // Visitor for updating root pointers and to-space pointers. |
3042 // It does not expect to encounter pointers to dead objects. | 3090 // It does not expect to encounter pointers to dead objects. |
3043 class PointersUpdatingVisitor : public ObjectVisitor { | 3091 // TODO(ulan): Remove code object specific functions. This visitor |
| 3092 // nevers visits code objects. |
| 3093 class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor { |
3044 public: | 3094 public: |
3045 void VisitPointer(Object** p) override { UpdateSlot(p); } | 3095 void VisitPointer(Object** p) override { UpdateSlot(p); } |
3046 | 3096 |
3047 void VisitPointers(Object** start, Object** end) override { | 3097 void VisitPointers(Object** start, Object** end) override { |
3048 for (Object** p = start; p < end; p++) UpdateSlot(p); | 3098 for (Object** p = start; p < end; p++) UpdateSlot(p); |
3049 } | 3099 } |
3050 | 3100 |
| 3101 void VisitRootPointer(Root root, Object** p) override { UpdateSlot(p); } |
| 3102 |
| 3103 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 3104 for (Object** p = start; p < end; p++) UpdateSlot(p); |
| 3105 } |
| 3106 |
3051 void VisitCell(RelocInfo* rinfo) override { | 3107 void VisitCell(RelocInfo* rinfo) override { |
3052 UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot); | 3108 UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot); |
3053 } | 3109 } |
3054 | 3110 |
3055 void VisitEmbeddedPointer(RelocInfo* rinfo) override { | 3111 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
3056 UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot); | 3112 UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot); |
3057 } | 3113 } |
3058 | 3114 |
3059 void VisitCodeTarget(RelocInfo* rinfo) override { | 3115 void VisitCodeTarget(RelocInfo* rinfo) override { |
3060 UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot); | 3116 UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot); |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3902 job.AddPage(page, std::make_pair(start, end)); | 3958 job.AddPage(page, std::make_pair(start, end)); |
3903 } | 3959 } |
3904 PointersUpdatingVisitor visitor; | 3960 PointersUpdatingVisitor visitor; |
3905 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3961 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
3906 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3962 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
3907 } | 3963 } |
3908 | 3964 |
3909 void MarkCompactCollector::UpdatePointersAfterEvacuation() { | 3965 void MarkCompactCollector::UpdatePointersAfterEvacuation() { |
3910 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS); | 3966 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS); |
3911 | 3967 |
3912 PointersUpdatingVisitor updating_visitor; | |
3913 | 3968 |
3914 { | 3969 { |
3915 TRACE_GC(heap()->tracer(), | 3970 TRACE_GC(heap()->tracer(), |
3916 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW); | 3971 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW); |
3917 UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_); | 3972 UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_); |
3918 // Update roots. | 3973 // Update roots. |
| 3974 PointersUpdatingVisitor updating_visitor; |
3919 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); | 3975 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
3920 UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_); | 3976 UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_); |
3921 } | 3977 } |
3922 | 3978 |
3923 { | 3979 { |
3924 Heap* heap = this->heap(); | 3980 Heap* heap = this->heap(); |
3925 TRACE_GC(heap->tracer(), | 3981 TRACE_GC(heap->tracer(), |
3926 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); | 3982 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); |
3927 UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_); | 3983 UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_); |
3928 } | 3984 } |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4154 // The target is always in old space, we don't have to record the slot in | 4210 // The target is always in old space, we don't have to record the slot in |
4155 // the old-to-new remembered set. | 4211 // the old-to-new remembered set. |
4156 DCHECK(!heap()->InNewSpace(target)); | 4212 DCHECK(!heap()->InNewSpace(target)); |
4157 RecordRelocSlot(host, &rinfo, target); | 4213 RecordRelocSlot(host, &rinfo, target); |
4158 } | 4214 } |
4159 } | 4215 } |
4160 } | 4216 } |
4161 | 4217 |
4162 } // namespace internal | 4218 } // namespace internal |
4163 } // namespace v8 | 4219 } // namespace v8 |
OLD | NEW |