-
Notifications
You must be signed in to change notification settings - Fork 17k
Expand file tree
/
Copy pathjavascript_environment.cc
More file actions
164 lines (137 loc) · 5.75 KB
/
javascript_environment.cc
File metadata and controls
164 lines (137 loc) · 5.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "shell/browser/javascript_environment.h"
#include <memory>
#include <string>
#include <utility>
#include "base/allocator/partition_alloc_features.h"
#include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc.h"
#include "base/bits.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool/initialization_util.h"
#include "gin/array_buffer.h"
#include "gin/v8_initializer.h"
#include "shell/browser/microtasks_runner.h"
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
#include "shell/common/node_includes.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/electron_node/src/node_wasm_web_api.h"
namespace {
v8::Isolate* g_isolate;
}
namespace electron {
namespace {
std::unique_ptr<gin::IsolateHolder> CreateIsolateHolder(
v8::Isolate* isolate,
size_t* max_young_generation_size) {
std::unique_ptr<v8::Isolate::CreateParams> create_params =
gin::IsolateHolder::getDefaultIsolateParams();
// The value is needed to adjust heap limit when capturing
// snapshot via v8.setHeapSnapshotNearHeapLimit(limit) or
// --heapsnapshot-near-heap-limit=max_count.
*max_young_generation_size =
create_params->constraints.max_young_generation_size_in_bytes();
// Align behavior with V8 Isolate default for Node.js.
// This is necessary for important aspects of Node.js
// including heap and cpu profilers to function properly.
return std::make_unique<gin::IsolateHolder>(
base::SingleThreadTaskRunner::GetCurrentDefault(),
gin::IsolateHolder::kSingleThread,
gin::IsolateHolder::IsolateType::kUtility, std::move(create_params),
gin::IsolateHolder::IsolateCreationMode::kNormal, nullptr, nullptr,
isolate);
}
} // namespace
JavascriptEnvironment::JavascriptEnvironment(uv_loop_t* event_loop,
bool setup_wasm_streaming)
: isolate_holder_{CreateIsolateHolder(
Initialize(event_loop, setup_wasm_streaming),
&max_young_generation_size_)},
isolate_{isolate_holder_->isolate()},
locker_{std::make_unique<v8::Locker>(isolate_)} {
isolate_->Enter();
v8::HandleScope scope(isolate_);
auto context = node::NewContext(isolate_);
CHECK(!context.IsEmpty());
context->Enter();
}
JavascriptEnvironment::~JavascriptEnvironment() {
DCHECK_NE(platform_, nullptr);
{
v8::HandleScope scope(isolate_);
isolate_->GetCurrentContext()->Exit();
}
isolate_->Exit();
g_isolate = nullptr;
// Deinit gin::IsolateHolder prior to calling NodePlatform::UnregisterIsolate.
// Otherwise cppgc::internal::Sweeper::Start will try to request a task runner
// from the NodePlatform with an already unregistered isolate.
locker_.reset();
isolate_holder_.reset();
platform_->UnregisterIsolate(isolate_);
}
v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop,
bool setup_wasm_streaming) {
auto* cmd = base::CommandLine::ForCurrentProcess();
// --js-flags.
std::string js_flags = "--no-freeze-flags-after-init ";
js_flags.append(cmd->GetSwitchValueASCII(blink::switches::kJavaScriptFlags));
v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());
// The V8Platform of gin relies on Chromium's task schedule, which has not
// been started at this point, so we have to rely on Node's V8Platform.
auto* tracing_agent = new node::tracing::Agent();
auto* tracing_controller = tracing_agent->GetTracingController();
node::tracing::TraceEventHelper::SetAgent(tracing_agent);
platform_ = node::MultiIsolatePlatform::Create(
base::RecommendedMaxNumberOfThreadsInThreadGroup(3, 8, 0.1, 0),
tracing_controller, gin::V8Platform::GetCurrentPageAllocator());
v8::V8::InitializePlatform(platform_.get());
gin::IsolateHolder::Initialize(
gin::IsolateHolder::kNonStrictMode,
gin::ArrayBufferAllocator::SharedInstance(),
nullptr /* external_reference_table */, js_flags,
false /* disallow_v8_feature_flag_overrides */,
nullptr /* fatal_error_callback */, nullptr /* oom_error_callback */,
false /* create_v8_platform */);
v8::Isolate* isolate = v8::Isolate::Allocate();
platform_->RegisterIsolate(isolate, event_loop);
// This is done here because V8 checks for the callback in NewContext.
// Our setup order doesn't allow for calling SetupIsolateForNode
// before NewContext without polluting JavaScriptEnvironment with
// Node.js logic and so we conditionally do it here to keep
// concerns separate.
if (setup_wasm_streaming) {
isolate->SetWasmStreamingCallback(
node::wasm_web_api::StartStreamingCompilation);
}
g_isolate = isolate;
return isolate;
}
// static
v8::Isolate* JavascriptEnvironment::GetIsolate() {
CHECK(g_isolate);
return g_isolate;
}
void JavascriptEnvironment::CreateMicrotasksRunner() {
DCHECK(!microtasks_runner_);
microtasks_runner_ = std::make_unique<MicrotasksRunner>(isolate());
isolate_holder_->WillCreateMicrotasksRunner();
base::CurrentThread::Get()->AddTaskObserver(microtasks_runner_.get());
}
void JavascriptEnvironment::DestroyMicrotasksRunner() {
DCHECK(microtasks_runner_);
// Should be called before running gin_helper::CleanedUpAtExit::DoCleanup.
// This helps to signal wrappable finalizer callbacks to not act on freed
// parameters.
isolate_holder_->WillDestroyMicrotasksRunner();
{
v8::HandleScope scope(isolate_);
gin_helper::CleanedUpAtExit::DoCleanup();
}
base::CurrentThread::Get()->RemoveTaskObserver(microtasks_runner_.get());
}
} // namespace electron