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 164 : void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) {
15 164 : if (remote_tracer_) remote_tracer_->isolate_ = nullptr;
16 :
17 164 : remote_tracer_ = tracer;
18 164 : if (remote_tracer_)
19 89 : remote_tracer_->isolate_ = reinterpret_cast<v8::Isolate*>(isolate_);
20 164 : }
21 :
22 73781 : void LocalEmbedderHeapTracer::TracePrologue() {
23 73781 : if (!InUse()) return;
24 :
25 51 : num_v8_marking_worklist_was_empty_ = 0;
26 51 : embedder_worklist_empty_ = false;
27 51 : remote_tracer_->TracePrologue();
28 : }
29 :
30 68866 : void LocalEmbedderHeapTracer::TraceEpilogue() {
31 68866 : if (!InUse()) return;
32 :
33 46 : remote_tracer_->TraceEpilogue();
34 : }
35 :
36 68873 : void LocalEmbedderHeapTracer::EnterFinalPause() {
37 68873 : if (!InUse()) return;
38 :
39 53 : 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 53 : embedder_stack_state_ = EmbedderHeapTracer::kUnknown;
43 : }
44 :
45 136 : bool LocalEmbedderHeapTracer::Trace(double deadline) {
46 136 : if (!InUse()) return true;
47 :
48 135 : return remote_tracer_->AdvanceTracing(deadline);
49 : }
50 :
51 344353 : bool LocalEmbedderHeapTracer::IsRemoteTracingDone() {
52 344353 : return !InUse() || remote_tracer_->IsTracingDone();
53 : }
54 :
55 7 : void LocalEmbedderHeapTracer::SetEmbedderStackStateForNextFinalization(
56 : EmbedderHeapTracer::EmbedderStackState stack_state) {
57 7 : if (!InUse()) return;
58 :
59 7 : embedder_stack_state_ = stack_state;
60 : }
61 :
62 136 : LocalEmbedderHeapTracer::ProcessingScope::ProcessingScope(
63 : LocalEmbedderHeapTracer* tracer)
64 136 : : tracer_(tracer) {
65 136 : wrapper_cache_.reserve(kWrapperCacheSize);
66 136 : }
67 :
68 272 : LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope() {
69 136 : if (!wrapper_cache_.empty()) {
70 16 : tracer_->remote_tracer()->RegisterV8References(std::move(wrapper_cache_));
71 : }
72 136 : }
73 :
74 35 : void LocalEmbedderHeapTracer::ProcessingScope::TracePossibleWrapper(
75 : JSObject js_object) {
76 : DCHECK(js_object->IsApiWrapper());
77 35 : if (js_object->GetEmbedderFieldCount() < 2) return;
78 :
79 : void* pointer0;
80 : void* pointer1;
81 50 : if (EmbedderDataSlot(js_object, 0).ToAlignedPointer(&pointer0) && pointer0 &&
82 : EmbedderDataSlot(js_object, 1).ToAlignedPointer(&pointer1)) {
83 30 : wrapper_cache_.push_back({pointer0, pointer1});
84 : }
85 35 : FlushWrapperCacheIfFull();
86 : }
87 :
88 36 : void LocalEmbedderHeapTracer::ProcessingScope::FlushWrapperCacheIfFull() {
89 36 : 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 36 : }
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 121996 : } // namespace v8
|