Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h

Issue 2843603002: Move ScriptWrappable and dependencies to platform/bindings (Closed)
Patch Set: Rebase and try again Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef ScriptWrappableVisitor_h 5 // This file has been moved to platform/bindings/ScriptWrappableVisitor.h.
6 #define ScriptWrappableVisitor_h 6 // TODO(adithyas): Remove this file.
7 7 #include "platform/bindings/ScriptWrappableVisitor.h"
8 #include "core/CoreExport.h"
9 #include "platform/RuntimeEnabledFeatures.h"
10 #include "platform/heap/HeapPage.h"
11 #include "platform/heap/VisitorImpl.h"
12 #include "platform/heap/WrapperVisitor.h"
13 #include "platform/wtf/Deque.h"
14 #include "platform/wtf/Vector.h"
15 #include "v8/include/v8.h"
16
17 namespace blink {
18
19 class HeapObjectHeader;
20 template <typename T>
21 class Member;
22 class ScriptWrappable;
23 template <typename T>
24 class TraceWrapperV8Reference;
25
26 class WrapperMarkingData {
27 public:
28 WrapperMarkingData(
29 void (*trace_wrappers_callback)(const WrapperVisitor*, const void*),
30 HeapObjectHeader* (*heap_object_header_callback)(const void*),
31 const void* object)
32 : trace_wrappers_callback_(trace_wrappers_callback),
33 heap_object_header_callback_(heap_object_header_callback),
34 raw_object_pointer_(object) {
35 DCHECK(trace_wrappers_callback_);
36 DCHECK(heap_object_header_callback_);
37 DCHECK(raw_object_pointer_);
38 }
39
40 inline void TraceWrappers(WrapperVisitor* visitor) {
41 if (raw_object_pointer_) {
42 trace_wrappers_callback_(visitor, raw_object_pointer_);
43 }
44 }
45
46 // Returns true when object was marked. Ignores (returns true) invalidated
47 // objects.
48 inline bool IsWrapperHeaderMarked() {
49 return !raw_object_pointer_ ||
50 GetHeapObjectHeader()->IsWrapperHeaderMarked();
51 }
52
53 inline const void* RawObjectPointer() { return raw_object_pointer_; }
54
55 private:
56 inline bool ShouldBeInvalidated() {
57 return raw_object_pointer_ && !GetHeapObjectHeader()->IsMarked();
58 }
59
60 inline void Invalidate() { raw_object_pointer_ = nullptr; }
61
62 inline const HeapObjectHeader* GetHeapObjectHeader() {
63 DCHECK(raw_object_pointer_);
64 return heap_object_header_callback_(raw_object_pointer_);
65 }
66
67 void (*trace_wrappers_callback_)(const WrapperVisitor*, const void*);
68 HeapObjectHeader* (*heap_object_header_callback_)(const void*);
69 const void* raw_object_pointer_;
70
71 friend class ScriptWrappableVisitor;
72 };
73
74 // ScriptWrappableVisitor is able to trace through the objects to get all
75 // wrappers. It is used during V8 garbage collection. When this visitor is
76 // set to the v8::Isolate as its embedder heap tracer, V8 will call it during
77 // its garbage collection. At the beginning, it will call TracePrologue, then
78 // repeatedly it will call AdvanceTracing, and at the end it will call
79 // TraceEpilogue. Everytime V8 finds new wrappers, it will let the tracer
80 // know using RegisterV8References.
81 class CORE_EXPORT ScriptWrappableVisitor : public v8::EmbedderHeapTracer,
82 public WrapperVisitor {
83 DISALLOW_IMPLICIT_CONSTRUCTORS(ScriptWrappableVisitor);
84
85 public:
86 ScriptWrappableVisitor(v8::Isolate* isolate) : isolate_(isolate){};
87 ~ScriptWrappableVisitor() override;
88
89 // Replace all dead objects in the marking deque with nullptr after oilpan
90 // gc.
91 static void InvalidateDeadObjectsInMarkingDeque(v8::Isolate*);
92
93 // Immediately clean up all wrappers.
94 static void PerformCleanup(v8::Isolate*);
95
96 void TracePrologue() override;
97
98 static WrapperVisitor* CurrentVisitor(v8::Isolate*);
99
100 static void WriteBarrier(v8::Isolate*,
101 const void*,
102 const TraceWrapperV8Reference<v8::Value>*);
103
104 // TODO(mlippautz): Remove once ScriptWrappable is converted to
105 // TraceWrapperV8Reference.
106 static void WriteBarrier(v8::Isolate*, const v8::Persistent<v8::Object>*);
107
108 template <typename T>
109 static void WriteBarrier(const void* object, const Member<T>& value) {
110 WriteBarrier(object, value.Get());
111 }
112
113 template <typename T>
114 static void WriteBarrier(const void* src_object, const T* dst_object) {
115 static_assert(!NeedsAdjustAndMark<T>::value,
116 "wrapper tracing is not supported within mixins");
117 if (!src_object || !dst_object) {
118 return;
119 }
120 // We only require a write barrier if |srcObject| is already marked. Note
121 // that this implicitly disables the write barrier when the GC is not
122 // active as object will not be marked in this case.
123 if (!HeapObjectHeader::FromPayload(src_object)->IsWrapperHeaderMarked()) {
124 return;
125 }
126
127 const ThreadState* thread_state = ThreadState::Current();
128 DCHECK(thread_state);
129 // If the wrapper is already marked we can bail out here.
130 if (TraceTrait<T>::GetHeapObjectHeader(dst_object)->IsWrapperHeaderMarked())
131 return;
132 // Otherwise, eagerly mark the wrapper header and put the object on the
133 // marking deque for further processing.
134 WrapperVisitor* const visitor = CurrentVisitor(thread_state->GetIsolate());
135 visitor->MarkAndPushToMarkingDeque(dst_object);
136 }
137
138 void RegisterV8References(const std::vector<std::pair<void*, void*>>&
139 internal_fields_of_potential_wrappers) override;
140 void RegisterV8Reference(const std::pair<void*, void*>& internal_fields);
141 bool AdvanceTracing(double deadline_in_ms,
142 v8::EmbedderHeapTracer::AdvanceTracingActions) override;
143 void TraceEpilogue() override;
144 void AbortTracing() override;
145 void EnterFinalPause() override;
146 size_t NumberOfWrappersToTrace() override;
147
148 void DispatchTraceWrappers(const TraceWrapperBase*) const override;
149
150 void TraceWrappers(const TraceWrapperV8Reference<v8::Value>&) const override;
151 void MarkWrapper(const v8::PersistentBase<v8::Value>*) const override;
152
153 void InvalidateDeadObjectsInMarkingDeque();
154
155 bool MarkWrapperHeader(HeapObjectHeader*) const;
156
157 // Mark wrappers in all worlds for the given script wrappable as alive in
158 // V8.
159 void MarkWrappersInAllWorlds(const ScriptWrappable*) const override;
160
161 WTF::Deque<WrapperMarkingData>* GetMarkingDeque() { return &marking_deque_; }
162 WTF::Deque<WrapperMarkingData>* GetVerifierDeque() {
163 return &verifier_deque_;
164 }
165 WTF::Vector<HeapObjectHeader*>* GetHeadersToUnmark() {
166 return &headers_to_unmark_;
167 }
168
169 // Immediately cleans up all wrappers if necessary.
170 void PerformCleanup();
171
172 protected:
173 bool PushToMarkingDeque(
174 void (*trace_wrappers_callback)(const WrapperVisitor*, const void*),
175 HeapObjectHeader* (*heap_object_header_callback)(const void*),
176 void (*missed_write_barrier_callback)(void),
177 const void* object) const override {
178 if (!tracing_in_progress_)
179 return false;
180
181 marking_deque_.push_back(WrapperMarkingData(
182 trace_wrappers_callback, heap_object_header_callback, object));
183 #if DCHECK_IS_ON()
184 if (!advancing_tracing_) {
185 verifier_deque_.push_back(WrapperMarkingData(
186 trace_wrappers_callback, heap_object_header_callback, object));
187 }
188 #endif
189 return true;
190 }
191
192 // Returns true if wrapper tracing is currently in progress, i.e.,
193 // TracePrologue has been called, and TraceEpilogue has not yet been called.
194 bool tracing_in_progress_ = false;
195
196 // Is AdvanceTracing currently running? If not, we know that all calls of
197 // pushToMarkingDeque are from V8 or new wrapper associations. And this
198 // information is used by the verifier feature.
199 bool advancing_tracing_ = false;
200
201 // Indicates whether an idle task for a lazy cleanup has already been
202 // scheduled. The flag is used to avoid scheduling multiple idle tasks for
203 // cleaning up.
204 bool idle_cleanup_task_scheduled_ = false;
205
206 // Indicates whether cleanup should currently happen. The flag is used to
207 // avoid cleaning up in the next GC cycle.
208 bool should_cleanup_ = false;
209
210 // Schedule an idle task to perform a lazy (incremental) clean up of
211 // wrappers.
212 void ScheduleIdleLazyCleanup();
213 void PerformLazyCleanup(double deadline_seconds);
214
215 // Collection of objects we need to trace from. We assume it is safe to hold
216 // on to the raw pointers because:
217 // - oilpan object cannot move
218 // - oilpan gc will call invalidateDeadObjectsInMarkingDeque to delete all
219 // obsolete objects
220 mutable WTF::Deque<WrapperMarkingData> marking_deque_;
221
222 // Collection of objects we started tracing from. We assume it is safe to
223 // hold on to the raw pointers because:
224 // - oilpan object cannot move
225 // - oilpan gc will call invalidateDeadObjectsInMarkingDeque to delete
226 // all obsolete objects
227 //
228 // These objects are used when TraceWrappablesVerifier feature is enabled to
229 // verify that all objects reachable in the atomic pause were marked
230 // incrementally. If not, there is one or multiple write barriers missing.
231 mutable WTF::Deque<WrapperMarkingData> verifier_deque_;
232
233 // Collection of headers we need to unmark after the tracing finished. We
234 // assume it is safe to hold on to the headers because:
235 // - oilpan objects cannot move
236 // - objects this headers belong to are invalidated by the oilpan GC in
237 // invalidateDeadObjectsInMarkingDeque.
238 mutable WTF::Vector<HeapObjectHeader*> headers_to_unmark_;
239 v8::Isolate* isolate_;
240 };
241
242 } // namespace blink
243
244 #endif // ScriptWrappableVisitor_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698