1 // Copyright 2017 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 #ifndef V8_WASM_WASM_ENGINE_H_ 6 #define V8_WASM_WASM_ENGINE_H_ 7 8 #include <memory> 9 10 #include "src/wasm/wasm-code-manager.h" 11 #include "src/wasm/wasm-memory.h" 12 #include "src/wasm/wasm-tier.h" 13 #include "src/zone/accounting-allocator.h" 14 15 namespace v8 { 16 namespace internal { 17 18 class CodeTracer; 19 class CompilationStatistics; 20 class WasmModuleObject; 21 class WasmInstanceObject; 22 23 namespace wasm { 24 25 class ErrorThrower; 26 struct WasmFeatures; 27 struct ModuleWireBytes; 28 29 class V8_EXPORT_PRIVATE CompilationResultResolver { 30 public: 31 virtual void OnCompilationSucceeded(Handle<WasmModuleObject> result) = 0; 32 virtual void OnCompilationFailed(Handle<Object> error_reason) = 0; ~CompilationResultResolver()33 virtual ~CompilationResultResolver() {} 34 }; 35 36 class V8_EXPORT_PRIVATE InstantiationResultResolver { 37 public: 38 virtual void OnInstantiationSucceeded(Handle<WasmInstanceObject> result) = 0; 39 virtual void OnInstantiationFailed(Handle<Object> error_reason) = 0; ~InstantiationResultResolver()40 virtual ~InstantiationResultResolver() {} 41 }; 42 43 // The central data structure that represents an engine instance capable of 44 // loading, instantiating, and executing WASM code. 45 class V8_EXPORT_PRIVATE WasmEngine { 46 public: 47 WasmEngine(); 48 ~WasmEngine(); 49 50 // Synchronously validates the given bytes that represent an encoded WASM 51 // module. 52 bool SyncValidate(Isolate* isolate, const WasmFeatures& enabled, 53 const ModuleWireBytes& bytes); 54 55 // Synchronously compiles the given bytes that represent a translated 56 // asm.js module. 57 MaybeHandle<WasmModuleObject> SyncCompileTranslatedAsmJs( 58 Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, 59 Handle<Script> asm_js_script, 60 Vector<const byte> asm_js_offset_table_bytes); 61 62 // Synchronously compiles the given bytes that represent an encoded WASM 63 // module. 64 MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate, 65 const WasmFeatures& enabled, 66 ErrorThrower* thrower, 67 const ModuleWireBytes& bytes); 68 69 // Synchronously instantiate the given WASM module with the given imports. 70 // If the module represents an asm.js module, then the supplied {memory} 71 // should be used as the memory of the instance. 72 MaybeHandle<WasmInstanceObject> SyncInstantiate( 73 Isolate* isolate, ErrorThrower* thrower, 74 Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports, 75 MaybeHandle<JSArrayBuffer> memory); 76 77 // Begin an asynchronous compilation of the given bytes that represent an 78 // encoded WASM module. 79 // The {is_shared} flag indicates if the bytes backing the module could 80 // be shared across threads, i.e. could be concurrently modified. 81 void AsyncCompile(Isolate* isolate, const WasmFeatures& enabled, 82 std::shared_ptr<CompilationResultResolver> resolver, 83 const ModuleWireBytes& bytes, bool is_shared); 84 85 // Begin an asynchronous instantiation of the given WASM module. 86 void AsyncInstantiate(Isolate* isolate, 87 std::unique_ptr<InstantiationResultResolver> resolver, 88 Handle<WasmModuleObject> module_object, 89 MaybeHandle<JSReceiver> imports); 90 91 std::shared_ptr<StreamingDecoder> StartStreamingCompilation( 92 Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context, 93 std::shared_ptr<CompilationResultResolver> resolver); 94 95 // Compiles the function with the given index at a specific compilation tier 96 // and returns true on success, false (and pending exception) otherwise. This 97 // is mostly used for testing to force a function into a specific tier. 98 bool CompileFunction(Isolate* isolate, NativeModule* native_module, 99 uint32_t function_index, ExecutionTier tier); 100 101 // Exports the sharable parts of the given module object so that they can be 102 // transferred to a different Context/Isolate using the same engine. 103 std::shared_ptr<NativeModule> ExportNativeModule( 104 Handle<WasmModuleObject> module_object); 105 106 // Imports the shared part of a module from a different Context/Isolate using 107 // the the same engine, recreating a full module object in the given Isolate. 108 Handle<WasmModuleObject> ImportNativeModule( 109 Isolate* isolate, std::shared_ptr<NativeModule> shared_module); 110 code_manager()111 WasmCodeManager* code_manager() { return &code_manager_; } 112 memory_tracker()113 WasmMemoryTracker* memory_tracker() { return &memory_tracker_; } 114 allocator()115 AccountingAllocator* allocator() { return &allocator_; } 116 117 // Compilation statistics for TurboFan compilations. 118 CompilationStatistics* GetOrCreateTurboStatistics(); 119 120 // Prints the gathered compilation statistics, then resets them. 121 void DumpAndResetTurboStatistics(); 122 123 // Used to redirect tracing output from {stdout} to a file. 124 CodeTracer* GetCodeTracer(); 125 126 // Remove {job} from the list of active compile jobs. 127 std::unique_ptr<AsyncCompileJob> RemoveCompileJob(AsyncCompileJob* job); 128 129 // Returns true if at least one AsyncCompileJob that belongs to the given 130 // Isolate is currently running. 131 bool HasRunningCompileJob(Isolate* isolate); 132 133 // Deletes all AsyncCompileJobs that belong to the given Isolate. All 134 // compilation is aborted, no more callbacks will be triggered. This is used 135 // for tearing down an isolate, or to clean it up to be reused. 136 void DeleteCompileJobsOnIsolate(Isolate* isolate); 137 138 // Call on process start and exit. 139 static void InitializeOncePerProcess(); 140 static void GlobalTearDown(); 141 142 // Constructs a WasmEngine instance. Depending on whether we are sharing 143 // engines this might be a pointer to a new instance or to a shared one. 144 static std::shared_ptr<WasmEngine> GetWasmEngine(); 145 146 private: 147 AsyncCompileJob* CreateAsyncCompileJob( 148 Isolate* isolate, const WasmFeatures& enabled, 149 std::unique_ptr<byte[]> bytes_copy, size_t length, 150 Handle<Context> context, 151 std::shared_ptr<CompilationResultResolver> resolver); 152 153 WasmMemoryTracker memory_tracker_; 154 WasmCodeManager code_manager_; 155 AccountingAllocator allocator_; 156 157 // This mutex protects all information which is mutated concurrently or 158 // fields that are initialized lazily on the first access. 159 base::Mutex mutex_; 160 161 ////////////////////////////////////////////////////////////////////////////// 162 // Protected by {mutex_}: 163 164 // We use an AsyncCompileJob as the key for itself so that we can delete the 165 // job from the map when it is finished. 166 std::unordered_map<AsyncCompileJob*, std::unique_ptr<AsyncCompileJob>> jobs_; 167 168 std::unique_ptr<CompilationStatistics> compilation_stats_; 169 std::unique_ptr<CodeTracer> code_tracer_; 170 171 // End of fields protected by {mutex_}. 172 ////////////////////////////////////////////////////////////////////////////// 173 174 DISALLOW_COPY_AND_ASSIGN(WasmEngine); 175 }; 176 177 } // namespace wasm 178 } // namespace internal 179 } // namespace v8 180 181 #endif // V8_WASM_WASM_ENGINE_H_ 182