v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
v8.cc
Go to the documentation of this file.
1// Copyright 2012 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/init/v8.h"
6
7#include <fstream>
8
10#include "include/v8-sandbox.h"
11#include "src/api/api.h"
12#include "src/base/atomicops.h"
13#include "src/base/once.h"
18#include "src/debug/debug.h"
23#include "src/flags/flags.h"
30#include "src/sandbox/sandbox.h"
31#include "src/sandbox/testing.h"
33#if defined(V8_USE_PERFETTO)
35#endif // defined(V8_USE_PERFETTO)
37
38#if V8_ENABLE_WEBASSEMBLY
40#endif // V8_ENABLE_WEBASSEMBLY
41
42#if defined(V8_ENABLE_ETW_STACK_WALKING)
44#endif // V8_ENABLE_ETW_STACK_WALKING
45
46namespace v8 {
47namespace internal {
48
49// static
51const OOMDetails V8::kNoOOMDetails{false, nullptr};
52const OOMDetails V8::kHeapOOM{true, nullptr};
53
54namespace {
55enum class V8StartupState {
56 kIdle,
57 kPlatformInitializing,
58 kPlatformInitialized,
59 kV8Initializing,
60 kV8Initialized,
61 kV8Disposing,
62 kV8Disposed,
63 kPlatformDisposing,
64 kPlatformDisposed
65};
66
67std::atomic<V8StartupState> v8_startup_state_(V8StartupState::kIdle);
68
69void AdvanceStartupState(V8StartupState expected_next_state) {
70 V8StartupState current_state = v8_startup_state_;
71 CHECK_NE(current_state, V8StartupState::kPlatformDisposed);
72 V8StartupState next_state =
73 static_cast<V8StartupState>(static_cast<int>(current_state) + 1);
74 if (next_state != expected_next_state) {
75 // Ensure the following order:
76 // v8::V8::InitializePlatform(platform);
77 // v8::V8::Initialize();
78 // v8::Isolate* isolate = v8::Isolate::New(...);
79 // ...
80 // isolate->Dispose();
81 // v8::V8::Dispose();
82 // v8::V8::DisposePlatform();
83 FATAL("Wrong initialization order: from %d to %d, expected to %d!",
84 static_cast<int>(current_state), static_cast<int>(next_state),
85 static_cast<int>(expected_next_state));
86 }
87 if (!v8_startup_state_.compare_exchange_strong(current_state, next_state)) {
88 FATAL(
89 "Multiple threads are initializating V8 in the wrong order: expected "
90 "%d got %d!",
91 static_cast<int>(current_state),
92 static_cast<int>(v8_startup_state_.load()));
93 }
94}
95
96} // namespace
97
98#ifdef V8_USE_EXTERNAL_STARTUP_DATA
99V8_DECLARE_ONCE(init_snapshot_once);
100#endif
101
102// static
104 AdvanceStartupState(V8StartupState::kPlatformInitializing);
106 CHECK_NOT_NULL(platform);
107 platform_ = platform;
110#if defined(V8_ENABLE_ETW_STACK_WALKING)
111 if (v8_flags.enable_etw_stack_walking ||
112 v8_flags.enable_etw_by_custom_filter_only) {
114 }
115#endif // V8_ENABLE_ETW_STACK_WALKING
116
117 // Initialization needs to happen on platform-level, as this sets up some
118 // cppgc internals that are needed to allow gracefully failing during cppgc
119 // platform setup.
121
122 AdvanceStartupState(V8StartupState::kPlatformInitialized);
123}
124
125// static
127 if (v8_startup_state_ != V8StartupState::kIdle) {
128 FATAL(
129 "The platform was initialized before. Note that running multiple tests "
130 "in the same process is not supported.");
131 }
132 V8::InitializePlatform(platform);
133}
134
136 AdvanceStartupState(V8StartupState::kV8Initializing);
138
140
141 // Initialize the default FlagList::Hash.
143
144 // Before initializing internals, freeze the flags such that further changes
145 // are not allowed. Global initialization of the Isolate or the WasmEngine
146 // already reads flags, so they should not be changed afterwards.
147 if (v8_flags.freeze_flags_after_init) FlagList::FreezeFlags();
148
149 if (v8_flags.trace_turbo) {
150 // Create an empty file shared by the process (e.g. the wasm engine).
151 std::ofstream(Isolate::GetTurboCfgFileName(nullptr).c_str(),
152 std::ios_base::trunc);
153 }
154
155 // The --jitless and --interpreted-frames-native-stack flags are incompatible
156 // since the latter requires code generation while the former prohibits code
157 // generation.
158 CHECK(!v8_flags.interpreted_frames_native_stack || !v8_flags.jitless);
159
161
162 if (v8_flags.sandbox_fuzzing || v8_flags.hole_fuzzing) {
163 // In this mode, controlled crashes are harmless. Furthermore, DCHECK
164 // failures should be ignored (and execution should continue past them) as
165 // they may otherwise hide issues.
167 } else if (v8_flags.sandbox_testing) {
168 // Similar to the above case, but here we want to exit with a status
169 // indicating success (e.g. zero on unix). This is useful for example for
170 // sandbox regression tests, which should "pass" if they crash in a
171 // controlled fashion (e.g. in a SBXCHECK).
173 } else if (v8_flags.hard_abort) {
175 }
176
177 base::OS::Initialize(abort_mode, v8_flags.gc_fake_mmap);
178
179 if (v8_flags.random_seed) {
182 }
183
184 if (v8_flags.print_flag_values) FlagList::PrintValues();
185
186 // Fetch the ThreadIsolatedAllocator once since we need to keep the pointer in
187 // protected memory.
189 GetCurrentPlatform()->GetThreadIsolatedAllocator());
190
191#ifdef V8_ENABLE_SANDBOX
192 // If enabled, the sandbox must be initialized first.
193 Sandbox::InitializeDefaultOncePerProcess(GetPlatformVirtualAddressSpace());
194 CHECK_EQ(kSandboxSize, Sandbox::current()->size());
195
196 // Enable sandbox testing mode if requested.
197 //
198 // This will install the sandbox crash filter to ignore all crashes that do
199 // not represent sandbox violations.
200 //
201 // Note: this should happen before the Wasm trap handler is installed, so that
202 // the wasm trap handler is invoked first (and can handle Wasm OOB accesses),
203 // then forwards all "real" crashes to the sandbox crash filter.
204 if (v8_flags.sandbox_testing || v8_flags.sandbox_fuzzing) {
205 SandboxTesting::Mode mode = v8_flags.sandbox_testing
206 ? SandboxTesting::Mode::kForTesting
207 : SandboxTesting::Mode::kForFuzzing;
208 SandboxTesting::Enable(mode);
209 }
210#endif // V8_ENABLE_SANDBOX
211
212#if defined(V8_USE_PERFETTO)
213 if (perfetto::Tracing::IsInitialized()) {
214 TrackEvent::Register();
215 if (v8_flags.perfetto_code_logger) {
217 }
218 }
219#endif
222
223#if defined(USE_SIMULATOR)
224 Simulator::InitializeOncePerProcess();
225#endif
226 CpuFeatures::Probe(false);
230
231#if V8_ENABLE_WEBASSEMBLY
233#endif // V8_ENABLE_WEBASSEMBLY
234
236 IsolateGroup::current()->external_ref_table());
237 AdvanceStartupState(V8StartupState::kV8Initialized);
238}
239
241 AdvanceStartupState(V8StartupState::kV8Disposing);
243#if V8_ENABLE_WEBASSEMBLY
245#endif // V8_ENABLE_WEBASSEMBLY
246#if defined(USE_SIMULATOR)
247 Simulator::GlobalTearDown();
248#endif
254 AdvanceStartupState(V8StartupState::kV8Disposed);
255}
256
258 AdvanceStartupState(V8StartupState::kPlatformDisposing);
260#if defined(V8_OS_WIN) && defined(V8_ENABLE_ETW_STACK_WALKING)
261 if (v8_flags.enable_etw_stack_walking ||
262 v8_flags.enable_etw_by_custom_filter_only) {
264 }
265#endif
268
269#ifdef V8_ENABLE_SANDBOX
270 Sandbox::TearDownDefault();
271#endif // V8_ENABLE_SANDBOX
272
273 platform_ = nullptr;
274
275#if DEBUG
276 internal::ThreadIsolation::CheckTrackedMemoryEmpty();
277#endif
278
279 AdvanceStartupState(V8StartupState::kPlatformDisposed);
280}
281
283 v8::Platform* platform = reinterpret_cast<v8::Platform*>(
284 base::Relaxed_Load(reinterpret_cast<base::AtomicWord*>(&platform_)));
285 DCHECK(platform);
286 return platform;
287}
288
291 reinterpret_cast<base::AtomicWord>(platform));
292}
293
294void V8::SetSnapshotBlob(StartupData* snapshot_blob) {
295#ifdef V8_USE_EXTERNAL_STARTUP_DATA
296 base::CallOnce(&init_snapshot_once, &SetSnapshotFromFile, snapshot_blob);
297#else
298 UNREACHABLE();
299#endif
300}
301} // namespace internal
302
303// static
307
308// static
310#if V8_HAS_PKU_JIT_WRITE_PROTECT
311 internal::RwxMemoryWriteScope::SetDefaultPermissionsForSignalHandler();
312#endif
313 // TODO(sroettger): this could move to a more generic
314 // SecurityHardwareSupport::SetDefaultPermissionsForSignalHandler.
316}
317
318// static
322
323} // namespace v8
virtual void SetRandomMmapSeed(int64_t seed)=0
virtual StackTracePrinter GetStackTracePrinter()
static V8_EXPORT double SystemClockTimeMillis()
Definition v8.cc:304
static void UnregisterAll()
Definition api.cc:460
static V8_EXPORT void InitializeBeforeThreadCreation()
Definition v8.cc:319
static void SetDefaultPermissionsForSignalHandler()
Definition v8.cc:309
virtual void SetRandomSeed(int64_t seed)=0
static void Initialize(AbortMode abort_mode, const char *const gc_fake_mmap)
static double TimeCurrentMillis()
static void InitializeOncePerProcess()
static void InitializeOncePerProcess()
Definition cpp-heap.cc:488
static void Probe(bool cross_compile)
static void InitializeOncePerProcess()
Definition elements.cc:5728
static void InitializeOncePerIsolateGroup(MemorySpan< Address > shared_external_references)
static uint32_t Hash()
Definition flags.cc:1196
static void EnforceFlagImplications()
Definition flags.cc:1188
static void PrintValues()
Definition flags.cc:865
static void ReleaseDynamicAllocations()
Definition flags.cc:834
static void FreezeFlags()
Definition flags.cc:817
static void TearDownOncePerProcess()
static IsolateGroup * current()
static void InitializeOncePerProcess()
static void InitializeOncePerProcess()
Definition isolate.cc:583
static std::string GetTurboCfgFileName(Isolate *isolate)
Definition isolate.cc:7057
static void Initialize(ThreadIsolatedAllocator *allocator)
static V8_EXPORT_PRIVATE void SetPlatformForTesting(v8::Platform *platform)
Definition v8.cc:289
static v8::Platform * platform_
Definition v8.h:57
static V8_EXPORT_PRIVATE const OOMDetails kNoOOMDetails
Definition v8.h:36
static void SetSnapshotBlob(StartupData *snapshot_blob)
Definition v8.cc:294
static V8_EXPORT_PRIVATE void InitializePlatformForTesting(v8::Platform *platform)
Definition v8.cc:126
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
Definition v8.cc:282
static void InitializePlatform(v8::Platform *platform)
Definition v8.cc:103
static void DisposePlatform()
Definition v8.cc:257
static V8_EXPORT_PRIVATE const OOMDetails kHeapOOM
Definition v8.h:37
static void Initialize()
Definition v8.cc:135
static void Dispose()
Definition v8.cc:240
void Relaxed_Store(volatile Atomic8 *ptr, Atomic8 value)
Definition atomicops.h:189
Atomic32 AtomicWord
Definition atomicops.h:76
Atomic8 Relaxed_Load(volatile const Atomic8 *ptr)
Definition atomicops.h:234
@ kExitWithFailureAndIgnoreDcheckFailures
@ kExitWithSuccessAndIgnoreDcheckFailures
void CallOnce(OnceType *once, std::function< void()> init_func)
Definition once.h:90
void SetPrintStackTrace(void(*print_stack_trace)())
Definition logging.cc:68
v8::PageAllocator * GetPlatformPageAllocator()
Definition allocation.cc:66
v8::VirtualAddressSpace * GetPlatformVirtualAddressSpace()
Definition allocation.cc:71
V8_EXPORT_PRIVATE FlagValues v8_flags
void SetSnapshotFromFile(StartupData *snapshot_blob)
#define V8_DECLARE_ONCE(NAME)
Definition once.h:72
#define FATAL(...)
Definition logging.h:47
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NOT_NULL(val)
#define CHECK_NE(lhs, rhs)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482