Line data Source code
1 : // Copyright 2016 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/embedder-tracing.h"
6 :
7 : #include "src/base/logging.h"
8 : #include "src/objects/embedder-data-slot.h"
9 : #include "src/objects/js-objects-inl.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 84 : void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) {
15 84 : if (remote_tracer_) remote_tracer_->isolate_ = nullptr;
16 :
17 84 : remote_tracer_ = tracer;
18 84 : if (remote_tracer_)
19 49 : remote_tracer_->isolate_ = reinterpret_cast<v8::Isolate*>(isolate_);
20 84 : }
21 :
22 84030 : void LocalEmbedderHeapTracer::TracePrologue() {
23 168060 : if (!InUse()) return;
24 :
25 41 : num_v8_marking_worklist_was_empty_ = 0;
26 41 : embedder_worklist_empty_ = false;
27 41 : remote_tracer_->TracePrologue();
28 : }
29 :
30 83494 : void LocalEmbedderHeapTracer::TraceEpilogue() {
31 166988 : if (!InUse()) return;
32 :
33 41 : remote_tracer_->TraceEpilogue();
34 : }
35 :
36 83501 : void LocalEmbedderHeapTracer::EnterFinalPause() {
37 167002 : if (!InUse()) return;
38 :
39 48 : remote_tracer_->EnterFinalPause(embedder_stack_state_);
40 : // Resetting to state unknown as there may be follow up garbage collections
41 : // triggered from callbacks that have a different stack state.
42 48 : embedder_stack_state_ = EmbedderHeapTracer::kUnknown;
43 : }
44 :
45 121 : bool LocalEmbedderHeapTracer::Trace(double deadline) {
46 121 : if (!InUse()) return true;
47 :
48 120 : return remote_tracer_->AdvanceTracing(deadline);
49 : }
50 :
51 417463 : bool LocalEmbedderHeapTracer::IsRemoteTracingDone() {
52 417463 : return !InUse() || remote_tracer_->IsTracingDone();
53 : }
54 :
55 7 : void LocalEmbedderHeapTracer::SetEmbedderStackStateForNextFinalization(
56 7 : EmbedderHeapTracer::EmbedderStackState stack_state) {
57 14 : if (!InUse()) return;
58 :
59 7 : embedder_stack_state_ = stack_state;
60 : }
61 :
62 121 : LocalEmbedderHeapTracer::ProcessingScope::ProcessingScope(
63 : LocalEmbedderHeapTracer* tracer)
64 121 : : tracer_(tracer) {
65 121 : wrapper_cache_.reserve(kWrapperCacheSize);
66 121 : }
67 :
68 121 : LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope() {
69 121 : if (!wrapper_cache_.empty()) {
70 16 : tracer_->remote_tracer()->RegisterV8References(std::move(wrapper_cache_));
71 : }
72 121 : }
73 :
74 30 : void LocalEmbedderHeapTracer::ProcessingScope::TracePossibleWrapper(
75 : JSObject js_object) {
76 : DCHECK(js_object->IsApiWrapper());
77 60 : if (js_object->GetEmbedderFieldCount() < 2) return;
78 :
79 : void* pointer0;
80 : void* pointer1;
81 75 : if (EmbedderDataSlot(js_object, 0).ToAlignedPointer(&pointer0) && pointer0 &&
82 30 : EmbedderDataSlot(js_object, 1).ToAlignedPointer(&pointer1)) {
83 30 : wrapper_cache_.push_back({pointer0, pointer1});
84 : }
85 30 : FlushWrapperCacheIfFull();
86 : }
87 :
88 31 : void LocalEmbedderHeapTracer::ProcessingScope::FlushWrapperCacheIfFull() {
89 93 : if (wrapper_cache_.size() == wrapper_cache_.capacity()) {
90 0 : tracer_->remote_tracer()->RegisterV8References(std::move(wrapper_cache_));
91 : wrapper_cache_.clear();
92 0 : wrapper_cache_.reserve(kWrapperCacheSize);
93 : }
94 31 : }
95 :
96 1 : void LocalEmbedderHeapTracer::ProcessingScope::AddWrapperInfoForTesting(
97 : WrapperInfo info) {
98 1 : wrapper_cache_.push_back(info);
99 1 : FlushWrapperCacheIfFull();
100 1 : }
101 :
102 : } // namespace internal
103 183867 : } // namespace v8
|