diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 934e3baa49..0afdad5848 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -5739,10 +5739,8 @@ V8_DECLARE_ONCE(initialize_gc_once); static void InitializeGCOnce() { Scavenger::Initialize(); - MarkCompactCollector::Initialize(); } - bool Heap::SetUp() { #ifdef DEBUG allocation_timeout_ = FLAG_gc_interval; diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc index 3933d0a39b..6988383f73 100644 --- a/src/heap/incremental-marking.cc +++ b/src/heap/incremental-marking.cc @@ -213,41 +213,41 @@ void IncrementalMarking::NotifyLeftTrimming(HeapObject* from, HeapObject* to) { } } -class IncrementalMarkingMarkingVisitor - : public StaticMarkingVisitor { +class IncrementalMarkingMarkingVisitor final + : public MarkingVisitor { public: - static void Initialize() { - StaticMarkingVisitor::Initialize(); - table_.Register(kVisitFixedArray, &VisitFixedArrayIncremental); - table_.Register(kVisitNativeContext, &VisitNativeContextIncremental); - } + typedef MarkingVisitor Parent; static const int kProgressBarScanningChunk = 32 * 1024; - static void VisitFixedArrayIncremental(Map* map, HeapObject* object) { + explicit IncrementalMarkingMarkingVisitor(MarkCompactCollector* collector) + : MarkingVisitor(collector->heap(), + collector), + incremental_marking_(collector->heap()->incremental_marking()) {} + + V8_INLINE int VisitFixedArray(Map* map, FixedArray* object) { MemoryChunk* chunk = MemoryChunk::FromAddress(object->address()); + int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { DCHECK(!FLAG_use_marking_progress_bar || chunk->owner()->identity() == LO_SPACE); - Heap* heap = map->GetHeap(); // When using a progress bar for large fixed arrays, scan only a chunk of // the array and try to push it onto the marking deque again until it is // fully scanned. Fall back to scanning it through to the end in case this // fails because of a full deque. - int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); int start_offset = Max(FixedArray::BodyDescriptor::kStartOffset, chunk->progress_bar()); if (start_offset < object_size) { #ifdef CONCURRENT_MARKING - heap->incremental_marking()->marking_worklist()->PushBailout(object); + incremental_marking_->marking_worklist()->PushBailout(object); #else if (ObjectMarking::IsGrey( - object, heap->incremental_marking()->marking_state(object))) { - heap->incremental_marking()->marking_worklist()->Push(object); + object, incremental_marking_->marking_state(object))) { + incremental_marking_->marking_worklist()->Push(object); } else { DCHECK(ObjectMarking::IsBlack( - object, heap->incremental_marking()->marking_state(object))); - heap->mark_compact_collector()->PushBlack(object); + object, incremental_marking_->marking_state(object))); + collector_->PushBlack(object); } #endif int end_offset = @@ -255,28 +255,25 @@ class IncrementalMarkingMarkingVisitor int already_scanned_offset = start_offset; bool scan_until_end = false; do { - VisitPointers(heap, object, - HeapObject::RawField(object, start_offset), + VisitPointers(object, HeapObject::RawField(object, start_offset), HeapObject::RawField(object, end_offset)); start_offset = end_offset; end_offset = Min(object_size, end_offset + kProgressBarScanningChunk); - scan_until_end = - heap->incremental_marking()->marking_worklist()->IsFull(); + scan_until_end = incremental_marking_->marking_worklist()->IsFull(); } while (scan_until_end && start_offset < object_size); chunk->set_progress_bar(start_offset); if (start_offset < object_size) { - heap->incremental_marking()->NotifyIncompleteScanOfObject( + incremental_marking_->NotifyIncompleteScanOfObject( object_size - (start_offset - already_scanned_offset)); } } } else { - FixedArrayVisitor::Visit(map, object); + FixedArray::BodyDescriptor::IterateBody(object, object_size, this); } + return object_size; } - static void VisitNativeContextIncremental(Map* map, HeapObject* object) { - Context* context = Context::cast(object); - + V8_INLINE int VisitNativeContext(Map* map, Context* context) { // We will mark cache black with a separate pass when we finish marking. // Note that GC can happen when the context is not fully initialized, // so the cache can be undefined. @@ -286,47 +283,47 @@ class IncrementalMarkingMarkingVisitor HeapObject* heap_obj = HeapObject::cast(cache); // Mark the object grey if it is white, do not enque it into the marking // deque. - Heap* heap = map->GetHeap(); - bool ignored = - ObjectMarking::WhiteToGrey( - heap_obj, heap->incremental_marking()->marking_state(heap_obj)); - USE(ignored); + ObjectMarking::WhiteToGrey( + heap_obj, incremental_marking_->marking_state(heap_obj)); } } - VisitNativeContext(map, context); + return Parent::VisitNativeContext(map, context); } - INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) { + inline void VisitPointer(HeapObject* host, Object** p) final { Object* target = *p; if (target->IsHeapObject()) { - heap->mark_compact_collector()->RecordSlot(object, p, target); - MarkObject(heap, target); + collector_->RecordSlot(host, p, target); + MarkObject(target); } } - INLINE(static void VisitPointers(Heap* heap, HeapObject* object, - Object** start, Object** end)) { + inline void VisitPointers(HeapObject* host, Object** start, + Object** end) final { for (Object** p = start; p < end; p++) { Object* target = *p; if (target->IsHeapObject()) { - heap->mark_compact_collector()->RecordSlot(object, p, target); - MarkObject(heap, target); + collector_->RecordSlot(host, p, target); + MarkObject(target); } } } // Marks the object grey and pushes it on the marking stack. - INLINE(static void MarkObject(Heap* heap, Object* obj)) { - heap->incremental_marking()->WhiteToGreyAndPush(HeapObject::cast(obj)); + V8_INLINE void MarkObject(Object* obj) { + incremental_marking_->WhiteToGreyAndPush(HeapObject::cast(obj)); } // Marks the object black without pushing it on the marking stack. // Returns true if object needed marking and false otherwise. - INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { + V8_INLINE bool MarkObjectWithoutPush(Object* obj) { HeapObject* heap_object = HeapObject::cast(obj); return ObjectMarking::WhiteToBlack( - heap_object, heap->incremental_marking()->marking_state(heap_object)); + heap_object, incremental_marking_->marking_state(heap_object)); } + + private: + IncrementalMarking* const incremental_marking_; }; class IncrementalMarkingRootMarkingVisitor : public RootVisitor { @@ -354,12 +351,6 @@ class IncrementalMarkingRootMarkingVisitor : public RootVisitor { Heap* heap_; }; - -void IncrementalMarking::Initialize() { - IncrementalMarkingMarkingVisitor::Initialize(); -} - - void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk, bool is_marking, bool is_compacting) { @@ -893,7 +884,8 @@ void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { } DCHECK(ObjectMarking::IsBlack(obj, marking_state(obj))); WhiteToGreyAndPush(map); - IncrementalMarkingMarkingVisitor::IterateBody(map, obj); + IncrementalMarkingMarkingVisitor visitor(heap()->mark_compact_collector()); + visitor.Visit(map, obj); } void IncrementalMarking::ProcessBlackAllocatedObject(HeapObject* obj) { @@ -913,7 +905,8 @@ void IncrementalMarking::RevisitObject(HeapObject* obj) { } Map* map = obj->map(); WhiteToGreyAndPush(map); - IncrementalMarkingMarkingVisitor::IterateBody(map, obj); + IncrementalMarkingMarkingVisitor visitor(heap()->mark_compact_collector()); + visitor.Visit(map, obj); } intptr_t IncrementalMarking::ProcessMarkingWorklist( diff --git a/src/heap/incremental-marking.h b/src/heap/incremental-marking.h index ec32c554ec..6fe5c9768a 100644 --- a/src/heap/incremental-marking.h +++ b/src/heap/incremental-marking.h @@ -53,8 +53,6 @@ class V8_EXPORT_PRIVATE IncrementalMarking { bool paused_; }; - static void Initialize(); - explicit IncrementalMarking(Heap* heap); MarkingState marking_state(HeapObject* object) const { diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index d8e053ac1e..7e80087bfc 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -4810,10 +4810,6 @@ void MarkCompactCollector::StartSweepSpaces() { heap_->lo_space()->FreeUnmarkedObjects(); } -void MarkCompactCollector::Initialize() { - IncrementalMarking::Initialize(); -} - void MarkCompactCollector::RecordCodeEntrySlot(HeapObject* host, Address slot, Code* target) { Page* target_page = Page::FromAddress(reinterpret_cast
(target)); diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h index de28ac7a42..a80f2cd4b9 100644 --- a/src/heap/mark-compact.h +++ b/src/heap/mark-compact.h @@ -541,8 +541,6 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { kClearMarkbits, }; - static void Initialize(); - MarkingState marking_state(HeapObject* object) const override { return MarkingState::Internal(object); } diff --git a/src/heap/objects-visiting-inl.h b/src/heap/objects-visiting-inl.h index c7b676a6c8..b4c4bfc24f 100644 --- a/src/heap/objects-visiting-inl.h +++ b/src/heap/objects-visiting-inl.h @@ -5,9 +5,11 @@ #ifndef V8_OBJECTS_VISITING_INL_H_ #define V8_OBJECTS_VISITING_INL_H_ -#include "src/heap/array-buffer-tracker.h" -#include "src/heap/mark-compact.h" #include "src/heap/objects-visiting.h" + +#include "src/heap/array-buffer-tracker.h" +#include "src/heap/embedder-tracing.h" +#include "src/heap/mark-compact.h" #include "src/ic/ic-state.h" #include "src/macro-assembler.h" #include "src/objects-body-descriptors-inl.h" @@ -219,387 +221,6 @@ Callback VisitorDispatchTable::GetVisitor(Map* map) { return reinterpret_cast(callbacks_[map->visitor_id()]); } -template -void StaticMarkingVisitor::Initialize() { - table_.Register(kVisitShortcutCandidate, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitConsString, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitThinString, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitSlicedString, - &FixedBodyVisitor::Visit); - - table_.Register( - kVisitSymbol, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitFixedArray, &FixedArrayVisitor::Visit); - - table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit); - - table_.Register( - kVisitFixedTypedArrayBase, - &FlexibleBodyVisitor::Visit); - - table_.Register( - kVisitFixedFloat64Array, - &FlexibleBodyVisitor::Visit); - - table_.Register(kVisitNativeContext, &VisitNativeContext); - - table_.Register( - kVisitAllocationSite, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitByteArray, &DataObjectVisitor::Visit); - - table_.Register(kVisitBytecodeArray, &VisitBytecodeArray); - - table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit); - - table_.Register(kVisitSeqOneByteString, &DataObjectVisitor::Visit); - - table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit); - - table_.Register(kVisitJSWeakCollection, &VisitWeakCollection); - - table_.Register( - kVisitOddball, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitMap, &VisitMap); - - table_.Register(kVisitCode, &VisitCode); - - table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo); - - table_.Register(kVisitJSFunction, &VisitJSFunction); - - table_.Register( - kVisitJSArrayBuffer, - &FlexibleBodyVisitor::Visit); - - table_.Register(kVisitJSRegExp, &JSObjectVisitor::Visit); - - table_.Register( - kVisitCell, - &FixedBodyVisitor::Visit); - - table_.Register(kVisitPropertyCell, - &FixedBodyVisitor::Visit); - - table_.Register( - kVisitSmallOrderedHashMap, - &FlexibleBodyVisitor< - StaticVisitor, - SmallOrderedHashTable::BodyDescriptor, - void>::Visit); - - table_.Register( - kVisitSmallOrderedHashSet, - &FlexibleBodyVisitor< - StaticVisitor, - SmallOrderedHashTable::BodyDescriptor, - void>::Visit); - - table_.Register(kVisitWeakCell, &VisitWeakCell); - - table_.Register(kVisitTransitionArray, &VisitTransitionArray); - - table_.Register(kVisitDataObject, &DataObjectVisitor::Visit); - - table_.Register(kVisitJSObjectFast, &JSObjectFastVisitor::Visit); - table_.Register(kVisitJSObject, &JSObjectVisitor::Visit); - - table_.Register(kVisitJSApiObject, &JSApiObjectVisitor::Visit); - - table_.Register(kVisitStruct, &StructObjectVisitor::Visit); -} - - -template -void StaticMarkingVisitor::VisitCodeEntry( - Heap* heap, HeapObject* object, Address entry_address) { - Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); - heap->mark_compact_collector()->RecordCodeEntrySlot(object, entry_address, - code); - StaticVisitor::MarkObject(heap, code); -} - - -template -void StaticMarkingVisitor::VisitEmbeddedPointer( - Heap* heap, RelocInfo* rinfo) { - DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); - HeapObject* object = HeapObject::cast(rinfo->target_object()); - Code* host = rinfo->host(); - heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, object); - // TODO(ulan): It could be better to record slots only for strongly embedded - // objects here and record slots for weakly embedded object during clearing - // of non-live references in mark-compact. - if (!host->IsWeakObject(object)) { - StaticVisitor::MarkObject(heap, object); - } -} - - -template -void StaticMarkingVisitor::VisitCell(Heap* heap, - RelocInfo* rinfo) { - DCHECK(rinfo->rmode() == RelocInfo::CELL); - Cell* cell = rinfo->target_cell(); - Code* host = rinfo->host(); - heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, cell); - if (!host->IsWeakObject(cell)) { - StaticVisitor::MarkObject(heap, cell); - } -} - - -template -void StaticMarkingVisitor::VisitDebugTarget(Heap* heap, - RelocInfo* rinfo) { - DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && - rinfo->IsPatchedDebugBreakSlotSequence()); - Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); - Code* host = rinfo->host(); - heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target); - StaticVisitor::MarkObject(heap, target); -} - - -template -void StaticMarkingVisitor::VisitCodeTarget(Heap* heap, - RelocInfo* rinfo) { - DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); - Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); - Code* host = rinfo->host(); - heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target); - StaticVisitor::MarkObject(heap, target); -} - -template -void StaticMarkingVisitor::VisitCodeAgeSequence( - Heap* heap, RelocInfo* rinfo) { - DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); - Code* target = rinfo->code_age_stub(); - DCHECK(target != NULL); - Code* host = rinfo->host(); - heap->mark_compact_collector()->RecordRelocSlot(host, rinfo, target); - StaticVisitor::MarkObject(heap, target); -} - -template -void StaticMarkingVisitor::VisitBytecodeArray( - Map* map, HeapObject* object) { - FlexibleBodyVisitor::Visit(map, object); - BytecodeArray::cast(object)->MakeOlder(); -} - -template -void StaticMarkingVisitor::VisitNativeContext( - Map* map, HeapObject* object) { - FixedBodyVisitor::Visit( - map, object); -} - - -template -void StaticMarkingVisitor::VisitMap(Map* map, - HeapObject* object) { - Heap* heap = map->GetHeap(); - Map* map_object = Map::cast(object); - - // Clears the cache of ICs related to this map. - if (FLAG_cleanup_code_caches_at_gc) { - map_object->ClearCodeCache(heap); - } - - // When map collection is enabled we have to mark through map's transitions - // and back pointers in a special way to make these links weak. - if (map_object->CanTransition()) { - MarkMapContents(heap, map_object); - } else { - StaticVisitor::VisitPointers( - heap, object, - HeapObject::RawField(object, Map::kPointerFieldsBeginOffset), - HeapObject::RawField(object, Map::kPointerFieldsEndOffset)); - } -} - -template -void StaticMarkingVisitor::VisitWeakCell(Map* map, - HeapObject* object) { - Heap* heap = map->GetHeap(); - WeakCell* weak_cell = reinterpret_cast(object); - // Enqueue weak cell in linked list of encountered weak collections. - // We can ignore weak cells with cleared values because they will always - // contain smi zero. - if (weak_cell->next_cleared() && !weak_cell->cleared()) { - HeapObject* value = HeapObject::cast(weak_cell->value()); - if (ObjectMarking::IsBlackOrGrey( - value, MarkingState::Internal(value))) { - // Weak cells with live values are directly processed here to reduce - // the processing time of weak cells during the main GC pause. - Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset); - map->GetHeap()->mark_compact_collector()->RecordSlot(weak_cell, slot, - *slot); - } else { - // If we do not know about liveness of values of weak cells, we have to - // process them when we know the liveness of the whole transitive - // closure. - weak_cell->set_next(heap->encountered_weak_cells(), - UPDATE_WEAK_WRITE_BARRIER); - heap->set_encountered_weak_cells(weak_cell); - } - } -} - - -template -void StaticMarkingVisitor::VisitTransitionArray( - Map* map, HeapObject* object) { - TransitionArray* array = TransitionArray::cast(object); - Heap* heap = array->GetHeap(); - // Visit strong references. - if (array->HasPrototypeTransitions()) { - StaticVisitor::VisitPointer(heap, array, - array->GetPrototypeTransitionsSlot()); - } - int num_transitions = TransitionArray::NumberOfTransitions(array); - for (int i = 0; i < num_transitions; ++i) { - StaticVisitor::VisitPointer(heap, array, array->GetKeySlot(i)); - } - // Enqueue the array in linked list of encountered transition arrays if it is - // not already in the list. - if (array->next_link()->IsUndefined(heap->isolate())) { - Heap* heap = map->GetHeap(); - array->set_next_link(heap->encountered_transition_arrays(), - UPDATE_WEAK_WRITE_BARRIER); - heap->set_encountered_transition_arrays(array); - } -} - -template -void StaticMarkingVisitor::VisitWeakCollection( - Map* map, HeapObject* object) { - typedef FlexibleBodyVisitor JSWeakCollectionBodyVisitor; - Heap* heap = map->GetHeap(); - JSWeakCollection* weak_collection = - reinterpret_cast(object); - - // Enqueue weak collection in linked list of encountered weak collections. - if (weak_collection->next() == heap->undefined_value()) { - weak_collection->set_next(heap->encountered_weak_collections()); - heap->set_encountered_weak_collections(weak_collection); - } - - // Skip visiting the backing hash table containing the mappings and the - // pointer to the other enqueued weak collections, both are post-processed. - JSWeakCollectionBodyVisitor::Visit(map, object); - - // Partially initialized weak collection is enqueued, but table is ignored. - if (!weak_collection->table()->IsHashTable()) return; - - // Mark the backing hash table without pushing it on the marking stack. - Object** slot = HeapObject::RawField(object, JSWeakCollection::kTableOffset); - HeapObject* obj = HeapObject::cast(*slot); - heap->mark_compact_collector()->RecordSlot(object, slot, obj); - StaticVisitor::MarkObjectWithoutPush(heap, obj); -} - - -template -void StaticMarkingVisitor::VisitCode(Map* map, - HeapObject* object) { - typedef FlexibleBodyVisitor - CodeBodyVisitor; - Heap* heap = map->GetHeap(); - Code* code = Code::cast(object); - if (FLAG_age_code && !heap->isolate()->serializer_enabled()) { - code->MakeOlder(); - } - CodeBodyVisitor::Visit(map, object); -} - - -template -void StaticMarkingVisitor::VisitSharedFunctionInfo( - Map* map, HeapObject* object) { - Heap* heap = map->GetHeap(); - SharedFunctionInfo* shared = SharedFunctionInfo::cast(object); - if (shared->ic_age() != heap->global_ic_age()) { - shared->ResetForNewContext(heap->global_ic_age()); - } - FixedBodyVisitor::Visit(map, object); -} - - -template -void StaticMarkingVisitor::VisitJSFunction(Map* map, - HeapObject* object) { - FlexibleBodyVisitor::Visit(map, object); -} - -template -void StaticMarkingVisitor::MarkMapContents(Heap* heap, - Map* map) { - // Since descriptor arrays are potentially shared, ensure that only the - // descriptors that belong to this map are marked. The first time a non-empty - // descriptor array is marked, its header is also visited. The slot holding - // the descriptor array will be implicitly recorded when the pointer fields of - // this map are visited. Prototype maps don't keep track of transitions, so - // just mark the entire descriptor array. - if (!map->is_prototype_map()) { - DescriptorArray* descriptors = map->instance_descriptors(); - if (StaticVisitor::MarkObjectWithoutPush(heap, descriptors) && - descriptors->length() > 0) { - StaticVisitor::VisitPointers(heap, descriptors, - descriptors->GetFirstElementAddress(), - descriptors->GetDescriptorEndSlot(0)); - } - int start = 0; - int end = map->NumberOfOwnDescriptors(); - if (start < end) { - StaticVisitor::VisitPointers(heap, descriptors, - descriptors->GetDescriptorStartSlot(start), - descriptors->GetDescriptorEndSlot(end)); - } - } - - // Mark the pointer fields of the Map. Since the transitions array has - // been marked already, it is fine that one of these fields contains a - // pointer to it. - StaticVisitor::VisitPointers( - heap, map, HeapObject::RawField(map, Map::kPointerFieldsBeginOffset), - HeapObject::RawField(map, Map::kPointerFieldsEndOffset)); -} - - -inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { - Object* undefined = heap->undefined_value(); - return (info->script() != undefined) && - (reinterpret_cast(info->script())->source() != undefined); -} - template ResultType HeapVisitor::Visit(HeapObject* object) { return Visit(object->map(), object); diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h index ce53d19314..35c971898f 100644 --- a/src/heap/objects-visiting.h +++ b/src/heap/objects-visiting.h @@ -6,22 +6,11 @@ #define V8_OBJECTS_VISITING_H_ #include "src/allocation.h" -#include "src/heap/embedder-tracing.h" #include "src/heap/heap.h" -#include "src/heap/spaces.h" #include "src/layout-descriptor.h" #include "src/objects-body-descriptors.h" #include "src/objects/string.h" -// This file provides base classes and auxiliary methods for defining -// static object visitors used during GC. -// Visiting HeapObject body with a normal ObjectVisitor requires performing -// two switches on object's instance type to determine object size and layout -// and one or more virtual method calls on visitor itself. -// Static visitor is different: it provides a dispatch table which contains -// pointers to specialized visit functions. Each map has the visitor_id -// field which contains an index of specialized visitor to use. - namespace v8 { namespace internal { @@ -121,122 +110,6 @@ class VisitorDispatchTable { base::AtomicWord callbacks_[kVisitorIdCount]; }; - -template -class FlexibleBodyVisitor : public AllStatic { - public: - INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { - int object_size = BodyDescriptor::SizeOf(map, object); - BodyDescriptor::template IterateBody(object, object_size); - return static_cast(object_size); - } -}; - - -template -class FixedBodyVisitor : public AllStatic { - public: - INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { - BodyDescriptor::template IterateBody(object); - return static_cast(BodyDescriptor::kSize); - } -}; - -// Base class for visitors used to transitively mark the entire heap. -// IterateBody returns nothing. -// Certain types of objects might not be handled by this base class and -// no visitor function is registered by the generic initialization. A -// specialized visitor function needs to be provided by the inheriting -// class itself for those cases. -// -// This class is intended to be used in the following way: -// -// class SomeVisitor : public StaticMarkingVisitor { -// ... -// } -// -// This is an example of Curiously recurring template pattern. -template -class StaticMarkingVisitor : public StaticVisitorBase { - public: - static void Initialize(); - - INLINE(static void IterateBody(Map* map, HeapObject* obj)) { - table_.GetVisitor(map)(map, obj); - } - - INLINE(static void VisitWeakCell(Map* map, HeapObject* object)); - INLINE(static void VisitTransitionArray(Map* map, HeapObject* object)); - INLINE(static void VisitCodeEntry(Heap* heap, HeapObject* object, - Address entry_address)); - INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo)); - INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo)); - INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo)); - INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo)); - INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo)); - INLINE(static void VisitExternalReference(RelocInfo* rinfo)) {} - INLINE(static void VisitInternalReference(RelocInfo* rinfo)) {} - INLINE(static void VisitRuntimeEntry(RelocInfo* rinfo)) {} - // Skip the weak next code link in a code object. - INLINE(static void VisitNextCodeLink(Heap* heap, Object** slot)) {} - - protected: - INLINE(static void VisitMap(Map* map, HeapObject* object)); - INLINE(static void VisitCode(Map* map, HeapObject* object)); - INLINE(static void VisitBytecodeArray(Map* map, HeapObject* object)); - INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object)); - INLINE(static void VisitWeakCollection(Map* map, HeapObject* object)); - INLINE(static void VisitJSFunction(Map* map, HeapObject* object)); - INLINE(static void VisitNativeContext(Map* map, HeapObject* object)); - - // Mark pointers in a Map treating some elements of the descriptor array weak. - static void MarkMapContents(Heap* heap, Map* map); - - class DataObjectVisitor { - public: - template - static inline void VisitSpecialized(Map* map, HeapObject* object) {} - - INLINE(static void Visit(Map* map, HeapObject* object)) {} - }; - - typedef FlexibleBodyVisitor - FixedArrayVisitor; - - typedef FlexibleBodyVisitor - JSObjectFastVisitor; - typedef FlexibleBodyVisitor - JSObjectVisitor; - - class JSApiObjectVisitor : AllStatic { - public: - INLINE(static void Visit(Map* map, HeapObject* object)) { - TracePossibleWrapper(object); - JSObjectVisitor::Visit(map, object); - } - - private: - INLINE(static void TracePossibleWrapper(HeapObject* object)) { - if (object->GetHeap()->local_embedder_heap_tracer()->InUse()) { - DCHECK(object->IsJSObject()); - object->GetHeap()->TracePossibleWrapper(JSObject::cast(object)); - } - } - }; - - typedef FlexibleBodyVisitor - StructObjectVisitor; - - typedef void (*Callback)(Map* map, HeapObject* object); - - static VisitorDispatchTable table_; -}; - - -template -VisitorDispatchTable::Callback> - StaticMarkingVisitor::table_; - #define TYPED_VISITOR_ID_LIST(V) \ V(AllocationSite) \ V(ByteArray) \