| 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/heap.h" | 5 #include "src/heap/heap.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
| 10 #include "src/ast/context-slot-cache.h" | 10 #include "src/ast/context-slot-cache.h" |
| (...skipping 1694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1705 // objects lie between a 'front' mark and a 'rear' mark that is | 1705 // objects lie between a 'front' mark and a 'rear' mark that is |
| 1706 // updated as a side effect of promoting an object. | 1706 // updated as a side effect of promoting an object. |
| 1707 // | 1707 // |
| 1708 // There is guaranteed to be enough room at the top of the to space | 1708 // There is guaranteed to be enough room at the top of the to space |
| 1709 // for the addresses of promoted objects: every object promoted | 1709 // for the addresses of promoted objects: every object promoted |
| 1710 // frees up its size in bytes from the top of the new space, and | 1710 // frees up its size in bytes from the top of the new space, and |
| 1711 // objects are at least one pointer in size. | 1711 // objects are at least one pointer in size. |
| 1712 Address new_space_front = new_space_->ToSpaceStart(); | 1712 Address new_space_front = new_space_->ToSpaceStart(); |
| 1713 promotion_queue_.Initialize(); | 1713 promotion_queue_.Initialize(); |
| 1714 | 1714 |
| 1715 ScavengeVisitor scavenge_visitor(this); | 1715 RootScavengeVisitor root_scavenge_visitor(this); |
| 1716 | 1716 |
| 1717 isolate()->global_handles()->IdentifyWeakUnmodifiedObjects( | 1717 isolate()->global_handles()->IdentifyWeakUnmodifiedObjects( |
| 1718 &IsUnmodifiedHeapObject); | 1718 &IsUnmodifiedHeapObject); |
| 1719 | 1719 |
| 1720 { | 1720 { |
| 1721 // Copy roots. | 1721 // Copy roots. |
| 1722 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_ROOTS); | 1722 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_ROOTS); |
| 1723 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1723 IterateRoots(&root_scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1724 } | 1724 } |
| 1725 | 1725 |
| 1726 { | 1726 { |
| 1727 // Copy objects reachable from the old generation. | 1727 // Copy objects reachable from the old generation. |
| 1728 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS); | 1728 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_OLD_TO_NEW_POINTERS); |
| 1729 RememberedSet<OLD_TO_NEW>::Iterate(this, [this](Address addr) { | 1729 RememberedSet<OLD_TO_NEW>::Iterate(this, [this](Address addr) { |
| 1730 return Scavenger::CheckAndScavengeObject(this, addr); | 1730 return Scavenger::CheckAndScavengeObject(this, addr); |
| 1731 }); | 1731 }); |
| 1732 | 1732 |
| 1733 RememberedSet<OLD_TO_NEW>::IterateTyped( | 1733 RememberedSet<OLD_TO_NEW>::IterateTyped( |
| 1734 this, [this](SlotType type, Address host_addr, Address addr) { | 1734 this, [this](SlotType type, Address host_addr, Address addr) { |
| 1735 return UpdateTypedSlotHelper::UpdateTypedSlot( | 1735 return UpdateTypedSlotHelper::UpdateTypedSlot( |
| 1736 isolate(), type, addr, [this](Object** addr) { | 1736 isolate(), type, addr, [this](Object** addr) { |
| 1737 // We expect that objects referenced by code are long living. | 1737 // We expect that objects referenced by code are long living. |
| 1738 // If we do not force promotion, then we need to clear | 1738 // If we do not force promotion, then we need to clear |
| 1739 // old_to_new slots in dead code objects after mark-compact. | 1739 // old_to_new slots in dead code objects after mark-compact. |
| 1740 return Scavenger::CheckAndScavengeObject( | 1740 return Scavenger::CheckAndScavengeObject( |
| 1741 this, reinterpret_cast<Address>(addr)); | 1741 this, reinterpret_cast<Address>(addr)); |
| 1742 }); | 1742 }); |
| 1743 }); | 1743 }); |
| 1744 } | 1744 } |
| 1745 | 1745 |
| 1746 { | 1746 { |
| 1747 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_WEAK); | 1747 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_WEAK); |
| 1748 // Copy objects reachable from the encountered weak collections list. | 1748 IterateEncounteredWeakCollections(&root_scavenge_visitor); |
| 1749 scavenge_visitor.VisitPointer(&encountered_weak_collections_); | |
| 1750 } | 1749 } |
| 1751 | 1750 |
| 1752 { | 1751 { |
| 1753 // Copy objects reachable from the code flushing candidates list. | 1752 // Copy objects reachable from the code flushing candidates list. |
| 1754 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_CODE_FLUSH_CANDIDATES); | 1753 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_CODE_FLUSH_CANDIDATES); |
| 1755 MarkCompactCollector* collector = mark_compact_collector(); | 1754 MarkCompactCollector* collector = mark_compact_collector(); |
| 1756 if (collector->is_code_flushing_enabled()) { | 1755 if (collector->is_code_flushing_enabled()) { |
| 1757 collector->code_flusher()->IteratePointersToFromSpace(&scavenge_visitor); | 1756 collector->code_flusher()->IteratePointersToFromSpace( |
| 1757 &root_scavenge_visitor); |
| 1758 } | 1758 } |
| 1759 } | 1759 } |
| 1760 | 1760 |
| 1761 { | 1761 { |
| 1762 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE); | 1762 TRACE_GC(tracer(), GCTracer::Scope::SCAVENGER_SEMISPACE); |
| 1763 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1763 new_space_front = DoScavenge(new_space_front); |
| 1764 } | 1764 } |
| 1765 | 1765 |
| 1766 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( | 1766 isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( |
| 1767 &IsUnscavengedHeapObject); | 1767 &IsUnscavengedHeapObject); |
| 1768 | 1768 |
| 1769 isolate() | 1769 isolate() |
| 1770 ->global_handles() | 1770 ->global_handles() |
| 1771 ->IterateNewSpaceWeakUnmodifiedRoots< | 1771 ->IterateNewSpaceWeakUnmodifiedRoots< |
| 1772 GlobalHandles::HANDLE_PHANTOM_NODES_VISIT_OTHERS>(&scavenge_visitor); | 1772 GlobalHandles::HANDLE_PHANTOM_NODES_VISIT_OTHERS>( |
| 1773 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1773 &root_scavenge_visitor); |
| 1774 new_space_front = DoScavenge(new_space_front); |
| 1774 | 1775 |
| 1775 UpdateNewSpaceReferencesInExternalStringTable( | 1776 UpdateNewSpaceReferencesInExternalStringTable( |
| 1776 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1777 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1777 | 1778 |
| 1778 promotion_queue_.Destroy(); | 1779 promotion_queue_.Destroy(); |
| 1779 | 1780 |
| 1780 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1781 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1781 | 1782 |
| 1782 ScavengeWeakObjectRetainer weak_object_retainer(this); | 1783 ScavengeWeakObjectRetainer weak_object_retainer(this); |
| 1783 ProcessYoungWeakReferences(&weak_object_retainer); | 1784 ProcessYoungWeakReferences(&weak_object_retainer); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 old_generation_survival_rate); | 1952 old_generation_survival_rate); |
| 1952 } | 1953 } |
| 1953 } | 1954 } |
| 1954 } | 1955 } |
| 1955 | 1956 |
| 1956 | 1957 |
| 1957 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { | 1958 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
| 1958 DisallowHeapAllocation no_allocation; | 1959 DisallowHeapAllocation no_allocation; |
| 1959 // All external strings are listed in the external string table. | 1960 // All external strings are listed in the external string table. |
| 1960 | 1961 |
| 1961 class ExternalStringTableVisitorAdapter : public ObjectVisitor { | 1962 class ExternalStringTableVisitorAdapter : public RootVisitor { |
| 1962 public: | 1963 public: |
| 1963 explicit ExternalStringTableVisitorAdapter( | 1964 explicit ExternalStringTableVisitorAdapter( |
| 1964 v8::ExternalResourceVisitor* visitor) | 1965 v8::ExternalResourceVisitor* visitor) |
| 1965 : visitor_(visitor) {} | 1966 : visitor_(visitor) {} |
| 1966 virtual void VisitPointers(Object** start, Object** end) { | 1967 virtual void VisitRootPointers(Root root, Object** start, Object** end) { |
| 1967 for (Object** p = start; p < end; p++) { | 1968 for (Object** p = start; p < end; p++) { |
| 1968 DCHECK((*p)->IsExternalString()); | 1969 DCHECK((*p)->IsExternalString()); |
| 1969 visitor_->VisitExternalString( | 1970 visitor_->VisitExternalString( |
| 1970 Utils::ToLocal(Handle<String>(String::cast(*p)))); | 1971 Utils::ToLocal(Handle<String>(String::cast(*p)))); |
| 1971 } | 1972 } |
| 1972 } | 1973 } |
| 1973 | 1974 |
| 1974 private: | 1975 private: |
| 1975 v8::ExternalResourceVisitor* visitor_; | 1976 v8::ExternalResourceVisitor* visitor_; |
| 1976 } external_string_table_visitor(visitor); | 1977 } external_string_table_visitor(visitor); |
| 1977 | 1978 |
| 1978 external_string_table_.IterateAll(&external_string_table_visitor); | 1979 external_string_table_.IterateAll(&external_string_table_visitor); |
| 1979 } | 1980 } |
| 1980 | 1981 |
| 1981 Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor, | 1982 Address Heap::DoScavenge(Address new_space_front) { |
| 1982 Address new_space_front) { | |
| 1983 do { | 1983 do { |
| 1984 SemiSpace::AssertValidRange(new_space_front, new_space_->top()); | 1984 SemiSpace::AssertValidRange(new_space_front, new_space_->top()); |
| 1985 // The addresses new_space_front and new_space_.top() define a | 1985 // The addresses new_space_front and new_space_.top() define a |
| 1986 // queue of unprocessed copied objects. Process them until the | 1986 // queue of unprocessed copied objects. Process them until the |
| 1987 // queue is empty. | 1987 // queue is empty. |
| 1988 while (new_space_front != new_space_->top()) { | 1988 while (new_space_front != new_space_->top()) { |
| 1989 if (!Page::IsAlignedToPageSize(new_space_front)) { | 1989 if (!Page::IsAlignedToPageSize(new_space_front)) { |
| 1990 HeapObject* object = HeapObject::FromAddress(new_space_front); | 1990 HeapObject* object = HeapObject::FromAddress(new_space_front); |
| 1991 new_space_front += | 1991 new_space_front += |
| 1992 StaticScavengeVisitor::IterateBody(object->map(), object); | 1992 StaticScavengeVisitor::IterateBody(object->map(), object); |
| (...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4765 #undef INTERNALIZED_STRING | 4765 #undef INTERNALIZED_STRING |
| 4766 #define STRING_TYPE(NAME, size, name, Name) case Heap::k##Name##MapRootIndex: | 4766 #define STRING_TYPE(NAME, size, name, Name) case Heap::k##Name##MapRootIndex: |
| 4767 STRING_TYPE_LIST(STRING_TYPE) | 4767 STRING_TYPE_LIST(STRING_TYPE) |
| 4768 #undef STRING_TYPE | 4768 #undef STRING_TYPE |
| 4769 return true; | 4769 return true; |
| 4770 default: | 4770 default: |
| 4771 return false; | 4771 return false; |
| 4772 } | 4772 } |
| 4773 } | 4773 } |
| 4774 | 4774 |
| 4775 | |
| 4776 #ifdef VERIFY_HEAP | 4775 #ifdef VERIFY_HEAP |
| 4777 void Heap::Verify() { | 4776 void Heap::Verify() { |
| 4778 CHECK(HasBeenSetUp()); | 4777 CHECK(HasBeenSetUp()); |
| 4779 HandleScope scope(isolate()); | 4778 HandleScope scope(isolate()); |
| 4780 | 4779 |
| 4781 // We have to wait here for the sweeper threads to have an iterable heap. | 4780 // We have to wait here for the sweeper threads to have an iterable heap. |
| 4782 mark_compact_collector()->EnsureSweepingCompleted(); | 4781 mark_compact_collector()->EnsureSweepingCompleted(); |
| 4783 | 4782 |
| 4784 VerifyPointersVisitor visitor; | 4783 VerifyPointersVisitor visitor; |
| 4785 IterateRoots(&visitor, VISIT_ONLY_STRONG); | 4784 IterateRoots(&visitor, VISIT_ONLY_STRONG); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4897 // TODO(hpayer): Implement a special promotion visitor that incorporates | 4896 // TODO(hpayer): Implement a special promotion visitor that incorporates |
| 4898 // regular visiting and IteratePromotedObjectPointers. | 4897 // regular visiting and IteratePromotedObjectPointers. |
| 4899 if (!was_marked_black) { | 4898 if (!was_marked_black) { |
| 4900 if (incremental_marking()->black_allocation()) { | 4899 if (incremental_marking()->black_allocation()) { |
| 4901 IncrementalMarking::MarkGrey(this, target->map()); | 4900 IncrementalMarking::MarkGrey(this, target->map()); |
| 4902 incremental_marking()->IterateBlackObject(target); | 4901 incremental_marking()->IterateBlackObject(target); |
| 4903 } | 4902 } |
| 4904 } | 4903 } |
| 4905 } | 4904 } |
| 4906 | 4905 |
| 4907 | 4906 void Heap::IterateRoots(RootVisitor* v, VisitMode mode) { |
| 4908 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { | |
| 4909 IterateStrongRoots(v, mode); | 4907 IterateStrongRoots(v, mode); |
| 4910 IterateWeakRoots(v, mode); | 4908 IterateWeakRoots(v, mode); |
| 4911 } | 4909 } |
| 4912 | 4910 |
| 4913 | 4911 void Heap::IterateWeakRoots(RootVisitor* v, VisitMode mode) { |
| 4914 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { | 4912 v->VisitRootPointer(Root::kStringTable, reinterpret_cast<Object**>( |
| 4915 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kStringTableRootIndex])); | 4913 &roots_[kStringTableRootIndex])); |
| 4916 v->Synchronize(VisitorSynchronization::kStringTable); | 4914 v->Synchronize(VisitorSynchronization::kStringTable); |
| 4917 if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { | 4915 if (mode != VISIT_ALL_IN_SCAVENGE && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
| 4918 // Scavenge collections have special processing for this. | 4916 // Scavenge collections have special processing for this. |
| 4919 external_string_table_.IterateAll(v); | 4917 external_string_table_.IterateAll(v); |
| 4920 } | 4918 } |
| 4921 v->Synchronize(VisitorSynchronization::kExternalStringsTable); | 4919 v->Synchronize(VisitorSynchronization::kExternalStringsTable); |
| 4922 } | 4920 } |
| 4923 | 4921 |
| 4924 | 4922 void Heap::IterateSmiRoots(RootVisitor* v) { |
| 4925 void Heap::IterateSmiRoots(ObjectVisitor* v) { | |
| 4926 // Acquire execution access since we are going to read stack limit values. | 4923 // Acquire execution access since we are going to read stack limit values. |
| 4927 ExecutionAccess access(isolate()); | 4924 ExecutionAccess access(isolate()); |
| 4928 v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]); | 4925 v->VisitRootPointers(Root::kSmiRootList, &roots_[kSmiRootsStart], |
| 4926 &roots_[kRootListLength]); |
| 4929 v->Synchronize(VisitorSynchronization::kSmiRootList); | 4927 v->Synchronize(VisitorSynchronization::kSmiRootList); |
| 4930 } | 4928 } |
| 4931 | 4929 |
| 4930 void Heap::IterateEncounteredWeakCollections(RootVisitor* visitor) { |
| 4931 visitor->VisitRootPointer(Root::kWeakCollections, |
| 4932 &encountered_weak_collections_); |
| 4933 } |
| 4934 |
| 4932 // We cannot avoid stale handles to left-trimmed objects, but can only make | 4935 // We cannot avoid stale handles to left-trimmed objects, but can only make |
| 4933 // sure all handles still needed are updated. Filter out a stale pointer | 4936 // sure all handles still needed are updated. Filter out a stale pointer |
| 4934 // and clear the slot to allow post processing of handles (needed because | 4937 // and clear the slot to allow post processing of handles (needed because |
| 4935 // the sweeper might actually free the underlying page). | 4938 // the sweeper might actually free the underlying page). |
| 4936 class FixStaleLeftTrimmedHandlesVisitor : public ObjectVisitor { | 4939 class FixStaleLeftTrimmedHandlesVisitor : public RootVisitor { |
| 4937 public: | 4940 public: |
| 4938 explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) { | 4941 explicit FixStaleLeftTrimmedHandlesVisitor(Heap* heap) : heap_(heap) { |
| 4939 USE(heap_); | 4942 USE(heap_); |
| 4940 } | 4943 } |
| 4941 | 4944 |
| 4942 void VisitPointer(Object** p) override { FixHandle(p); } | 4945 void VisitRootPointer(Root root, Object** p) override { FixHandle(p); } |
| 4943 | 4946 |
| 4944 void VisitPointers(Object** start, Object** end) override { | 4947 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 4945 for (Object** p = start; p < end; p++) FixHandle(p); | 4948 for (Object** p = start; p < end; p++) FixHandle(p); |
| 4946 } | 4949 } |
| 4947 | 4950 |
| 4948 private: | 4951 private: |
| 4949 inline void FixHandle(Object** p) { | 4952 inline void FixHandle(Object** p) { |
| 4950 HeapObject* current = reinterpret_cast<HeapObject*>(*p); | 4953 HeapObject* current = reinterpret_cast<HeapObject*>(*p); |
| 4951 if (!current->IsHeapObject()) return; | 4954 if (!current->IsHeapObject()) return; |
| 4952 const MapWord map_word = current->map_word(); | 4955 const MapWord map_word = current->map_word(); |
| 4953 if (!map_word.IsForwardingAddress() && current->IsFiller()) { | 4956 if (!map_word.IsForwardingAddress() && current->IsFiller()) { |
| 4954 #ifdef DEBUG | 4957 #ifdef DEBUG |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4966 } | 4969 } |
| 4967 DCHECK(current->IsFixedArrayBase()); | 4970 DCHECK(current->IsFixedArrayBase()); |
| 4968 #endif // DEBUG | 4971 #endif // DEBUG |
| 4969 *p = nullptr; | 4972 *p = nullptr; |
| 4970 } | 4973 } |
| 4971 } | 4974 } |
| 4972 | 4975 |
| 4973 Heap* heap_; | 4976 Heap* heap_; |
| 4974 }; | 4977 }; |
| 4975 | 4978 |
| 4976 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 4979 void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) { |
| 4977 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 4980 v->VisitRootPointers(Root::kStrongRootList, &roots_[0], |
| 4981 &roots_[kStrongRootListLength]); |
| 4978 v->Synchronize(VisitorSynchronization::kStrongRootList); | 4982 v->Synchronize(VisitorSynchronization::kStrongRootList); |
| 4979 // The serializer/deserializer iterates the root list twice, first to pick | 4983 // The serializer/deserializer iterates the root list twice, first to pick |
| 4980 // off immortal immovable roots to make sure they end up on the first page, | 4984 // off immortal immovable roots to make sure they end up on the first page, |
| 4981 // and then again for the rest. | 4985 // and then again for the rest. |
| 4982 if (mode == VISIT_ONLY_STRONG_ROOT_LIST) return; | 4986 if (mode == VISIT_ONLY_STRONG_ROOT_LIST) return; |
| 4983 | 4987 |
| 4984 isolate_->bootstrapper()->Iterate(v); | 4988 isolate_->bootstrapper()->Iterate(v); |
| 4985 v->Synchronize(VisitorSynchronization::kBootstrapper); | 4989 v->Synchronize(VisitorSynchronization::kBootstrapper); |
| 4986 isolate_->Iterate(v); | 4990 isolate_->Iterate(v); |
| 4987 v->Synchronize(VisitorSynchronization::kTop); | 4991 v->Synchronize(VisitorSynchronization::kTop); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5037 isolate_->eternal_handles()->IterateAllRoots(v); | 5041 isolate_->eternal_handles()->IterateAllRoots(v); |
| 5038 } | 5042 } |
| 5039 v->Synchronize(VisitorSynchronization::kEternalHandles); | 5043 v->Synchronize(VisitorSynchronization::kEternalHandles); |
| 5040 | 5044 |
| 5041 // Iterate over pointers being held by inactive threads. | 5045 // Iterate over pointers being held by inactive threads. |
| 5042 isolate_->thread_manager()->Iterate(v); | 5046 isolate_->thread_manager()->Iterate(v); |
| 5043 v->Synchronize(VisitorSynchronization::kThreadManager); | 5047 v->Synchronize(VisitorSynchronization::kThreadManager); |
| 5044 | 5048 |
| 5045 // Iterate over other strong roots (currently only identity maps). | 5049 // Iterate over other strong roots (currently only identity maps). |
| 5046 for (StrongRootsList* list = strong_roots_list_; list; list = list->next) { | 5050 for (StrongRootsList* list = strong_roots_list_; list; list = list->next) { |
| 5047 v->VisitPointers(list->start, list->end); | 5051 v->VisitRootPointers(Root::kStrongRoots, list->start, list->end); |
| 5048 } | 5052 } |
| 5049 v->Synchronize(VisitorSynchronization::kStrongRoots); | 5053 v->Synchronize(VisitorSynchronization::kStrongRoots); |
| 5050 | 5054 |
| 5051 // Iterate over the partial snapshot cache unless serializing. | 5055 // Iterate over the partial snapshot cache unless serializing. |
| 5052 if (mode != VISIT_ONLY_STRONG_FOR_SERIALIZATION) { | 5056 if (mode != VISIT_ONLY_STRONG_FOR_SERIALIZATION) { |
| 5053 SerializerDeserializer::Iterate(isolate_, v); | 5057 SerializerDeserializer::Iterate(isolate_, v); |
| 5054 } | 5058 } |
| 5055 // We don't do a v->Synchronize call here, because in debug mode that will | 5059 // We don't do a v->Synchronize call here, because in debug mode that will |
| 5056 // output a flag to the snapshot. However at this point the serializer and | 5060 // output a flag to the snapshot. However at this point the serializer and |
| 5057 // deserializer are deliberately a little unsynchronized (see above) so the | 5061 // deserializer are deliberately a little unsynchronized (see above) so the |
| (...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5930 } | 5934 } |
| 5931 if (new_length != length) retained_maps->SetLength(new_length); | 5935 if (new_length != length) retained_maps->SetLength(new_length); |
| 5932 } | 5936 } |
| 5933 | 5937 |
| 5934 void Heap::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) { | 5938 void Heap::FatalProcessOutOfMemory(const char* location, bool is_heap_oom) { |
| 5935 v8::internal::V8::FatalProcessOutOfMemory(location, is_heap_oom); | 5939 v8::internal::V8::FatalProcessOutOfMemory(location, is_heap_oom); |
| 5936 } | 5940 } |
| 5937 | 5941 |
| 5938 #ifdef DEBUG | 5942 #ifdef DEBUG |
| 5939 | 5943 |
| 5940 class PrintHandleVisitor : public ObjectVisitor { | 5944 class PrintHandleVisitor : public RootVisitor { |
| 5941 public: | 5945 public: |
| 5942 void VisitPointers(Object** start, Object** end) override { | 5946 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 5943 for (Object** p = start; p < end; p++) | 5947 for (Object** p = start; p < end; p++) |
| 5944 PrintF(" handle %p to %p\n", reinterpret_cast<void*>(p), | 5948 PrintF(" handle %p to %p\n", reinterpret_cast<void*>(p), |
| 5945 reinterpret_cast<void*>(*p)); | 5949 reinterpret_cast<void*>(*p)); |
| 5946 } | 5950 } |
| 5947 }; | 5951 }; |
| 5948 | 5952 |
| 5949 | 5953 |
| 5950 void Heap::PrintHandles() { | 5954 void Heap::PrintHandles() { |
| 5951 PrintF("Handles:\n"); | 5955 PrintF("Handles:\n"); |
| 5952 PrintHandleVisitor v; | 5956 PrintHandleVisitor v; |
| 5953 isolate_->handle_scope_implementer()->Iterate(&v); | 5957 isolate_->handle_scope_implementer()->Iterate(&v); |
| 5954 } | 5958 } |
| 5955 | 5959 |
| 5956 #endif | 5960 #endif |
| 5957 | 5961 |
| 5958 class CheckHandleCountVisitor : public ObjectVisitor { | 5962 class CheckHandleCountVisitor : public RootVisitor { |
| 5959 public: | 5963 public: |
| 5960 CheckHandleCountVisitor() : handle_count_(0) {} | 5964 CheckHandleCountVisitor() : handle_count_(0) {} |
| 5961 ~CheckHandleCountVisitor() override { | 5965 ~CheckHandleCountVisitor() override { |
| 5962 CHECK(handle_count_ < HandleScope::kCheckHandleThreshold); | 5966 CHECK(handle_count_ < HandleScope::kCheckHandleThreshold); |
| 5963 } | 5967 } |
| 5964 void VisitPointers(Object** start, Object** end) override { | 5968 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 5965 handle_count_ += end - start; | 5969 handle_count_ += end - start; |
| 5966 } | 5970 } |
| 5967 | 5971 |
| 5968 private: | 5972 private: |
| 5969 ptrdiff_t handle_count_; | 5973 ptrdiff_t handle_count_; |
| 5970 }; | 5974 }; |
| 5971 | 5975 |
| 5972 | 5976 |
| 5973 void Heap::CheckHandleCount() { | 5977 void Heap::CheckHandleCount() { |
| 5974 CheckHandleCountVisitor v; | 5978 CheckHandleCountVisitor v; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6110 ~UnreachableObjectsFilter() { | 6114 ~UnreachableObjectsFilter() { |
| 6111 heap_->mark_compact_collector()->ClearMarkbits(); | 6115 heap_->mark_compact_collector()->ClearMarkbits(); |
| 6112 } | 6116 } |
| 6113 | 6117 |
| 6114 bool SkipObject(HeapObject* object) { | 6118 bool SkipObject(HeapObject* object) { |
| 6115 if (object->IsFiller()) return true; | 6119 if (object->IsFiller()) return true; |
| 6116 return ObjectMarking::IsWhite(object, MarkingState::Internal(object)); | 6120 return ObjectMarking::IsWhite(object, MarkingState::Internal(object)); |
| 6117 } | 6121 } |
| 6118 | 6122 |
| 6119 private: | 6123 private: |
| 6120 class MarkingVisitor : public ObjectVisitor { | 6124 class MarkingVisitor : public ObjectVisitor, public RootVisitor { |
| 6121 public: | 6125 public: |
| 6122 MarkingVisitor() : marking_stack_(10) {} | 6126 MarkingVisitor() : marking_stack_(10) {} |
| 6123 | 6127 |
| 6124 void VisitPointers(Object** start, Object** end) override { | 6128 void VisitPointers(Object** start, Object** end) override { |
| 6129 MarkPointers(start, end); |
| 6130 } |
| 6131 |
| 6132 void VisitRootPointers(Root root, Object** start, Object** end) override { |
| 6133 MarkPointers(start, end); |
| 6134 } |
| 6135 |
| 6136 void TransitiveClosure() { |
| 6137 while (!marking_stack_.is_empty()) { |
| 6138 HeapObject* obj = marking_stack_.RemoveLast(); |
| 6139 obj->Iterate(this); |
| 6140 } |
| 6141 } |
| 6142 |
| 6143 private: |
| 6144 void MarkPointers(Object** start, Object** end) { |
| 6125 for (Object** p = start; p < end; p++) { | 6145 for (Object** p = start; p < end; p++) { |
| 6126 if (!(*p)->IsHeapObject()) continue; | 6146 if (!(*p)->IsHeapObject()) continue; |
| 6127 HeapObject* obj = HeapObject::cast(*p); | 6147 HeapObject* obj = HeapObject::cast(*p); |
| 6128 // Use Marking instead of ObjectMarking to avoid adjusting live bytes | 6148 // Use Marking instead of ObjectMarking to avoid adjusting live bytes |
| 6129 // counter. | 6149 // counter. |
| 6130 MarkBit mark_bit = | 6150 MarkBit mark_bit = |
| 6131 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj)); | 6151 ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj)); |
| 6132 if (Marking::IsWhite(mark_bit)) { | 6152 if (Marking::IsWhite(mark_bit)) { |
| 6133 Marking::WhiteToBlack(mark_bit); | 6153 Marking::WhiteToBlack(mark_bit); |
| 6134 marking_stack_.Add(obj); | 6154 marking_stack_.Add(obj); |
| 6135 } | 6155 } |
| 6136 } | 6156 } |
| 6137 } | 6157 } |
| 6138 | |
| 6139 void TransitiveClosure() { | |
| 6140 while (!marking_stack_.is_empty()) { | |
| 6141 HeapObject* obj = marking_stack_.RemoveLast(); | |
| 6142 obj->Iterate(this); | |
| 6143 } | |
| 6144 } | |
| 6145 | |
| 6146 private: | |
| 6147 List<HeapObject*> marking_stack_; | 6158 List<HeapObject*> marking_stack_; |
| 6148 }; | 6159 }; |
| 6149 | 6160 |
| 6150 void MarkReachableObjects() { | 6161 void MarkReachableObjects() { |
| 6151 MarkingVisitor visitor; | 6162 MarkingVisitor visitor; |
| 6152 heap_->IterateRoots(&visitor, VISIT_ALL); | 6163 heap_->IterateRoots(&visitor, VISIT_ALL); |
| 6153 visitor.TransitiveClosure(); | 6164 visitor.TransitiveClosure(); |
| 6154 } | 6165 } |
| 6155 | 6166 |
| 6156 Heap* heap_; | 6167 Heap* heap_; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6404 } | 6415 } |
| 6405 | 6416 |
| 6406 | 6417 |
| 6407 // static | 6418 // static |
| 6408 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6419 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6409 return StaticVisitorBase::GetVisitorId(map); | 6420 return StaticVisitorBase::GetVisitorId(map); |
| 6410 } | 6421 } |
| 6411 | 6422 |
| 6412 } // namespace internal | 6423 } // namespace internal |
| 6413 } // namespace v8 | 6424 } // namespace v8 |
| OLD | NEW |