5 #include "src/heap/objects-visiting.h" 7 #include "src/heap/heap-inl.h" 8 #include "src/heap/mark-compact-inl.h" 9 #include "src/heap/objects-visiting-inl.h" 18 static bool MustRecordSlots(Heap* heap) {
19 return heap->gc_state() == Heap::MARK_COMPACT &&
20 heap->mark_compact_collector()->is_compacting();
32 bool record_slots = MustRecordSlots(heap);
34 while (list != undefined) {
36 T* candidate =
reinterpret_cast<T*
>(list);
38 Object* retained = retainer->RetainAs(list);
43 if (retained !=
nullptr) {
44 if (head == undefined) {
49 DCHECK_NOT_NULL(tail);
54 ObjectSlot slot = HeapObject::RawField(slot_holder, slot_offset);
55 MarkCompactCollector::RecordSlot(slot_holder, slot,
56 HeapObject::cast(retained));
60 DCHECK(!retained->IsUndefined(heap->isolate()));
61 candidate =
reinterpret_cast<T*
>(retained);
65 WeakListVisitor<T>::VisitLiveObject(heap, tail, retainer);
68 WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
73 if (tail !=
nullptr) WeakListVisitor<T>::SetWeakNext(tail, undefined);
80 Object* VisitWeakList2(Heap* heap, Object* list, WeakObjectRetainer* retainer) {
81 Object* undefined = ReadOnlyRoots(heap).undefined_value();
82 Object* head = undefined;
84 bool record_slots = MustRecordSlots(heap);
86 while (list != undefined) {
88 T candidate = T::cast(list);
90 Object* retained = retainer->RetainAs(list);
93 list = WeakListVisitor<T>::WeakNext(candidate);
95 if (retained !=
nullptr) {
96 if (head == undefined) {
101 DCHECK(!tail.is_null());
102 WeakListVisitor<T>::SetWeakNext(tail, retained);
104 HeapObject* slot_holder = WeakListVisitor<T>::WeakNextHolder(tail);
105 int slot_offset = WeakListVisitor<T>::WeakNextOffset();
106 ObjectSlot slot = HeapObject::RawField(slot_holder, slot_offset);
107 MarkCompactCollector::RecordSlot(slot_holder, slot,
108 HeapObject::cast(retained));
112 DCHECK(!retained->IsUndefined(heap->isolate()));
113 candidate = T::cast(retained);
117 WeakListVisitor<T>::VisitLiveObject(heap, tail, retainer);
120 WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
125 if (!tail.is_null()) WeakListVisitor<T>::SetWeakNext(tail, undefined);
130 static void ClearWeakList(Heap* heap, Object* list) {
131 Object* undefined = ReadOnlyRoots(heap).undefined_value();
132 while (list != undefined) {
133 T candidate = T::cast(list);
134 list = WeakListVisitor<T>::WeakNext(candidate);
135 WeakListVisitor<T>::SetWeakNext(candidate, undefined);
141 static void SetWeakNext(
Code code,
Object* next) {
142 code->code_data_container()->set_next_code_link(next,
143 UPDATE_WEAK_WRITE_BARRIER);
147 return code->code_data_container()->next_code_link();
151 return code->code_data_container();
154 static int WeakNextOffset() {
return CodeDataContainer::kNextCodeLinkOffset; }
158 static void VisitPhantomObject(
Heap* heap,
Code code) {
169 context->set(Context::NEXT_CONTEXT_LINK, next, UPDATE_WEAK_WRITE_BARRIER);
173 return context->next_context_link();
178 static int WeakNextOffset() {
179 return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
182 static void VisitLiveObject(
Heap* heap,
Context context,
184 if (heap->gc_state() == Heap::MARK_COMPACT) {
186 for (
int idx = Context::FIRST_WEAK_SLOT;
187 idx < Context::NATIVE_CONTEXT_SLOTS; ++idx) {
188 ObjectSlot slot = context->RawField(Context::OffsetOfElementAt(idx));
189 MarkCompactCollector::RecordSlot(context, slot,
190 HeapObject::cast(*slot));
194 DoWeakList<Code>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST);
195 DoWeakList<Code>(heap, context, retainer, Context::DEOPTIMIZED_CODE_LIST);
200 static void DoWeakList(
Heap* heap,
Context context,
203 Object* list_head = VisitWeakList2<T>(heap, context->get(index), retainer);
206 context->set(index, list_head, UPDATE_WRITE_BARRIER);
208 if (MustRecordSlots(heap)) {
210 ObjectSlot head_slot = context->RawField(FixedArray::SizeFor(index));
211 heap->mark_compact_collector()->RecordSlot(context, head_slot,
212 HeapObject::cast(list_head));
216 static void VisitPhantomObject(
Heap* heap,
Context context) {
217 ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST));
218 ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST));
226 obj->set_weak_next(next, UPDATE_WEAK_WRITE_BARRIER);
233 static int WeakNextOffset() {
return AllocationSite::kWeakNextOffset; }