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

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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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