• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 #include "src/heap/weak-object-worklists.h"
6 
7 #include "src/heap/heap-inl.h"
8 #include "src/heap/heap.h"
9 #include "src/heap/worklist.h"
10 #include "src/objects/hash-table.h"
11 #include "src/objects/heap-object.h"
12 #include "src/objects/js-function.h"
13 #include "src/objects/js-weak-refs-inl.h"
14 #include "src/objects/js-weak-refs.h"
15 #include "src/objects/shared-function-info.h"
16 #include "src/objects/transitions.h"
17 
18 namespace v8 {
19 
20 namespace internal {
21 
UpdateAfterScavenge()22 void WeakObjects::UpdateAfterScavenge() {
23 #define INVOKE_UPDATE(_, name, Name) Update##Name(name);
24   WEAK_OBJECT_WORKLISTS(INVOKE_UPDATE)
25 #undef INVOKE_UPDATE
26 }
27 
UpdateTransitionArrays(WeakObjectWorklist<TransitionArray> & transition_arrays)28 void WeakObjects::UpdateTransitionArrays(
29     WeakObjectWorklist<TransitionArray>& transition_arrays) {
30   DCHECK(!ContainsYoungObjects(transition_arrays));
31 }
32 
UpdateEphemeronHashTables(WeakObjectWorklist<EphemeronHashTable> & ephemeron_hash_tables)33 void WeakObjects::UpdateEphemeronHashTables(
34     WeakObjectWorklist<EphemeronHashTable>& ephemeron_hash_tables) {
35   ephemeron_hash_tables.Update(
36       [](EphemeronHashTable slot_in, EphemeronHashTable* slot_out) -> bool {
37         EphemeronHashTable forwarded = ForwardingAddress(slot_in);
38 
39         if (!forwarded.is_null()) {
40           *slot_out = forwarded;
41           return true;
42         }
43 
44         return false;
45       });
46 }
47 
48 namespace {
EphemeronUpdater(Ephemeron slot_in,Ephemeron * slot_out)49 bool EphemeronUpdater(Ephemeron slot_in, Ephemeron* slot_out) {
50   HeapObject key = slot_in.key;
51   HeapObject value = slot_in.value;
52   HeapObject forwarded_key = ForwardingAddress(key);
53   HeapObject forwarded_value = ForwardingAddress(value);
54 
55   if (!forwarded_key.is_null() && !forwarded_value.is_null()) {
56     *slot_out = Ephemeron{forwarded_key, forwarded_value};
57     return true;
58   }
59 
60   return false;
61 }
62 }  // anonymous namespace
63 
UpdateCurrentEphemerons(WeakObjectWorklist<Ephemeron> & current_ephemerons)64 void WeakObjects::UpdateCurrentEphemerons(
65     WeakObjectWorklist<Ephemeron>& current_ephemerons) {
66   current_ephemerons.Update(EphemeronUpdater);
67 }
68 
UpdateNextEphemerons(WeakObjectWorklist<Ephemeron> & next_ephemerons)69 void WeakObjects::UpdateNextEphemerons(
70     WeakObjectWorklist<Ephemeron>& next_ephemerons) {
71   next_ephemerons.Update(EphemeronUpdater);
72 }
73 
UpdateDiscoveredEphemerons(WeakObjectWorklist<Ephemeron> & discovered_ephemerons)74 void WeakObjects::UpdateDiscoveredEphemerons(
75     WeakObjectWorklist<Ephemeron>& discovered_ephemerons) {
76   discovered_ephemerons.Update(EphemeronUpdater);
77 }
78 
UpdateWeakReferences(WeakObjectWorklist<HeapObjectAndSlot> & weak_references)79 void WeakObjects::UpdateWeakReferences(
80     WeakObjectWorklist<HeapObjectAndSlot>& weak_references) {
81   weak_references.Update(
82       [](HeapObjectAndSlot slot_in, HeapObjectAndSlot* slot_out) -> bool {
83         HeapObject heap_obj = slot_in.first;
84         HeapObject forwarded = ForwardingAddress(heap_obj);
85 
86         if (!forwarded.is_null()) {
87           ptrdiff_t distance_to_slot =
88               slot_in.second.address() - slot_in.first.ptr();
89           Address new_slot = forwarded.ptr() + distance_to_slot;
90           slot_out->first = forwarded;
91           slot_out->second = HeapObjectSlot(new_slot);
92           return true;
93         }
94 
95         return false;
96       });
97 }
98 
UpdateWeakObjectsInCode(WeakObjectWorklist<HeapObjectAndCode> & weak_objects_in_code)99 void WeakObjects::UpdateWeakObjectsInCode(
100     WeakObjectWorklist<HeapObjectAndCode>& weak_objects_in_code) {
101   weak_objects_in_code.Update(
102       [](HeapObjectAndCode slot_in, HeapObjectAndCode* slot_out) -> bool {
103         HeapObject heap_obj = slot_in.first;
104         HeapObject forwarded = ForwardingAddress(heap_obj);
105 
106         if (!forwarded.is_null()) {
107           slot_out->first = forwarded;
108           slot_out->second = slot_in.second;
109           return true;
110         }
111 
112         return false;
113       });
114 }
115 
UpdateJSWeakRefs(WeakObjectWorklist<JSWeakRef> & js_weak_refs)116 void WeakObjects::UpdateJSWeakRefs(
117     WeakObjectWorklist<JSWeakRef>& js_weak_refs) {
118   if (FLAG_harmony_weak_refs) {
119     js_weak_refs.Update(
120         [](JSWeakRef js_weak_ref_in, JSWeakRef* js_weak_ref_out) -> bool {
121           JSWeakRef forwarded = ForwardingAddress(js_weak_ref_in);
122 
123           if (!forwarded.is_null()) {
124             *js_weak_ref_out = forwarded;
125             return true;
126           }
127 
128           return false;
129         });
130   }
131 }
132 
UpdateWeakCells(WeakObjectWorklist<WeakCell> & weak_cells)133 void WeakObjects::UpdateWeakCells(WeakObjectWorklist<WeakCell>& weak_cells) {
134   // TODO(syg, marja): Support WeakCells in the young generation.
135   DCHECK(!ContainsYoungObjects(weak_cells));
136 }
137 
UpdateBytecodeFlushingCandidates(WeakObjectWorklist<SharedFunctionInfo> & bytecode_flushing_candidates)138 void WeakObjects::UpdateBytecodeFlushingCandidates(
139     WeakObjectWorklist<SharedFunctionInfo>& bytecode_flushing_candidates) {
140   DCHECK(!ContainsYoungObjects(bytecode_flushing_candidates));
141 }
142 
UpdateFlushedJSFunctions(WeakObjectWorklist<JSFunction> & flushed_js_functions)143 void WeakObjects::UpdateFlushedJSFunctions(
144     WeakObjectWorklist<JSFunction>& flushed_js_functions) {
145   flushed_js_functions.Update(
146       [](JSFunction slot_in, JSFunction* slot_out) -> bool {
147         JSFunction forwarded = ForwardingAddress(slot_in);
148 
149         if (!forwarded.is_null()) {
150           *slot_out = forwarded;
151           return true;
152         }
153 
154         return false;
155       });
156 }
157 
158 #ifdef DEBUG
159 template <typename Type>
ContainsYoungObjects(WeakObjectWorklist<Type> & worklist)160 bool WeakObjects::ContainsYoungObjects(WeakObjectWorklist<Type>& worklist) {
161   bool result = false;
162   worklist.Iterate([&result](Type candidate) {
163     if (Heap::InYoungGeneration(candidate)) {
164       result = true;
165     }
166   });
167   return result;
168 }
169 #endif
170 
171 }  // namespace internal
172 }  // namespace v8
173