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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 pending_sweeper_tasks_semaphore_(0), | 67 pending_sweeper_tasks_semaphore_(0), |
68 pending_compaction_tasks_semaphore_(0), | 68 pending_compaction_tasks_semaphore_(0), |
69 concurrent_compaction_tasks_active_(0) { | 69 concurrent_compaction_tasks_active_(0) { |
70 } | 70 } |
71 | 71 |
72 #ifdef VERIFY_HEAP | 72 #ifdef VERIFY_HEAP |
73 class VerifyMarkingVisitor : public ObjectVisitor { | 73 class VerifyMarkingVisitor : public ObjectVisitor { |
74 public: | 74 public: |
75 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} | 75 explicit VerifyMarkingVisitor(Heap* heap) : heap_(heap) {} |
76 | 76 |
77 void VisitPointers(Object** start, Object** end) { | 77 void VisitPointers(Object** start, Object** end) override { |
78 for (Object** current = start; current < end; current++) { | 78 for (Object** current = start; current < end; current++) { |
79 if ((*current)->IsHeapObject()) { | 79 if ((*current)->IsHeapObject()) { |
80 HeapObject* object = HeapObject::cast(*current); | 80 HeapObject* object = HeapObject::cast(*current); |
81 CHECK(heap_->mark_compact_collector()->IsMarked(object)); | 81 CHECK(heap_->mark_compact_collector()->IsMarked(object)); |
82 } | 82 } |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 void VisitEmbeddedPointer(RelocInfo* rinfo) { | 86 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
87 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 87 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
88 if (!rinfo->host()->IsWeakObject(rinfo->target_object())) { | 88 if (!rinfo->host()->IsWeakObject(rinfo->target_object())) { |
89 Object* p = rinfo->target_object(); | 89 Object* p = rinfo->target_object(); |
90 VisitPointer(&p); | 90 VisitPointer(&p); |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 void VisitCell(RelocInfo* rinfo) { | 94 void VisitCell(RelocInfo* rinfo) override { |
95 Code* code = rinfo->host(); | 95 Code* code = rinfo->host(); |
96 DCHECK(rinfo->rmode() == RelocInfo::CELL); | 96 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
97 if (!code->IsWeakObject(rinfo->target_cell())) { | 97 if (!code->IsWeakObject(rinfo->target_cell())) { |
98 ObjectVisitor::VisitCell(rinfo); | 98 ObjectVisitor::VisitCell(rinfo); |
99 } | 99 } |
100 } | 100 } |
101 | 101 |
102 private: | 102 private: |
103 Heap* heap_; | 103 Heap* heap_; |
104 }; | 104 }; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 obj->Iterate(&visitor); | 161 obj->Iterate(&visitor); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 165 heap->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
166 } | 166 } |
167 | 167 |
168 | 168 |
169 class VerifyEvacuationVisitor : public ObjectVisitor { | 169 class VerifyEvacuationVisitor : public ObjectVisitor { |
170 public: | 170 public: |
171 void VisitPointers(Object** start, Object** end) { | 171 void VisitPointers(Object** start, Object** end) override { |
172 for (Object** current = start; current < end; current++) { | 172 for (Object** current = start; current < end; current++) { |
173 if ((*current)->IsHeapObject()) { | 173 if ((*current)->IsHeapObject()) { |
174 HeapObject* object = HeapObject::cast(*current); | 174 HeapObject* object = HeapObject::cast(*current); |
175 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); | 175 CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(object)); |
176 } | 176 } |
177 } | 177 } |
178 } | 178 } |
179 }; | 179 }; |
180 | 180 |
181 | 181 |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 private: | 1421 private: |
1422 MarkCompactCollector* collector_; | 1422 MarkCompactCollector* collector_; |
1423 }; | 1423 }; |
1424 | 1424 |
1425 | 1425 |
1426 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 1426 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { |
1427 public: | 1427 public: |
1428 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 1428 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) |
1429 : collector_(collector) {} | 1429 : collector_(collector) {} |
1430 | 1430 |
1431 void VisitPointers(Object** start, Object** end) { | 1431 void VisitPointers(Object** start, Object** end) override { |
1432 for (Object** p = start; p < end; p++) VisitPointer(p); | 1432 for (Object** p = start; p < end; p++) VisitPointer(p); |
1433 } | 1433 } |
1434 | 1434 |
1435 void VisitPointer(Object** slot) { | 1435 void VisitPointer(Object** slot) override { |
1436 Object* obj = *slot; | 1436 Object* obj = *slot; |
1437 if (obj->IsSharedFunctionInfo()) { | 1437 if (obj->IsSharedFunctionInfo()) { |
1438 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 1438 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); |
1439 MarkBit shared_mark = Marking::MarkBitFrom(shared); | 1439 MarkBit shared_mark = Marking::MarkBitFrom(shared); |
1440 MarkBit code_mark = Marking::MarkBitFrom(shared->code()); | 1440 MarkBit code_mark = Marking::MarkBitFrom(shared->code()); |
1441 collector_->MarkObject(shared->code(), code_mark); | 1441 collector_->MarkObject(shared->code(), code_mark); |
1442 collector_->MarkObject(shared, shared_mark); | 1442 collector_->MarkObject(shared, shared_mark); |
1443 } | 1443 } |
1444 } | 1444 } |
1445 | 1445 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 ProcessMarkingDeque(); | 1495 ProcessMarkingDeque(); |
1496 } | 1496 } |
1497 | 1497 |
1498 | 1498 |
1499 // Visitor class for marking heap roots. | 1499 // Visitor class for marking heap roots. |
1500 class RootMarkingVisitor : public ObjectVisitor { | 1500 class RootMarkingVisitor : public ObjectVisitor { |
1501 public: | 1501 public: |
1502 explicit RootMarkingVisitor(Heap* heap) | 1502 explicit RootMarkingVisitor(Heap* heap) |
1503 : collector_(heap->mark_compact_collector()) {} | 1503 : collector_(heap->mark_compact_collector()) {} |
1504 | 1504 |
1505 void VisitPointer(Object** p) { MarkObjectByPointer(p); } | 1505 void VisitPointer(Object** p) override { MarkObjectByPointer(p); } |
1506 | 1506 |
1507 void VisitPointers(Object** start, Object** end) { | 1507 void VisitPointers(Object** start, Object** end) override { |
1508 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 1508 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
1509 } | 1509 } |
1510 | 1510 |
1511 // Skip the weak next code link in a code object, which is visited in | 1511 // Skip the weak next code link in a code object, which is visited in |
1512 // ProcessTopOptimizedFrame. | 1512 // ProcessTopOptimizedFrame. |
1513 void VisitNextCodeLink(Object** p) {} | 1513 void VisitNextCodeLink(Object** p) override {} |
1514 | 1514 |
1515 private: | 1515 private: |
1516 void MarkObjectByPointer(Object** p) { | 1516 void MarkObjectByPointer(Object** p) { |
1517 if (!(*p)->IsHeapObject()) return; | 1517 if (!(*p)->IsHeapObject()) return; |
1518 | 1518 |
1519 // Replace flat cons strings in place. | 1519 // Replace flat cons strings in place. |
1520 HeapObject* object = HeapObject::cast(*p); | 1520 HeapObject* object = HeapObject::cast(*p); |
1521 MarkBit mark_bit = Marking::MarkBitFrom(object); | 1521 MarkBit mark_bit = Marking::MarkBitFrom(object); |
1522 if (Marking::IsBlackOrGrey(mark_bit)) return; | 1522 if (Marking::IsBlackOrGrey(mark_bit)) return; |
1523 | 1523 |
(...skipping 14 matching lines...) Expand all Loading... |
1538 MarkCompactCollector* collector_; | 1538 MarkCompactCollector* collector_; |
1539 }; | 1539 }; |
1540 | 1540 |
1541 | 1541 |
1542 // Helper class for pruning the string table. | 1542 // Helper class for pruning the string table. |
1543 template <bool finalize_external_strings> | 1543 template <bool finalize_external_strings> |
1544 class StringTableCleaner : public ObjectVisitor { | 1544 class StringTableCleaner : public ObjectVisitor { |
1545 public: | 1545 public: |
1546 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {} | 1546 explicit StringTableCleaner(Heap* heap) : heap_(heap), pointers_removed_(0) {} |
1547 | 1547 |
1548 virtual void VisitPointers(Object** start, Object** end) { | 1548 void VisitPointers(Object** start, Object** end) override { |
1549 // Visit all HeapObject pointers in [start, end). | 1549 // Visit all HeapObject pointers in [start, end). |
1550 for (Object** p = start; p < end; p++) { | 1550 for (Object** p = start; p < end; p++) { |
1551 Object* o = *p; | 1551 Object* o = *p; |
1552 if (o->IsHeapObject() && | 1552 if (o->IsHeapObject() && |
1553 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(o)))) { | 1553 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(o)))) { |
1554 if (finalize_external_strings) { | 1554 if (finalize_external_strings) { |
1555 DCHECK(o->IsExternalString()); | 1555 DCHECK(o->IsExternalString()); |
1556 heap_->FinalizeExternalString(String::cast(*p)); | 1556 heap_->FinalizeExternalString(String::cast(*p)); |
1557 } else { | 1557 } else { |
1558 pointers_removed_++; | 1558 pointers_removed_++; |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 } | 2866 } |
2867 } | 2867 } |
2868 | 2868 |
2869 | 2869 |
2870 // Visitor for updating pointers from live objects in old spaces to new space. | 2870 // Visitor for updating pointers from live objects in old spaces to new space. |
2871 // It does not expect to encounter pointers to dead objects. | 2871 // It does not expect to encounter pointers to dead objects. |
2872 class PointersUpdatingVisitor : public ObjectVisitor { | 2872 class PointersUpdatingVisitor : public ObjectVisitor { |
2873 public: | 2873 public: |
2874 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {} | 2874 explicit PointersUpdatingVisitor(Heap* heap) : heap_(heap) {} |
2875 | 2875 |
2876 void VisitPointer(Object** p) { UpdatePointer(p); } | 2876 void VisitPointer(Object** p) override { UpdatePointer(p); } |
2877 | 2877 |
2878 void VisitPointers(Object** start, Object** end) { | 2878 void VisitPointers(Object** start, Object** end) override { |
2879 for (Object** p = start; p < end; p++) UpdatePointer(p); | 2879 for (Object** p = start; p < end; p++) UpdatePointer(p); |
2880 } | 2880 } |
2881 | 2881 |
2882 void VisitCell(RelocInfo* rinfo) { | 2882 void VisitCell(RelocInfo* rinfo) override { |
2883 DCHECK(rinfo->rmode() == RelocInfo::CELL); | 2883 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
2884 Object* cell = rinfo->target_cell(); | 2884 Object* cell = rinfo->target_cell(); |
2885 Object* old_cell = cell; | 2885 Object* old_cell = cell; |
2886 VisitPointer(&cell); | 2886 VisitPointer(&cell); |
2887 if (cell != old_cell) { | 2887 if (cell != old_cell) { |
2888 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell)); | 2888 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell)); |
2889 } | 2889 } |
2890 } | 2890 } |
2891 | 2891 |
2892 void VisitEmbeddedPointer(RelocInfo* rinfo) { | 2892 void VisitEmbeddedPointer(RelocInfo* rinfo) override { |
2893 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 2893 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
2894 Object* target = rinfo->target_object(); | 2894 Object* target = rinfo->target_object(); |
2895 Object* old_target = target; | 2895 Object* old_target = target; |
2896 VisitPointer(&target); | 2896 VisitPointer(&target); |
2897 // Avoid unnecessary changes that might unnecessary flush the instruction | 2897 // Avoid unnecessary changes that might unnecessary flush the instruction |
2898 // cache. | 2898 // cache. |
2899 if (target != old_target) { | 2899 if (target != old_target) { |
2900 rinfo->set_target_object(target); | 2900 rinfo->set_target_object(target); |
2901 } | 2901 } |
2902 } | 2902 } |
2903 | 2903 |
2904 void VisitCodeTarget(RelocInfo* rinfo) { | 2904 void VisitCodeTarget(RelocInfo* rinfo) override { |
2905 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); | 2905 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); |
2906 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 2906 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
2907 Object* old_target = target; | 2907 Object* old_target = target; |
2908 VisitPointer(&target); | 2908 VisitPointer(&target); |
2909 if (target != old_target) { | 2909 if (target != old_target) { |
2910 rinfo->set_target_address(Code::cast(target)->instruction_start()); | 2910 rinfo->set_target_address(Code::cast(target)->instruction_start()); |
2911 } | 2911 } |
2912 } | 2912 } |
2913 | 2913 |
2914 void VisitCodeAgeSequence(RelocInfo* rinfo) { | 2914 void VisitCodeAgeSequence(RelocInfo* rinfo) override { |
2915 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); | 2915 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); |
2916 Object* stub = rinfo->code_age_stub(); | 2916 Object* stub = rinfo->code_age_stub(); |
2917 DCHECK(stub != NULL); | 2917 DCHECK(stub != NULL); |
2918 VisitPointer(&stub); | 2918 VisitPointer(&stub); |
2919 if (stub != rinfo->code_age_stub()) { | 2919 if (stub != rinfo->code_age_stub()) { |
2920 rinfo->set_code_age_stub(Code::cast(stub)); | 2920 rinfo->set_code_age_stub(Code::cast(stub)); |
2921 } | 2921 } |
2922 } | 2922 } |
2923 | 2923 |
2924 void VisitDebugTarget(RelocInfo* rinfo) { | 2924 void VisitDebugTarget(RelocInfo* rinfo) override { |
2925 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 2925 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
2926 rinfo->IsPatchedDebugBreakSlotSequence()); | 2926 rinfo->IsPatchedDebugBreakSlotSequence()); |
2927 Object* target = | 2927 Object* target = |
2928 Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); | 2928 Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); |
2929 VisitPointer(&target); | 2929 VisitPointer(&target); |
2930 rinfo->set_debug_call_address(Code::cast(target)->instruction_start()); | 2930 rinfo->set_debug_call_address(Code::cast(target)->instruction_start()); |
2931 } | 2931 } |
2932 | 2932 |
2933 static inline void UpdateSlot(Heap* heap, Object** slot) { | 2933 static inline void UpdateSlot(Heap* heap, Object** slot) { |
2934 Object* obj = reinterpret_cast<Object*>( | 2934 Object* obj = reinterpret_cast<Object*>( |
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4630 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4630 MarkBit mark_bit = Marking::MarkBitFrom(host); |
4631 if (Marking::IsBlack(mark_bit)) { | 4631 if (Marking::IsBlack(mark_bit)) { |
4632 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4632 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
4633 RecordRelocSlot(&rinfo, target); | 4633 RecordRelocSlot(&rinfo, target); |
4634 } | 4634 } |
4635 } | 4635 } |
4636 } | 4636 } |
4637 | 4637 |
4638 } // namespace internal | 4638 } // namespace internal |
4639 } // namespace v8 | 4639 } // namespace v8 |
OLD | NEW |