v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
marking-visitor.h
Go to the documentation of this file.
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_HEAP_MARKING_VISITOR_H_
6#define V8_HEAP_MARKING_VISITOR_H_
7
8#include "src/base/logging.h"
14#include "src/heap/marking.h"
16#include "src/heap/spaces.h"
18
19namespace v8 {
20namespace internal {
21
23 absl::flat_hash_map<Tagged<HeapObject>,
26
27// The base class for all marking visitors (main and concurrent marking) but
28// also for e.g. the reference summarizer. It implements marking logic with
29// support for bytecode flushing, embedder tracing and weak references.
30//
31// Derived classes are expected to provide the following methods:
32// - CanUpdateValuesInHeap
33// - AddStrongReferenceForReferenceSummarizer
34// - AddWeakReferenceForReferenceSummarizer
35// - marking_state
36// - MarkPointerTableEntry
37// - RecordSlot
38// - RecordRelocSlot
39//
40// These methods capture the difference between the different visitor
41// implementations. For example, the concurrent visitor has to use the locking
42// for string types that can be transitioned to other types on the main thread
43// concurrently. On the other hand, the reference summarizer is not supposed to
44// write into heap objects.
45template <typename ConcreteVisitor>
46class MarkingVisitorBase : public ConcurrentHeapVisitor<ConcreteVisitor> {
47 public:
49
51 WeakObjects::Local* local_weak_objects, Heap* heap,
52 unsigned mark_compact_epoch,
53 base::EnumSet<CodeFlushMode> code_flush_mode,
54 bool should_keep_ages_unchanged,
55 uint16_t code_flushing_increase)
56 : ConcurrentHeapVisitor<ConcreteVisitor>(heap->isolate()),
57 local_marking_worklists_(local_marking_worklists),
58 local_weak_objects_(local_weak_objects),
59 heap_(heap),
60 mark_compact_epoch_(mark_compact_epoch),
61 code_flush_mode_(code_flush_mode),
62 should_keep_ages_unchanged_(should_keep_ages_unchanged),
63 code_flushing_increase_(code_flushing_increase),
64 isolate_in_background_(heap->isolate()->is_backgrounded())
65#ifdef V8_COMPRESS_POINTERS
66 ,
67 external_pointer_table_(&heap->isolate()->external_pointer_table()),
68 shared_external_pointer_table_(
69 &heap->isolate()->shared_external_pointer_table()),
70 shared_external_pointer_space_(
71 heap->isolate()->shared_external_pointer_space()),
72 cpp_heap_pointer_table_(&heap->isolate()->cpp_heap_pointer_table())
73#endif // V8_COMPRESS_POINTERS
74#ifdef V8_ENABLE_SANDBOX
75 ,
76 trusted_pointer_table_(&heap->isolate()->trusted_pointer_table()),
77 shared_trusted_pointer_table_(
78 &heap->isolate()->shared_trusted_pointer_table())
79#endif // V8_ENABLE_SANDBOX
80 {
81 }
82
101 V8_INLINE size_t VisitMap(Tagged<Map> map, Tagged<Map> object,
111
112 // ObjectVisitor overrides.
115 ProcessStrongHeapObject(host, host->map_slot(), map);
116 }
118 VisitPointersImpl(host, p, p + 1);
119 }
121 MaybeObjectSlot p) final {
122 VisitPointersImpl(host, p, p + 1);
123 }
137 RelocInfo* rinfo) final;
139 RelocInfo* rinfo) final;
141 ObjectSlot end) final {
142 // Weak list pointers should be ignored during marking. The lists are
143 // reconstructed after GC.
144 }
145
147 ExternalPointerSlot slot) override;
149 CppHeapPointerSlot slot) override;
152 IndirectPointerMode mode) final;
153
155 IndirectPointerSlot slot) final;
156
158 JSDispatchHandle handle) override;
159
164
166 ProtectedMaybeObjectSlot slot) final {
167 VisitPointersImpl(host, slot, slot + 1);
168 }
169
171#ifdef THREAD_SANITIZER
172 // This is needed because TSAN does not process the memory fence
173 // emitted after page initialization.
174 MemoryChunk::FromHeapObject(heap_object)->SynchronizedLoad();
175#endif
176 }
177
178 // Marks the object and pushes it on the marking work list. The `host` is
179 // used for the reference summarizer to valide that the heap snapshot is in
180 // sync with the marker.
182 MarkingHelper::WorklistTarget target_worklist);
183
184 V8_INLINE static constexpr bool ShouldVisitReadOnlyMapPointer() {
185 return false;
186 }
187
188 V8_INLINE static constexpr bool CanEncounterFillerOrFreeSpace() {
189 return false;
190 }
191
192 V8_INLINE static constexpr bool IsTrivialWeakReferenceValue(
193 Tagged<HeapObject> host, Tagged<HeapObject> heap_object);
194
195 void SetKeyToValues(KeyToValues* key_to_values) {
197 key_to_values_ = key_to_values;
198 }
199
200 protected:
201 using ConcurrentHeapVisitor<ConcreteVisitor>::concrete_visitor;
202
203 template <typename THeapObjectSlot>
204 void ProcessStrongHeapObject(Tagged<HeapObject> host, THeapObjectSlot slot,
205 Tagged<HeapObject> heap_object);
206 template <typename THeapObjectSlot>
207 void ProcessWeakHeapObject(Tagged<HeapObject> host, THeapObjectSlot slot,
208 Tagged<HeapObject> heap_object);
209
210 template <typename TSlot>
212 TSlot end);
213
214 template <typename TSlot>
216
218
219 V8_INLINE size_t
221 MarkingProgressTracker& progress_tracker);
222
223 // Methods needed for supporting code flushing.
225 bool ShouldFlushBaselineCode(Tagged<JSFunction> js_function) const;
226
228 bool IsOld(Tagged<SharedFunctionInfo> sfi) const;
230
234 Heap* const heap_;
235 const unsigned mark_compact_epoch_;
240#ifdef V8_COMPRESS_POINTERS
241 ExternalPointerTable* const external_pointer_table_;
242 ExternalPointerTable* const shared_external_pointer_table_;
243 ExternalPointerTable::Space* const shared_external_pointer_space_;
244 CppHeapPointerTable* const cpp_heap_pointer_table_;
245#endif // V8_COMPRESS_POINTERS
246#ifdef V8_ENABLE_SANDBOX
247 TrustedPointerTable* const trusted_pointer_table_;
248 TrustedPointerTable* const shared_trusted_pointer_table_;
249#endif // V8_ENABLE_SANDBOX
250};
251
252// This is the common base class for main and concurrent full marking visitors.
253// Derived class are expected to provide the same methods as for
254// MarkingVisitorBase except for those defined in this class.
255template <typename ConcreteVisitor>
256class FullMarkingVisitorBase : public MarkingVisitorBase<ConcreteVisitor> {
257 public:
259 WeakObjects::Local* local_weak_objects, Heap* heap,
260 unsigned mark_compact_epoch,
261 base::EnumSet<CodeFlushMode> code_flush_mode,
262 bool should_keep_ages_unchanged,
263 uint16_t code_flushing_increase)
264 : MarkingVisitorBase<ConcreteVisitor>(
265 local_marking_worklists, local_weak_objects, heap,
266 mark_compact_epoch, code_flush_mode, should_keep_ages_unchanged,
267 code_flushing_increase),
269
272
275
276 constexpr bool CanUpdateValuesInHeap() { return true; }
277
279
281
282 private:
284};
285
286} // namespace internal
287} // namespace v8
288
289#endif // V8_HEAP_MARKING_VISITOR_H_
FullMarkingVisitorBase(MarkingWorklists::Local *local_marking_worklists, WeakObjects::Local *local_weak_objects, Heap *heap, unsigned mark_compact_epoch, base::EnumSet< CodeFlushMode > code_flush_mode, bool should_keep_ages_unchanged, uint16_t code_flushing_increase)
void MarkPointerTableEntry(Tagged< HeapObject > obj, IndirectPointerSlot slot)
V8_INLINE void AddStrongReferenceForReferenceSummarizer(Tagged< HeapObject > host, Tagged< HeapObject > obj)
V8_INLINE void AddWeakReferenceForReferenceSummarizer(Tagged< HeapObject > host, Tagged< HeapObject > obj)
ConcreteVisitor * concrete_visitor()
V8_INLINE size_t VisitJSFunction(Tagged< Map > map, Tagged< JSFunction > object, MaybeObjectSize)
static V8_INLINE constexpr bool CanEncounterFillerOrFreeSpace()
V8_INLINE size_t VisitEphemeronHashTable(Tagged< Map > map, Tagged< EphemeronHashTable > object, MaybeObjectSize)
const base::EnumSet< CodeFlushMode > code_flush_mode_
bool IsOld(Tagged< SharedFunctionInfo > sfi) const
V8_INLINE void VisitPointer(Tagged< HeapObject > host, MaybeObjectSlot p) final
V8_INLINE void VisitPointer(Tagged< HeapObject > host, ObjectSlot p) final
V8_INLINE void VisitProtectedPointer(Tagged< TrustedObject > host, ProtectedMaybeObjectSlot slot) final
V8_INLINE bool MarkObject(Tagged< HeapObject > host, Tagged< HeapObject > obj, MarkingHelper::WorklistTarget target_worklist)
void SetKeyToValues(KeyToValues *key_to_values)
V8_INLINE void VisitPointers(Tagged< HeapObject > host, MaybeObjectSlot start, MaybeObjectSlot end) final
V8_INLINE size_t VisitFixedArrayWithProgressTracker(Tagged< Map > map, Tagged< FixedArray > object, MarkingProgressTracker &progress_tracker)
V8_INLINE size_t VisitTransitionArray(Tagged< Map > map, Tagged< TransitionArray > object, MaybeObjectSize)
V8_INLINE void VisitCodeTarget(Tagged< InstructionStream > host, RelocInfo *rinfo) final
static V8_INLINE constexpr bool ShouldVisitReadOnlyMapPointer()
void VisitMapPointer(Tagged< HeapObject > host) final
V8_INLINE size_t VisitWeakCell(Tagged< Map > map, Tagged< WeakCell > object, MaybeObjectSize)
V8_INLINE void VisitExternalPointer(Tagged< HeapObject > host, ExternalPointerSlot slot) override
V8_INLINE void VisitIndirectPointer(Tagged< HeapObject > host, IndirectPointerSlot slot, IndirectPointerMode mode) final
void VisitJSDispatchTableEntry(Tagged< HeapObject > host, JSDispatchHandle handle) override
bool HasBytecodeArrayForFlushing(Tagged< SharedFunctionInfo > sfi) const
V8_INLINE size_t VisitJSWeakRef(Tagged< Map > map, Tagged< JSWeakRef > object, MaybeObjectSize)
void ProcessWeakHeapObject(Tagged< HeapObject > host, THeapObjectSlot slot, Tagged< HeapObject > heap_object)
V8_INLINE void VisitPointers(Tagged< HeapObject > host, ObjectSlot start, ObjectSlot end) final
V8_INLINE size_t VisitFixedArray(Tagged< Map > map, Tagged< FixedArray > object, MaybeObjectSize)
void VisitTrustedPointerTableEntry(Tagged< HeapObject > host, IndirectPointerSlot slot) final
WeakObjects::Local *const local_weak_objects_
V8_INLINE void VisitDescriptorsForMap(Tagged< Map > map)
void VisitCustomWeakPointers(Tagged< HeapObject > host, ObjectSlot start, ObjectSlot end) final
void SynchronizePageAccess(Tagged< HeapObject > heap_object) const
V8_INLINE void VisitProtectedPointer(Tagged< TrustedObject > host, ProtectedPointerSlot slot) final
V8_INLINE void VisitPointersImpl(Tagged< HeapObject > host, TSlot start, TSlot end)
V8_INLINE size_t VisitDescriptorArrayStrongly(Tagged< Map > map, Tagged< DescriptorArray > object, MaybeObjectSize)
void MakeOlder(Tagged< SharedFunctionInfo > sfi) const
V8_INLINE void VisitEmbeddedPointer(Tagged< InstructionStream > host, RelocInfo *rinfo) final
V8_INLINE void VisitCppHeapPointer(Tagged< HeapObject > host, CppHeapPointerSlot slot) override
V8_INLINE size_t VisitJSArrayBuffer(Tagged< Map > map, Tagged< JSArrayBuffer > object, MaybeObjectSize)
V8_INLINE size_t VisitSharedFunctionInfo(Tagged< Map > map, Tagged< SharedFunctionInfo > object, MaybeObjectSize)
void ProcessStrongHeapObject(Tagged< HeapObject > host, THeapObjectSlot slot, Tagged< HeapObject > heap_object)
V8_INLINE size_t VisitMap(Tagged< Map > map, Tagged< Map > object, MaybeObjectSize)
V8_INLINE size_t VisitDescriptorArray(Tagged< Map > map, Tagged< DescriptorArray > object, MaybeObjectSize)
MarkingVisitorBase(MarkingWorklists::Local *local_marking_worklists, WeakObjects::Local *local_weak_objects, Heap *heap, unsigned mark_compact_epoch, base::EnumSet< CodeFlushMode > code_flush_mode, bool should_keep_ages_unchanged, uint16_t code_flushing_increase)
bool ShouldFlushBaselineCode(Tagged< JSFunction > js_function) const
static V8_INLINE constexpr bool IsTrivialWeakReferenceValue(Tagged< HeapObject > host, Tagged< HeapObject > heap_object)
bool ShouldFlushCode(Tagged< SharedFunctionInfo > sfi) const
MarkingWorklists::Local *const local_marking_worklists_
V8_INLINE void VisitInstructionStreamPointer(Tagged< Code > host, InstructionStreamSlot slot) final
V8_INLINE void VisitStrongPointerImpl(Tagged< HeapObject > host, TSlot slot)
static V8_INLINE MemoryChunk * FromHeapObject(Tagged< HeapObject > object)
PtrComprCageBase cage_base() const
Definition visitors.h:225
int start
int end
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
absl::flat_hash_map< Tagged< HeapObject >, base::SmallVector< Tagged< HeapObject >, 1 >, Object::Hasher, Object::KeyEqualSafe > KeyToValues
#define DCHECK_NULL(val)
Definition logging.h:491
#define V8_INLINE
Definition v8config.h:500