Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/heap/mark-compact.cc

Issue 2801073006: Decouple root visitors from object visitors. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/object-stats.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/object-stats.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698