Chromium Code Reviews| 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 |