v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
heap-visitor.cc
Go to the documentation of this file.
1// Copyright 2011 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
6
7#include "src/heap/heap-inl.h"
12
13namespace v8 {
14namespace internal {
15
16// We don't record weak slots during marking or scavenges. Instead we do it
17// once when we complete mark-compact cycle. Note that write barrier has no
18// effect if we are already in the middle of compacting mark-sweep cycle and we
19// have to record slots manually.
20static bool MustRecordSlots(Heap* heap) {
21 return heap->gc_state() == Heap::MARK_COMPACT &&
22 heap->mark_compact_collector()->is_compacting();
23}
24
25template <class T>
27
28template <class T>
30 WeakObjectRetainer* retainer) {
31 Tagged<HeapObject> undefined = ReadOnlyRoots(heap).undefined_value();
33 Tagged<T> tail;
34 bool record_slots = MustRecordSlots(heap);
35
36 while (list != undefined) {
37 // Check whether to keep the candidate in the list.
38 Tagged<T> candidate = Cast<T>(list);
39
40 Tagged<Object> retained = retainer->RetainAs(list);
41
42 // Move to the next element before the WeakNext is cleared.
43 list = WeakListVisitor<T>::WeakNext(candidate);
44
45 if (retained != Tagged<Object>()) {
46 if (head == undefined) {
47 // First element in the list.
48 head = retained;
49 } else {
50 // Subsequent elements in the list.
51 DCHECK(!tail.is_null());
53 if (record_slots) {
54 Tagged<HeapObject> slot_holder =
56 int slot_offset = WeakListVisitor<T>::WeakNextOffset();
57 ObjectSlot slot = slot_holder->RawField(slot_offset);
58 MarkCompactCollector::RecordSlot(slot_holder, slot,
59 Cast<HeapObject>(retained));
60 }
61 }
62 // Retained object is new tail.
63 DCHECK(!IsUndefined(retained, heap->isolate()));
64 candidate = Cast<T>(retained);
65 tail = candidate;
66
67 // tail is a live object, visit it.
69
70 } else {
72 }
73 }
74
75 // Terminate the list if there is one or more elements.
76 if (!tail.is_null()) WeakListVisitor<T>::SetWeakNext(tail, undefined);
77 return head;
78}
79
80template <class T>
82 Tagged<Object> undefined = ReadOnlyRoots(heap).undefined_value();
83 while (list != undefined) {
84 Tagged<T> candidate = Cast<T>(list);
85 list = WeakListVisitor<T>::WeakNext(candidate);
86 WeakListVisitor<T>::SetWeakNext(candidate, undefined);
87 }
88}
89
90template <>
92 static void SetWeakNext(Tagged<Context> context, Tagged<HeapObject> next) {
94 }
95
97 return context->next_context_link();
98 }
99
101 return context;
102 }
103
107
109 WeakObjectRetainer* retainer) {
110 if (heap->gc_state() == Heap::MARK_COMPACT) {
111 // Record the slots of the weak entries in the native context.
112 for (int idx = Context::FIRST_WEAK_SLOT;
113 idx < Context::NATIVE_CONTEXT_SLOTS; ++idx) {
114 ObjectSlot slot = context->RawField(Context::OffsetOfElementAt(idx));
116 Cast<HeapObject>(*slot));
117 }
118 }
119 }
120
121 template <class T>
122 static void DoWeakList(Heap* heap, Tagged<Context> context,
123 WeakObjectRetainer* retainer, int index) {
124 // Visit the weak list, removing dead intermediate elements.
125 Tagged<Object> list_head =
126 VisitWeakList<T>(heap, context->get(index), retainer);
127
128 // Update the list head.
129 context->set(index, list_head, UPDATE_WRITE_BARRIER);
130
131 if (MustRecordSlots(heap)) {
132 // Record the updated slot if necessary.
133 ObjectSlot head_slot = context->RawField(FixedArray::SizeFor(index));
134 heap->mark_compact_collector()->RecordSlot(context, head_slot,
135 Cast<HeapObject>(list_head));
136 }
137 }
138
139 static void VisitPhantomObject(Heap* heap, Tagged<Context> context) {}
140};
141
142template <>
150
152 return obj->weak_next();
153 }
154
159
160 static int WeakNextOffset() {
161 return offsetof(AllocationSiteWithWeakNext, weak_next_);
162 }
163
166
168};
169
170template <>
177
179 return obj->next_dirty();
180 }
181
185
186 static int WeakNextOffset() {
187 return JSFinalizationRegistry::kNextDirtyOffset;
188 }
189
192 heap->set_dirty_js_finalization_registries_list_tail(obj);
193 }
194
196};
197
199 WeakObjectRetainer* retainer);
200
202 Heap* heap, Tagged<Object> list, WeakObjectRetainer* retainer);
203
205 Heap* heap, Tagged<Object> list, WeakObjectRetainer* retainer);
206} // namespace internal
207} // namespace v8
static V8_INLINE constexpr int OffsetOfElementAt(int index)
Definition contexts.h:512
static V8_INLINE void RecordSlot(Tagged< HeapObject > object, THeapObjectSlot slot, Tagged< HeapObject > target)
V8_INLINE constexpr bool is_null() const
Definition tagged.h:502
virtual Tagged< Object > RetainAs(Tagged< Object > object)=0
TNode< Context > context
template Tagged< Object > VisitWeakList< AllocationSiteWithWeakNext >(Heap *heap, Tagged< Object > list, WeakObjectRetainer *retainer)
@ UPDATE_WRITE_BARRIER
Definition objects.h:55
static bool MustRecordSlots(Heap *heap)
Tagged< Object > VisitWeakList(Heap *heap, Tagged< Object > list, WeakObjectRetainer *retainer)
template Tagged< Object > VisitWeakList< JSFinalizationRegistry >(Heap *heap, Tagged< Object > list, WeakObjectRetainer *retainer)
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
static void ClearWeakList(Heap *heap, Tagged< Object > list)
template Tagged< Object > VisitWeakList< Context >(Heap *heap, Tagged< Object > list, WeakObjectRetainer *retainer)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK(condition)
Definition logging.h:482
static void VisitPhantomObject(Heap *, Tagged< AllocationSite >)
static void VisitLiveObject(Heap *, Tagged< AllocationSite >, WeakObjectRetainer *)
static Tagged< Object > WeakNext(Tagged< AllocationSiteWithWeakNext > obj)
static void SetWeakNext(Tagged< AllocationSiteWithWeakNext > obj, Tagged< HeapObject > next)
static Tagged< HeapObject > WeakNextHolder(Tagged< AllocationSiteWithWeakNext > obj)
static void VisitLiveObject(Heap *heap, Tagged< Context > context, WeakObjectRetainer *retainer)
static Tagged< HeapObject > WeakNextHolder(Tagged< Context > context)
static void DoWeakList(Heap *heap, Tagged< Context > context, WeakObjectRetainer *retainer, int index)
static void VisitPhantomObject(Heap *heap, Tagged< Context > context)
static Tagged< Object > WeakNext(Tagged< Context > context)
static void SetWeakNext(Tagged< Context > context, Tagged< HeapObject > next)
static void VisitPhantomObject(Heap *, Tagged< JSFinalizationRegistry >)
static Tagged< Object > WeakNext(Tagged< JSFinalizationRegistry > obj)
static void VisitLiveObject(Heap *heap, Tagged< JSFinalizationRegistry > obj, WeakObjectRetainer *)
static Tagged< HeapObject > WeakNextHolder(Tagged< JSFinalizationRegistry > obj)
static void SetWeakNext(Tagged< JSFinalizationRegistry > obj, Tagged< HeapObject > next)