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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. | 43 // produce invalid {kImpossibleBitPattern} in the marking bitmap by overlapping. |
44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); | 44 STATIC_ASSERT(Heap::kMinObjectSizeInWords >= 2); |
45 | 45 |
46 // ============================================================================= | 46 // ============================================================================= |
47 // Verifiers | 47 // Verifiers |
48 // ============================================================================= | 48 // ============================================================================= |
49 | 49 |
50 #ifdef VERIFY_HEAP | 50 #ifdef VERIFY_HEAP |
51 namespace { | 51 namespace { |
52 | 52 |
53 class MarkingVerifier : public ObjectVisitor { | 53 class MarkingVerifier : public ObjectVisitor, public RootVisitor { |
Michael Lippautz
2017/04/20 09:01:29
Ugh, I am fine with this one but we should try har
Hannes Payer (out of office)
2017/04/21 09:42:08
Can't we compose ObjectVisitor and RootVisitor and
| |
54 public: | 54 public: |
55 virtual void Run() = 0; | 55 virtual void Run() = 0; |
56 | 56 |
57 protected: | 57 protected: |
58 explicit MarkingVerifier(Heap* heap) : heap_(heap) {} | 58 explicit MarkingVerifier(Heap* heap) : heap_(heap) {} |
59 | 59 |
60 virtual MarkingState marking_state(MemoryChunk* chunk) = 0; | 60 virtual MarkingState marking_state(MemoryChunk* chunk) = 0; |
61 | 61 |
62 virtual void VerifyPointers(Object** start, Object** end) = 0; | |
63 | |
64 void VisitPointers(Object** start, Object** end) override { | |
65 VerifyPointers(start, end); | |
66 } | |
67 | |
68 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
69 VerifyPointers(start, end); | |
70 } | |
71 | |
62 void VerifyRoots(VisitMode mode); | 72 void VerifyRoots(VisitMode mode); |
63 void VerifyMarkingOnPage(const Page& page, const MarkingState& state, | 73 void VerifyMarkingOnPage(const Page& page, const MarkingState& state, |
64 Address start, Address end); | 74 Address start, Address end); |
65 void VerifyMarking(NewSpace* new_space); | 75 void VerifyMarking(NewSpace* new_space); |
66 void VerifyMarking(PagedSpace* paged_space); | 76 void VerifyMarking(PagedSpace* paged_space); |
67 | 77 |
68 Heap* heap_; | 78 Heap* heap_; |
69 }; | 79 }; |
70 | 80 |
71 void MarkingVerifier::VerifyRoots(VisitMode mode) { | 81 void MarkingVerifier::VerifyRoots(VisitMode mode) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 | 154 |
145 protected: | 155 protected: |
146 MarkingState marking_state(MemoryChunk* chunk) override { | 156 MarkingState marking_state(MemoryChunk* chunk) override { |
147 return MarkingState::Internal(chunk); | 157 return MarkingState::Internal(chunk); |
148 } | 158 } |
149 | 159 |
150 MarkingState marking_state(HeapObject* object) { | 160 MarkingState marking_state(HeapObject* object) { |
151 return MarkingState::Internal(object); | 161 return MarkingState::Internal(object); |
152 } | 162 } |
153 | 163 |
154 void VisitPointers(Object** start, Object** end) override { | 164 void VerifyPointers(Object** start, Object** end) override { |
155 for (Object** current = start; current < end; current++) { | 165 for (Object** current = start; current < end; current++) { |
156 if ((*current)->IsHeapObject()) { | 166 if ((*current)->IsHeapObject()) { |
157 HeapObject* object = HeapObject::cast(*current); | 167 HeapObject* object = HeapObject::cast(*current); |
158 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); | 168 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); |
159 } | 169 } |
160 } | 170 } |
161 } | 171 } |
162 | 172 |
163 void VisitEmbeddedPointer(RelocInfo* rinfo) override { | 173 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
164 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 174 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
(...skipping 22 matching lines...) Expand all Loading... | |
187 | 197 |
188 MarkingState marking_state(HeapObject* object) { | 198 MarkingState marking_state(HeapObject* object) { |
189 return MarkingState::External(object); | 199 return MarkingState::External(object); |
190 } | 200 } |
191 | 201 |
192 void Run() override { | 202 void Run() override { |
193 VerifyRoots(VISIT_ALL_IN_SCAVENGE); | 203 VerifyRoots(VISIT_ALL_IN_SCAVENGE); |
194 VerifyMarking(heap_->new_space()); | 204 VerifyMarking(heap_->new_space()); |
195 } | 205 } |
196 | 206 |
197 void VisitPointers(Object** start, Object** end) override { | 207 void VerifyPointers(Object** start, Object** end) override { |
198 for (Object** current = start; current < end; current++) { | 208 for (Object** current = start; current < end; current++) { |
199 if ((*current)->IsHeapObject()) { | 209 if ((*current)->IsHeapObject()) { |
200 HeapObject* object = HeapObject::cast(*current); | 210 HeapObject* object = HeapObject::cast(*current); |
201 if (!heap_->InNewSpace(object)) return; | 211 if (!heap_->InNewSpace(object)) return; |
202 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); | 212 CHECK(ObjectMarking::IsBlackOrGrey(object, marking_state(object))); |
203 } | 213 } |
204 } | 214 } |
205 } | 215 } |
206 }; | 216 }; |
207 | 217 |
208 class EvacuationVerifier : public ObjectVisitor { | 218 class EvacuationVerifier : public ObjectVisitor, public RootVisitor { |
209 public: | 219 public: |
210 virtual void Run() = 0; | 220 virtual void Run() = 0; |
211 | 221 |
212 void VisitPointers(Object** start, Object** end) override { | 222 void VisitPointers(Object** start, Object** end) override { |
223 VerifyPointers(start, end); | |
224 } | |
225 | |
226 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
227 VerifyPointers(start, end); | |
228 } | |
229 | |
230 protected: | |
231 explicit EvacuationVerifier(Heap* heap) : heap_(heap) {} | |
232 | |
233 void VerifyPointers(Object** start, Object** end) { | |
213 for (Object** current = start; current < end; current++) { | 234 for (Object** current = start; current < end; current++) { |
214 if ((*current)->IsHeapObject()) { | 235 if ((*current)->IsHeapObject()) { |
215 HeapObject* object = HeapObject::cast(*current); | 236 HeapObject* object = HeapObject::cast(*current); |
216 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); | 237 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); |
217 } | 238 } |
218 } | 239 } |
219 } | 240 } |
220 | 241 |
221 protected: | |
222 explicit EvacuationVerifier(Heap* heap) : heap_(heap) {} | |
223 | |
224 void VerifyRoots(VisitMode mode); | 242 void VerifyRoots(VisitMode mode); |
225 void VerifyEvacuationOnPage(Address start, Address end); | 243 void VerifyEvacuationOnPage(Address start, Address end); |
226 void VerifyEvacuation(NewSpace* new_space); | 244 void VerifyEvacuation(NewSpace* new_space); |
227 void VerifyEvacuation(PagedSpace* paged_space); | 245 void VerifyEvacuation(PagedSpace* paged_space); |
228 | 246 |
229 Heap* heap_; | 247 Heap* heap_; |
230 }; | 248 }; |
231 | 249 |
232 void EvacuationVerifier::VerifyRoots(VisitMode mode) { | 250 void EvacuationVerifier::VerifyRoots(VisitMode mode) { |
233 heap_->IterateStrongRoots(this, mode); | 251 heap_->IterateStrongRoots(this, mode); |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1339 : collector_(collector) {} | 1357 : collector_(collector) {} |
1340 | 1358 |
1341 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1359 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
1342 collector_->PrepareThreadForCodeFlushing(isolate, top); | 1360 collector_->PrepareThreadForCodeFlushing(isolate, top); |
1343 } | 1361 } |
1344 | 1362 |
1345 private: | 1363 private: |
1346 MarkCompactCollector* collector_; | 1364 MarkCompactCollector* collector_; |
1347 }; | 1365 }; |
1348 | 1366 |
1349 | 1367 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor, |
1350 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 1368 public RootVisitor { |
1351 public: | 1369 public: |
1352 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 1370 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) |
1353 : collector_(collector) {} | 1371 : collector_(collector) {} |
1354 | 1372 |
1355 void VisitPointers(Object** start, Object** end) override { | 1373 void VisitPointers(Object** start, Object** end) override { |
1356 for (Object** p = start; p < end; p++) VisitPointer(p); | 1374 for (Object** p = start; p < end; p++) MarkObject(p); |
1357 } | 1375 } |
1358 | 1376 |
1359 void VisitPointer(Object** slot) override { | 1377 void VisitPointer(Object** slot) override { MarkObject(slot); } |
1378 | |
1379 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
1380 for (Object** p = start; p < end; p++) MarkObject(p); | |
1381 } | |
1382 | |
1383 void VisitRootPointer(Root root, Object** slot) override { MarkObject(slot); } | |
1384 | |
1385 private: | |
1386 void MarkObject(Object** slot) { | |
1360 Object* obj = *slot; | 1387 Object* obj = *slot; |
1361 if (obj->IsSharedFunctionInfo()) { | 1388 if (obj->IsSharedFunctionInfo()) { |
1362 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 1389 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); |
1363 collector_->MarkObject(shared->code()); | 1390 collector_->MarkObject(shared->code()); |
1364 collector_->MarkObject(shared); | 1391 collector_->MarkObject(shared); |
1365 } | 1392 } |
1366 } | 1393 } |
1367 | |
1368 private: | |
1369 MarkCompactCollector* collector_; | 1394 MarkCompactCollector* collector_; |
1370 }; | 1395 }; |
1371 | 1396 |
1372 | 1397 |
1373 void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, | 1398 void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate, |
1374 ThreadLocalTop* top) { | 1399 ThreadLocalTop* top) { |
1375 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1400 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { |
1376 // Note: for the frame that has a pending lazy deoptimization | 1401 // Note: for the frame that has a pending lazy deoptimization |
1377 // StackFrame::unchecked_code will return a non-optimized code object for | 1402 // StackFrame::unchecked_code will return a non-optimized code object for |
1378 // the outermost function and StackFrame::LookupCode will return | 1403 // the outermost function and StackFrame::LookupCode will return |
(...skipping 24 matching lines...) Expand all Loading... | |
1403 heap()->isolate()->thread_manager()->IterateArchivedThreads( | 1428 heap()->isolate()->thread_manager()->IterateArchivedThreads( |
1404 &code_marking_visitor); | 1429 &code_marking_visitor); |
1405 | 1430 |
1406 SharedFunctionInfoMarkingVisitor visitor(this); | 1431 SharedFunctionInfoMarkingVisitor visitor(this); |
1407 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); | 1432 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); |
1408 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); | 1433 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); |
1409 | 1434 |
1410 ProcessMarkingDeque(); | 1435 ProcessMarkingDeque(); |
1411 } | 1436 } |
1412 | 1437 |
1413 class MinorMarkCompactCollector::RootMarkingVisitor : public ObjectVisitor { | 1438 class MinorMarkCompactCollector::RootMarkingVisitor : public RootVisitor { |
1414 public: | 1439 public: |
1415 explicit RootMarkingVisitor(MinorMarkCompactCollector* collector) | 1440 explicit RootMarkingVisitor(MinorMarkCompactCollector* collector) |
1416 : collector_(collector) {} | 1441 : collector_(collector) {} |
1417 | 1442 |
1418 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } | 1443 void VisitRootPointer(Root root, Object** p) override { |
1444 MarkObjectByPointer(p); | |
1445 } | |
1419 | 1446 |
1420 void VisitPointers(Object** start, Object** end) override { | 1447 void VisitRootPointers(Root root, Object** start, Object** end) override { |
1421 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 1448 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
1422 } | 1449 } |
1423 | 1450 |
1424 // Skip the weak next code link in a code object, which is visited in | |
1425 // ProcessTopOptimizedFrame. | |
1426 void VisitNextCodeLink(Object** p) override {} | |
1427 | |
1428 private: | 1451 private: |
1429 void MarkObjectByPointer(Object** p) { | 1452 void MarkObjectByPointer(Object** p) { |
1430 if (!(*p)->IsHeapObject()) return; | 1453 if (!(*p)->IsHeapObject()) return; |
1431 | 1454 |
1432 HeapObject* object = HeapObject::cast(*p); | 1455 HeapObject* object = HeapObject::cast(*p); |
1433 | 1456 |
1434 if (!collector_->heap()->InNewSpace(object)) return; | 1457 if (!collector_->heap()->InNewSpace(object)) return; |
1435 | 1458 |
1436 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( | 1459 if (ObjectMarking::IsBlackOrGrey<MarkBit::NON_ATOMIC>( |
1437 object, MarkingState::External(object))) | 1460 object, MarkingState::External(object))) |
1438 return; | 1461 return; |
1439 | 1462 |
1440 Map* map = object->map(); | 1463 Map* map = object->map(); |
1441 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( | 1464 ObjectMarking::WhiteToBlack<MarkBit::NON_ATOMIC>( |
1442 object, MarkingState::External(object)); | 1465 object, MarkingState::External(object)); |
1443 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); | 1466 StaticYoungGenerationMarkingVisitor::IterateBody(map, object); |
1444 | 1467 |
1445 collector_->EmptyMarkingDeque(); | 1468 collector_->EmptyMarkingDeque(); |
1446 } | 1469 } |
1447 | 1470 |
1448 MinorMarkCompactCollector* collector_; | 1471 MinorMarkCompactCollector* collector_; |
1449 }; | 1472 }; |
1450 | 1473 |
1451 // Visitor class for marking heap roots. | 1474 // Visitor class for marking heap roots. |
1452 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor { | 1475 // TODO(ulan): Remove ObjectVisitor base class after fixing marking of |
1476 // the string table and the top optimized code. | |
1477 class MarkCompactCollector::RootMarkingVisitor : public ObjectVisitor, | |
1478 public RootVisitor { | |
1453 public: | 1479 public: |
1454 explicit RootMarkingVisitor(Heap* heap) | 1480 explicit RootMarkingVisitor(Heap* heap) |
1455 : collector_(heap->mark_compact_collector()) {} | 1481 : collector_(heap->mark_compact_collector()) {} |
1456 | 1482 |
1457 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } | 1483 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } |
1458 | 1484 |
1459 void VisitPointers(Object** start, Object** end) override { | 1485 void VisitPointers(Object** start, Object** end) override { |
1460 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 1486 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
1461 } | 1487 } |
1462 | 1488 |
1489 void VisitRootPointer(Root root, Object** p) override { | |
1490 MarkObjectByPointer(p); | |
1491 } | |
1492 | |
1493 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
1494 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | |
1495 } | |
1496 | |
1463 // Skip the weak next code link in a code object, which is visited in | 1497 // Skip the weak next code link in a code object, which is visited in |
1464 // ProcessTopOptimizedFrame. | 1498 // ProcessTopOptimizedFrame. |
1465 void VisitNextCodeLink(Object** p) override {} | 1499 void VisitNextCodeLink(Object** p) override {} |
1466 | 1500 |
1467 private: | 1501 private: |
1468 void MarkObjectByPointer(Object** p) { | 1502 void MarkObjectByPointer(Object** p) { |
1469 if (!(*p)->IsHeapObject()) return; | 1503 if (!(*p)->IsHeapObject()) return; |
1470 | 1504 |
1471 HeapObject* object = HeapObject::cast(*p); | 1505 HeapObject* object = HeapObject::cast(*p); |
1472 | 1506 |
(...skipping 11 matching lines...) Expand all Loading... | |
1484 MarkCompactMarkingVisitor::IterateBody(map, object); | 1518 MarkCompactMarkingVisitor::IterateBody(map, object); |
1485 | 1519 |
1486 // Mark all the objects reachable from the map and body. May leave | 1520 // Mark all the objects reachable from the map and body. May leave |
1487 // overflowed objects in the heap. | 1521 // overflowed objects in the heap. |
1488 collector_->EmptyMarkingDeque(); | 1522 collector_->EmptyMarkingDeque(); |
1489 } | 1523 } |
1490 | 1524 |
1491 MarkCompactCollector* collector_; | 1525 MarkCompactCollector* collector_; |
1492 }; | 1526 }; |
1493 | 1527 |
1494 | 1528 class InternalizedStringTableCleaner : public ObjectVisitor { |
1495 // Helper class for pruning the string table. | |
1496 template <bool finalize_external_strings, bool record_slots> | |
1497 class StringTableCleaner : public ObjectVisitor { | |
1498 public: | 1529 public: |
1499 StringTableCleaner(Heap* heap, HeapObject* table) | 1530 InternalizedStringTableCleaner(Heap* heap, HeapObject* table) |
1500 : heap_(heap), pointers_removed_(0), table_(table) { | 1531 : heap_(heap), pointers_removed_(0), table_(table) {} |
1501 DCHECK(!record_slots || table != nullptr); | |
1502 } | |
1503 | 1532 |
1504 void VisitPointers(Object** start, Object** end) override { | 1533 void VisitPointers(Object** start, Object** end) override { |
1505 // Visit all HeapObject pointers in [start, end). | 1534 // Visit all HeapObject pointers in [start, end). |
1506 MarkCompactCollector* collector = heap_->mark_compact_collector(); | 1535 MarkCompactCollector* collector = heap_->mark_compact_collector(); |
1536 Object* the_hole = heap_->the_hole_value(); | |
1507 for (Object** p = start; p < end; p++) { | 1537 for (Object** p = start; p < end; p++) { |
1508 Object* o = *p; | 1538 Object* o = *p; |
1509 if (o->IsHeapObject()) { | 1539 if (o->IsHeapObject()) { |
1510 HeapObject* heap_object = HeapObject::cast(o); | 1540 HeapObject* heap_object = HeapObject::cast(o); |
1511 if (ObjectMarking::IsWhite(heap_object, | 1541 if (ObjectMarking::IsWhite(heap_object, |
1512 MarkingState::Internal(heap_object))) { | 1542 MarkingState::Internal(heap_object))) { |
1513 if (finalize_external_strings) { | 1543 pointers_removed_++; |
1514 if (o->IsExternalString()) { | |
1515 heap_->FinalizeExternalString(String::cast(*p)); | |
1516 } else { | |
1517 // The original external string may have been internalized. | |
1518 DCHECK(o->IsThinString()); | |
1519 } | |
1520 } else { | |
1521 pointers_removed_++; | |
1522 } | |
1523 // Set the entry to the_hole_value (as deleted). | 1544 // Set the entry to the_hole_value (as deleted). |
1524 *p = heap_->the_hole_value(); | 1545 *p = the_hole; |
1525 } else if (record_slots) { | 1546 } else { |
1526 // StringTable contains only old space strings. | 1547 // StringTable contains only old space strings. |
1527 DCHECK(!heap_->InNewSpace(o)); | 1548 DCHECK(!heap_->InNewSpace(o)); |
1528 collector->RecordSlot(table_, p, o); | 1549 collector->RecordSlot(table_, p, o); |
1529 } | 1550 } |
1530 } | 1551 } |
1531 } | 1552 } |
1532 } | 1553 } |
1533 | 1554 |
1534 int PointersRemoved() { | 1555 int PointersRemoved() { |
1535 DCHECK(!finalize_external_strings); | |
1536 return pointers_removed_; | 1556 return pointers_removed_; |
1537 } | 1557 } |
1538 | 1558 |
1539 private: | 1559 private: |
1540 Heap* heap_; | 1560 Heap* heap_; |
1541 int pointers_removed_; | 1561 int pointers_removed_; |
1542 HeapObject* table_; | 1562 HeapObject* table_; |
1543 }; | 1563 }; |
1544 | 1564 |
1545 typedef StringTableCleaner<false, true> InternalizedStringTableCleaner; | 1565 class ExternalStringTableCleaner : public RootVisitor { |
1546 typedef StringTableCleaner<true, false> ExternalStringTableCleaner; | 1566 public: |
1567 explicit ExternalStringTableCleaner(Heap* heap) : heap_(heap) {} | |
1568 | |
1569 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
1570 // Visit all HeapObject pointers in [start, end). | |
1571 Object* the_hole = heap_->the_hole_value(); | |
1572 for (Object** p = start; p < end; p++) { | |
1573 Object* o = *p; | |
1574 if (o->IsHeapObject()) { | |
1575 HeapObject* heap_object = HeapObject::cast(o); | |
1576 if (ObjectMarking::IsWhite(heap_object, | |
1577 MarkingState::Internal(heap_object))) { | |
1578 if (o->IsExternalString()) { | |
1579 heap_->FinalizeExternalString(String::cast(*p)); | |
1580 } else { | |
1581 // The original external string may have been internalized. | |
1582 DCHECK(o->IsThinString()); | |
1583 } | |
1584 // Set the entry to the_hole_value (as deleted). | |
1585 *p = the_hole; | |
1586 } | |
1587 } | |
1588 } | |
1589 } | |
1590 | |
1591 private: | |
1592 Heap* heap_; | |
1593 }; | |
1547 | 1594 |
1548 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects | 1595 // Implementation of WeakObjectRetainer for mark compact GCs. All marked objects |
1549 // are retained. | 1596 // are retained. |
1550 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { | 1597 class MarkCompactWeakObjectRetainer : public WeakObjectRetainer { |
1551 public: | 1598 public: |
1552 virtual Object* RetainAs(Object* object) { | 1599 virtual Object* RetainAs(Object* object) { |
1553 HeapObject* heap_object = HeapObject::cast(object); | 1600 HeapObject* heap_object = HeapObject::cast(object); |
1554 DCHECK(!ObjectMarking::IsGrey(heap_object, | 1601 DCHECK(!ObjectMarking::IsGrey(heap_object, |
1555 MarkingState::Internal(heap_object))); | 1602 MarkingState::Internal(heap_object))); |
1556 if (ObjectMarking::IsBlack(heap_object, | 1603 if (ObjectMarking::IsBlack(heap_object, |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2133 while (marking_deque()->overflowed()) { | 2180 while (marking_deque()->overflowed()) { |
2134 RefillMarkingDeque(); | 2181 RefillMarkingDeque(); |
2135 EmptyMarkingDeque(); | 2182 EmptyMarkingDeque(); |
2136 } | 2183 } |
2137 DCHECK(marking_deque()->IsEmpty()); | 2184 DCHECK(marking_deque()->IsEmpty()); |
2138 } | 2185 } |
2139 | 2186 |
2140 // Mark all objects reachable (transitively) from objects on the marking | 2187 // Mark all objects reachable (transitively) from objects on the marking |
2141 // stack including references only considered in the atomic marking pause. | 2188 // stack including references only considered in the atomic marking pause. |
2142 void MarkCompactCollector::ProcessEphemeralMarking( | 2189 void MarkCompactCollector::ProcessEphemeralMarking( |
2143 ObjectVisitor* visitor, bool only_process_harmony_weak_collections) { | 2190 bool only_process_harmony_weak_collections) { |
2144 DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed()); | 2191 DCHECK(marking_deque()->IsEmpty() && !marking_deque()->overflowed()); |
2145 bool work_to_do = true; | 2192 bool work_to_do = true; |
2146 while (work_to_do) { | 2193 while (work_to_do) { |
2147 if (!only_process_harmony_weak_collections) { | 2194 if (!only_process_harmony_weak_collections) { |
2148 if (heap_->local_embedder_heap_tracer()->InUse()) { | 2195 if (heap_->local_embedder_heap_tracer()->InUse()) { |
2149 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING); | 2196 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_TRACING); |
2150 heap_->local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer(); | 2197 heap_->local_embedder_heap_tracer()->RegisterWrappersWithRemoteTracer(); |
2151 heap_->local_embedder_heap_tracer()->Trace( | 2198 heap_->local_embedder_heap_tracer()->Trace( |
2152 0, | 2199 0, |
2153 EmbedderHeapTracer::AdvanceTracingActions( | 2200 EmbedderHeapTracer::AdvanceTracingActions( |
2154 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); | 2201 EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION)); |
2155 } | 2202 } |
2156 } else { | 2203 } else { |
2157 // TODO(mlippautz): We currently do not trace through blink when | 2204 // TODO(mlippautz): We currently do not trace through blink when |
2158 // discovering new objects reachable from weak roots (that have been made | 2205 // discovering new objects reachable from weak roots (that have been made |
2159 // strong). This is a limitation of not having a separate handle type | 2206 // strong). This is a limitation of not having a separate handle type |
2160 // that doesn't require zapping before this phase. See crbug.com/668060. | 2207 // that doesn't require zapping before this phase. See crbug.com/668060. |
2161 heap_->local_embedder_heap_tracer()->ClearCachedWrappersToTrace(); | 2208 heap_->local_embedder_heap_tracer()->ClearCachedWrappersToTrace(); |
2162 } | 2209 } |
2163 ProcessWeakCollections(); | 2210 ProcessWeakCollections(); |
2164 work_to_do = !marking_deque()->IsEmpty(); | 2211 work_to_do = !marking_deque()->IsEmpty(); |
2165 ProcessMarkingDeque(); | 2212 ProcessMarkingDeque(); |
2166 } | 2213 } |
2167 CHECK(marking_deque()->IsEmpty()); | 2214 CHECK(marking_deque()->IsEmpty()); |
2168 CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace()); | 2215 CHECK_EQ(0, heap()->local_embedder_heap_tracer()->NumberOfWrappersToTrace()); |
2169 } | 2216 } |
2170 | 2217 |
2171 void MarkCompactCollector::ProcessTopOptimizedFrame(ObjectVisitor* visitor) { | 2218 void MarkCompactCollector::ProcessTopOptimizedFrame( |
2219 RootMarkingVisitor* visitor) { | |
2172 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); | 2220 for (StackFrameIterator it(isolate(), isolate()->thread_local_top()); |
2173 !it.done(); it.Advance()) { | 2221 !it.done(); it.Advance()) { |
2174 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { | 2222 if (it.frame()->type() == StackFrame::JAVA_SCRIPT) { |
2175 return; | 2223 return; |
2176 } | 2224 } |
2177 if (it.frame()->type() == StackFrame::OPTIMIZED) { | 2225 if (it.frame()->type() == StackFrame::OPTIMIZED) { |
2178 Code* code = it.frame()->LookupCode(); | 2226 Code* code = it.frame()->LookupCode(); |
2179 if (!code->CanDeoptAt(it.frame()->pc())) { | 2227 if (!code->CanDeoptAt(it.frame()->pc())) { |
2180 Code::BodyDescriptor::IterateBody(code, visitor); | 2228 Code::BodyDescriptor::IterateBody(code, visitor); |
2181 } | 2229 } |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2390 isolate(), type, addr, [this](Object** addr) { | 2438 isolate(), type, addr, [this](Object** addr) { |
2391 return CheckAndMarkObject(heap(), | 2439 return CheckAndMarkObject(heap(), |
2392 reinterpret_cast<Address>(addr)); | 2440 reinterpret_cast<Address>(addr)); |
2393 }); | 2441 }); |
2394 }); | 2442 }); |
2395 ProcessMarkingDeque(); | 2443 ProcessMarkingDeque(); |
2396 } | 2444 } |
2397 | 2445 |
2398 { | 2446 { |
2399 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK); | 2447 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_WEAK); |
2400 heap()->VisitEncounteredWeakCollections(&root_visitor); | 2448 heap()->IterateEncounteredWeakCollections(&root_visitor); |
2401 ProcessMarkingDeque(); | 2449 ProcessMarkingDeque(); |
2402 } | 2450 } |
2403 | 2451 |
2404 { | 2452 { |
2405 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES); | 2453 TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES); |
2406 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( | 2454 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( |
2407 &IsUnmarkedObject); | 2455 &IsUnmarkedObject); |
2408 isolate() | 2456 isolate() |
2409 ->global_handles() | 2457 ->global_handles() |
2410 ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>( | 2458 ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>( |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2491 | 2539 |
2492 { | 2540 { |
2493 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); | 2541 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE); |
2494 | 2542 |
2495 // The objects reachable from the roots are marked, yet unreachable | 2543 // The objects reachable from the roots are marked, yet unreachable |
2496 // objects are unmarked. Mark objects reachable due to host | 2544 // objects are unmarked. Mark objects reachable due to host |
2497 // application specific logic or through Harmony weak maps. | 2545 // application specific logic or through Harmony weak maps. |
2498 { | 2546 { |
2499 TRACE_GC(heap()->tracer(), | 2547 TRACE_GC(heap()->tracer(), |
2500 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); | 2548 GCTracer::Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL); |
2501 ProcessEphemeralMarking(&root_visitor, false); | 2549 ProcessEphemeralMarking(false); |
2502 } | 2550 } |
2503 | 2551 |
2504 // The objects reachable from the roots, weak maps or object groups | 2552 // The objects reachable from the roots, weak maps or object groups |
2505 // are marked. Objects pointed to only by weak global handles cannot be | 2553 // are marked. Objects pointed to only by weak global handles cannot be |
2506 // immediately reclaimed. Instead, we have to mark them as pending and mark | 2554 // immediately reclaimed. Instead, we have to mark them as pending and mark |
2507 // objects reachable from them. | 2555 // objects reachable from them. |
2508 // | 2556 // |
2509 // First we identify nonlive weak handles and mark them as pending | 2557 // First we identify nonlive weak handles and mark them as pending |
2510 // destruction. | 2558 // destruction. |
2511 { | 2559 { |
(...skipping 12 matching lines...) Expand all Loading... | |
2524 ProcessMarkingDeque(); | 2572 ProcessMarkingDeque(); |
2525 } | 2573 } |
2526 | 2574 |
2527 // Repeat Harmony weak maps marking to mark unmarked objects reachable from | 2575 // Repeat Harmony weak maps marking to mark unmarked objects reachable from |
2528 // the weak roots we just marked as pending destruction. | 2576 // the weak roots we just marked as pending destruction. |
2529 // | 2577 // |
2530 // We only process harmony collections, as all object groups have been fully | 2578 // We only process harmony collections, as all object groups have been fully |
2531 // processed and no weakly reachable node can discover new objects groups. | 2579 // processed and no weakly reachable node can discover new objects groups. |
2532 { | 2580 { |
2533 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); | 2581 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WEAK_CLOSURE_HARMONY); |
2534 ProcessEphemeralMarking(&root_visitor, true); | 2582 ProcessEphemeralMarking(true); |
2535 { | 2583 { |
2536 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_EPILOGUE); | 2584 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_MARK_WRAPPER_EPILOGUE); |
2537 heap()->local_embedder_heap_tracer()->TraceEpilogue(); | 2585 heap()->local_embedder_heap_tracer()->TraceEpilogue(); |
2538 } | 2586 } |
2539 } | 2587 } |
2540 } | 2588 } |
2541 } | 2589 } |
2542 | 2590 |
2543 | 2591 |
2544 void MarkCompactCollector::ClearNonLiveReferences() { | 2592 void MarkCompactCollector::ClearNonLiveReferences() { |
2545 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); | 2593 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR); |
2546 | 2594 |
2547 { | 2595 { |
2548 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_STRING_TABLE); | 2596 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_STRING_TABLE); |
2549 | 2597 |
2550 // Prune the string table removing all strings only pointed to by the | 2598 // Prune the string table removing all strings only pointed to by the |
2551 // string table. Cannot use string_table() here because the string | 2599 // string table. Cannot use string_table() here because the string |
2552 // table is marked. | 2600 // table is marked. |
2553 StringTable* string_table = heap()->string_table(); | 2601 StringTable* string_table = heap()->string_table(); |
2554 InternalizedStringTableCleaner internalized_visitor(heap(), string_table); | 2602 InternalizedStringTableCleaner internalized_visitor(heap(), string_table); |
2555 string_table->IterateElements(&internalized_visitor); | 2603 string_table->IterateElements(&internalized_visitor); |
2556 string_table->ElementsRemoved(internalized_visitor.PointersRemoved()); | 2604 string_table->ElementsRemoved(internalized_visitor.PointersRemoved()); |
2557 | 2605 |
2558 ExternalStringTableCleaner external_visitor(heap(), nullptr); | 2606 ExternalStringTableCleaner external_visitor(heap()); |
2559 heap()->external_string_table_.IterateAll(&external_visitor); | 2607 heap()->external_string_table_.IterateAll(&external_visitor); |
2560 heap()->external_string_table_.CleanUpAll(); | 2608 heap()->external_string_table_.CleanUpAll(); |
2561 } | 2609 } |
2562 | 2610 |
2563 { | 2611 { |
2564 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_LISTS); | 2612 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_LISTS); |
2565 // Process the weak references. | 2613 // Process the weak references. |
2566 MarkCompactWeakObjectRetainer mark_compact_object_retainer; | 2614 MarkCompactWeakObjectRetainer mark_compact_object_retainer; |
2567 heap()->ProcessAllWeakReferences(&mark_compact_object_retainer); | 2615 heap()->ProcessAllWeakReferences(&mark_compact_object_retainer); |
2568 } | 2616 } |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3019 reinterpret_cast<base::AtomicWord*>(slot), | 3067 reinterpret_cast<base::AtomicWord*>(slot), |
3020 reinterpret_cast<base::AtomicWord>(obj), | 3068 reinterpret_cast<base::AtomicWord>(obj), |
3021 reinterpret_cast<base::AtomicWord>(target)); | 3069 reinterpret_cast<base::AtomicWord>(target)); |
3022 DCHECK(!heap_obj->GetHeap()->InFromSpace(target)); | 3070 DCHECK(!heap_obj->GetHeap()->InFromSpace(target)); |
3023 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(target)); | 3071 DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(target)); |
3024 } | 3072 } |
3025 } | 3073 } |
3026 return REMOVE_SLOT; | 3074 return REMOVE_SLOT; |
3027 } | 3075 } |
3028 | 3076 |
3029 // Visitor for updating pointers from live objects in old spaces to new space. | 3077 // Visitor for updating root pointers and to-space pointers. |
3030 // It does not expect to encounter pointers to dead objects. | 3078 // It does not expect to encounter pointers to dead objects. |
3031 class PointersUpdatingVisitor : public ObjectVisitor { | 3079 // TODO(ulan): Remove code object specific functions. This visitor |
3080 // nevers visits code objects. | |
3081 class PointersUpdatingVisitor : public ObjectVisitor, public RootVisitor { | |
3032 public: | 3082 public: |
3033 void VisitPointer(Object** p) override { UpdateSlot(p); } | 3083 void VisitPointer(Object** p) override { UpdateSlot(p); } |
3034 | 3084 |
3035 void VisitPointers(Object** start, Object** end) override { | 3085 void VisitPointers(Object** start, Object** end) override { |
3036 for (Object** p = start; p < end; p++) UpdateSlot(p); | 3086 for (Object** p = start; p < end; p++) UpdateSlot(p); |
3037 } | 3087 } |
3038 | 3088 |
3089 void VisitRootPointer(Root root, Object** p) override { UpdateSlot(p); } | |
3090 | |
3091 void VisitRootPointers(Root root, Object** start, Object** end) override { | |
3092 for (Object** p = start; p < end; p++) UpdateSlot(p); | |
3093 } | |
3094 | |
3039 void VisitCell(RelocInfo* rinfo) override { | 3095 void VisitCell(RelocInfo* rinfo) override { |
3040 UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot); | 3096 UpdateTypedSlotHelper::UpdateCell(rinfo, UpdateSlot); |
3041 } | 3097 } |
3042 | 3098 |
3043 void VisitEmbeddedPointer(RelocInfo* rinfo) override { | 3099 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
3044 UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot); | 3100 UpdateTypedSlotHelper::UpdateEmbeddedPointer(rinfo, UpdateSlot); |
3045 } | 3101 } |
3046 | 3102 |
3047 void VisitCodeTarget(RelocInfo* rinfo) override { | 3103 void VisitCodeTarget(RelocInfo* rinfo) override { |
3048 UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot); | 3104 UpdateTypedSlotHelper::UpdateCodeTarget(rinfo, UpdateSlot); |
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3910 job.AddPage(page, std::make_pair(start, end)); | 3966 job.AddPage(page, std::make_pair(start, end)); |
3911 } | 3967 } |
3912 PointersUpdatingVisitor visitor; | 3968 PointersUpdatingVisitor visitor; |
3913 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; | 3969 int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1; |
3914 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); | 3970 job.Run(num_tasks, [&visitor](int i) { return &visitor; }); |
3915 } | 3971 } |
3916 | 3972 |
3917 void MarkCompactCollector::UpdatePointersAfterEvacuation() { | 3973 void MarkCompactCollector::UpdatePointersAfterEvacuation() { |
3918 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS); | 3974 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS); |
3919 | 3975 |
3920 PointersUpdatingVisitor updating_visitor; | |
3921 | 3976 |
3922 { | 3977 { |
3923 TRACE_GC(heap()->tracer(), | 3978 TRACE_GC(heap()->tracer(), |
3924 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW); | 3979 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW); |
3925 UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_); | 3980 UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_); |
3926 // Update roots. | 3981 // Update roots. |
3982 PointersUpdatingVisitor updating_visitor; | |
3927 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); | 3983 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
3928 UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_); | 3984 UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_); |
3929 } | 3985 } |
3930 | 3986 |
3931 { | 3987 { |
3932 Heap* heap = this->heap(); | 3988 Heap* heap = this->heap(); |
3933 TRACE_GC(heap->tracer(), | 3989 TRACE_GC(heap->tracer(), |
3934 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); | 3990 GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED); |
3935 UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_); | 3991 UpdatePointersInParallel<OLD_TO_OLD>(heap_, &page_parallel_job_semaphore_); |
3936 } | 3992 } |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4165 // The target is always in old space, we don't have to record the slot in | 4221 // The target is always in old space, we don't have to record the slot in |
4166 // the old-to-new remembered set. | 4222 // the old-to-new remembered set. |
4167 DCHECK(!heap()->InNewSpace(target)); | 4223 DCHECK(!heap()->InNewSpace(target)); |
4168 RecordRelocSlot(host, &rinfo, target); | 4224 RecordRelocSlot(host, &rinfo, target); |
4169 } | 4225 } |
4170 } | 4226 } |
4171 } | 4227 } |
4172 | 4228 |
4173 } // namespace internal | 4229 } // namespace internal |
4174 } // namespace v8 | 4230 } // namespace v8 |
OLD | NEW |