| 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 |