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 9 #include "src/api/api.h" 10 #include "src/base/atomicops.h" 11 #include "src/base/once.h" 12 #include "src/base/platform/platform.h" 13 #include "src/codegen/cpu-features.h" 14 #include "src/codegen/interface-descriptors.h" 15 #include "src/debug/debug.h" 16 #include "src/deoptimizer/deoptimizer.h" 17 #include "src/execution/frames.h" 18 #include "src/execution/isolate.h" 19 #include "src/execution/runtime-profiler.h" 20 #include "src/execution/simulator.h" 21 #include "src/init/bootstrapper.h" 22 #include "src/libsampler/sampler.h" 23 #include "src/objects/elements.h" 24 #include "src/objects/objects-inl.h" 25 #include "src/profiler/heap-profiler.h" 26 #include "src/snapshot/snapshot.h" 27 #include "src/tracing/tracing-category-observer.h" 28 #include "src/wasm/wasm-engine.h" 29 30 namespace v8 { 31 namespace internal { 32 33 V8_DECLARE_ONCE(init_once); 34 35 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 36 V8_DECLARE_ONCE(init_natives_once); 37 V8_DECLARE_ONCE(init_snapshot_once); 38 #endif 39 40 v8::Platform* V8::platform_ = nullptr; 41 Initialize()42bool V8::Initialize() { 43 InitializeOncePerProcess(); 44 return true; 45 } 46 TearDown()47void V8::TearDown() { 48 wasm::WasmEngine::GlobalTearDown(); 49 #if defined(USE_SIMULATOR) 50 Simulator::GlobalTearDown(); 51 #endif 52 CallDescriptors::TearDown(); 53 ElementsAccessor::TearDown(); 54 RegisteredExtension::UnregisterAll(); 55 FlagList::ResetAllFlags(); // Frees memory held by string arguments. 56 } 57 InitializeOncePerProcessImpl()58void V8::InitializeOncePerProcessImpl() { 59 FlagList::EnforceFlagImplications(); 60 61 if (FLAG_predictable && FLAG_random_seed == 0) { 62 // Avoid random seeds in predictable mode. 63 FLAG_random_seed = 12347; 64 } 65 66 if (FLAG_stress_compaction) { 67 FLAG_force_marking_deque_overflows = true; 68 FLAG_gc_global = true; 69 FLAG_max_semi_space_size = 1; 70 } 71 72 if (FLAG_trace_turbo) { 73 // Create an empty file shared by the process (e.g. the wasm engine). 74 std::ofstream(Isolate::GetTurboCfgFileName(nullptr).c_str(), 75 std::ios_base::trunc); 76 } 77 78 // Do not expose wasm in jitless mode. 79 // 80 // Even in interpreter-only mode, wasm currently still creates executable 81 // memory at runtime. Unexpose wasm until this changes. 82 // The correctness fuzzers are a special case: many of their test cases are 83 // built by fetching a random property from the the global object, and thus 84 // the global object layout must not change between configs. That is why we 85 // continue exposing wasm on correctness fuzzers even in jitless mode. 86 // TODO(jgruber): Remove this once / if wasm can run without executable 87 // memory. 88 if (FLAG_jitless && !FLAG_correctness_fuzzer_suppressions) { 89 FLAG_expose_wasm = false; 90 } 91 92 if (FLAG_regexp_interpret_all && FLAG_regexp_tier_up) { 93 // Turning off the tier-up strategy, because the --regexp-interpret-all and 94 // --regexp-tier-up flags are incompatible. 95 FLAG_regexp_tier_up = false; 96 } 97 98 // The --jitless and --interpreted-frames-native-stack flags are incompatible 99 // since the latter requires code generation while the former prohibits code 100 // generation. 101 CHECK(!FLAG_interpreted_frames_native_stack || !FLAG_jitless); 102 103 base::OS::Initialize(FLAG_hard_abort, FLAG_gc_fake_mmap); 104 105 if (FLAG_random_seed) SetRandomMmapSeed(FLAG_random_seed); 106 107 #if defined(V8_USE_PERFETTO) 108 TrackEvent::Register(); 109 #endif 110 Isolate::InitializeOncePerProcess(); 111 112 #if defined(USE_SIMULATOR) 113 Simulator::InitializeOncePerProcess(); 114 #endif 115 CpuFeatures::Probe(false); 116 ElementsAccessor::InitializeOncePerProcess(); 117 Bootstrapper::InitializeOncePerProcess(); 118 CallDescriptors::InitializeOncePerProcess(); 119 wasm::WasmEngine::InitializeOncePerProcess(); 120 } 121 InitializeOncePerProcess()122void V8::InitializeOncePerProcess() { 123 base::CallOnce(&init_once, &InitializeOncePerProcessImpl); 124 } 125 InitializePlatform(v8::Platform * platform)126void V8::InitializePlatform(v8::Platform* platform) { 127 CHECK(!platform_); 128 CHECK(platform); 129 platform_ = platform; 130 v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter()); 131 v8::tracing::TracingCategoryObserver::SetUp(); 132 } 133 ShutdownPlatform()134void V8::ShutdownPlatform() { 135 CHECK(platform_); 136 v8::tracing::TracingCategoryObserver::TearDown(); 137 v8::base::SetPrintStackTrace(nullptr); 138 platform_ = nullptr; 139 } 140 GetCurrentPlatform()141v8::Platform* V8::GetCurrentPlatform() { 142 v8::Platform* platform = reinterpret_cast<v8::Platform*>( 143 base::Relaxed_Load(reinterpret_cast<base::AtomicWord*>(&platform_))); 144 DCHECK(platform); 145 return platform; 146 } 147 SetPlatformForTesting(v8::Platform * platform)148void V8::SetPlatformForTesting(v8::Platform* platform) { 149 base::Relaxed_Store(reinterpret_cast<base::AtomicWord*>(&platform_), 150 reinterpret_cast<base::AtomicWord>(platform)); 151 } 152 SetSnapshotBlob(StartupData * snapshot_blob)153void V8::SetSnapshotBlob(StartupData* snapshot_blob) { 154 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 155 base::CallOnce(&init_snapshot_once, &SetSnapshotFromFile, snapshot_blob); 156 #else 157 UNREACHABLE(); 158 #endif 159 } 160 } // namespace internal 161 162 // static SystemClockTimeMillis()163double Platform::SystemClockTimeMillis() { 164 return base::OS::TimeCurrentMillis(); 165 } 166 } // namespace v8 167