1 // Copyright 2018 The Chromium 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 "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
6
7 #include "third_party/blink/public/common/features.h"
8 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
9 #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
10 #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
11 #include "third_party/blink/renderer/platform/heap/blink_gc.h"
12 #include "third_party/blink/renderer/platform/heap/thread_state.h"
13 #include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
14
15 namespace blink {
16
UnifiedHeapMarkingVisitorBase(ThreadState * thread_state,v8::Isolate * isolate,int task_id)17 UnifiedHeapMarkingVisitorBase::UnifiedHeapMarkingVisitorBase(
18 ThreadState* thread_state,
19 v8::Isolate* isolate,
20 int task_id)
21 : isolate_(isolate),
22 controller_(thread_state->unified_heap_controller()),
23 v8_references_worklist_(thread_state->Heap().GetV8ReferencesWorklist(),
24 task_id),
25 task_id_(task_id) {
26 DCHECK(controller_);
27 }
28
VisitImpl(const TraceWrapperV8Reference<v8::Value> & v8_reference)29 void UnifiedHeapMarkingVisitorBase::VisitImpl(
30 const TraceWrapperV8Reference<v8::Value>& v8_reference) {
31 DCHECK(isolate_);
32 if (v8_reference.IsEmptySafe())
33 return;
34 if (task_id_ != WorklistTaskId::MutatorThread) {
35 // This is a temporary solution. Pushing directly from concurrent threads
36 // to V8 marking worklist will currently result in data races. This
37 // solution guarantees correctness until we implement a long-term solution
38 // (i.e. allowing Oilpan concurrent threads concurrent-safe access to V8
39 // marking worklist without data-races)
40 v8_references_worklist_.Push(&v8_reference);
41 return;
42 }
43 controller_->RegisterEmbedderReference(
44 v8_reference.template Cast<v8::Data>().Get());
45 }
46
UnifiedHeapMarkingVisitor(ThreadState * thread_state,MarkingMode mode,v8::Isolate * isolate)47 UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state,
48 MarkingMode mode,
49 v8::Isolate* isolate)
50 : MarkingVisitor(thread_state, mode),
51 UnifiedHeapMarkingVisitorBase(thread_state,
52 isolate,
53 WorklistTaskId::MutatorThread) {}
54
55 // static
WriteBarrier(const TraceWrapperV8Reference<v8::Value> & object)56 void UnifiedHeapMarkingVisitor::WriteBarrier(
57 const TraceWrapperV8Reference<v8::Value>& object) {
58 if (object.IsEmpty() || !ThreadState::IsAnyIncrementalMarking())
59 return;
60
61 ThreadState* thread_state = ThreadState::Current();
62 if (!thread_state->IsIncrementalMarking())
63 return;
64
65 thread_state->CurrentVisitor()->Trace(object);
66 }
67
68 // static
WriteBarrier(v8::Isolate * isolate,const WrapperTypeInfo * wrapper_type_info,const void * object)69 void UnifiedHeapMarkingVisitor::WriteBarrier(
70 v8::Isolate* isolate,
71 const WrapperTypeInfo* wrapper_type_info,
72 const void* object) {
73 // |object| here is either ScriptWrappable or CustomWrappable.
74
75 if (!ThreadState::IsAnyIncrementalMarking())
76 return;
77
78 ThreadState* thread_state = ThreadState::Current();
79 if (!thread_state->IsIncrementalMarking())
80 return;
81
82 wrapper_type_info->Trace(thread_state->CurrentVisitor(), object);
83 }
84
Visit(const TraceWrapperV8Reference<v8::Value> & v)85 void UnifiedHeapMarkingVisitor::Visit(
86 const TraceWrapperV8Reference<v8::Value>& v) {
87 VisitImpl(v);
88 }
89
ConcurrentUnifiedHeapMarkingVisitor(ThreadState * thread_state,MarkingMode mode,v8::Isolate * isolate,int task_id)90 ConcurrentUnifiedHeapMarkingVisitor::ConcurrentUnifiedHeapMarkingVisitor(
91 ThreadState* thread_state,
92 MarkingMode mode,
93 v8::Isolate* isolate,
94 int task_id)
95 : ConcurrentMarkingVisitor(thread_state, mode, task_id),
96 UnifiedHeapMarkingVisitorBase(thread_state, isolate, task_id) {}
97
FlushWorklists()98 void ConcurrentUnifiedHeapMarkingVisitor::FlushWorklists() {
99 ConcurrentMarkingVisitor::FlushWorklists();
100 v8_references_worklist_.FlushToGlobal();
101 }
102
Visit(const TraceWrapperV8Reference<v8::Value> & v)103 void ConcurrentUnifiedHeapMarkingVisitor::Visit(
104 const TraceWrapperV8Reference<v8::Value>& v) {
105 VisitImpl(v);
106 }
107
108 } // namespace blink
109