2018-01-17 14:46:27 +00:00
|
|
|
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "src/wasm/wasm-engine.h"
|
2018-01-31 14:58:12 +00:00
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
#include "src/code-tracer.h"
|
2018-07-10 13:15:29 +00:00
|
|
|
#include "src/compilation-statistics.h"
|
2018-01-17 14:46:27 +00:00
|
|
|
#include "src/objects-inl.h"
|
2018-12-25 00:19:47 +00:00
|
|
|
#include "src/objects/heap-number.h"
|
2018-05-23 13:29:02 +00:00
|
|
|
#include "src/objects/js-promise.h"
|
2018-08-17 12:35:29 +00:00
|
|
|
#include "src/wasm/function-compiler.h"
|
2018-01-17 14:46:27 +00:00
|
|
|
#include "src/wasm/module-compiler.h"
|
2018-04-27 13:38:40 +00:00
|
|
|
#include "src/wasm/module-decoder.h"
|
|
|
|
#include "src/wasm/streaming-decoder.h"
|
2018-07-31 08:16:22 +00:00
|
|
|
#include "src/wasm/wasm-objects-inl.h"
|
2018-01-17 14:46:27 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
namespace wasm {
|
|
|
|
|
2018-09-18 13:05:45 +00:00
|
|
|
WasmEngine::WasmEngine()
|
|
|
|
: code_manager_(&memory_tracker_, kMaxWasmCodeMemory) {}
|
2018-07-10 13:15:29 +00:00
|
|
|
|
2018-08-01 11:18:46 +00:00
|
|
|
WasmEngine::~WasmEngine() {
|
|
|
|
// All AsyncCompileJobs have been canceled.
|
|
|
|
DCHECK(jobs_.empty());
|
2018-09-25 11:24:09 +00:00
|
|
|
// All Isolates have been deregistered.
|
|
|
|
DCHECK(isolates_.empty());
|
2018-08-01 11:18:46 +00:00
|
|
|
}
|
2018-07-10 13:15:29 +00:00
|
|
|
|
2018-08-08 14:54:44 +00:00
|
|
|
bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
|
|
|
|
const ModuleWireBytes& bytes) {
|
2018-01-17 14:46:27 +00:00
|
|
|
// TODO(titzer): remove dependency on the isolate.
|
|
|
|
if (bytes.start() == nullptr || bytes.length() == 0) return false;
|
2018-07-20 12:55:40 +00:00
|
|
|
ModuleResult result =
|
2018-08-08 14:54:44 +00:00
|
|
|
DecodeWasmModule(enabled, bytes.start(), bytes.end(), true, kWasmOrigin,
|
2018-07-20 12:55:40 +00:00
|
|
|
isolate->counters(), allocator());
|
2018-01-17 14:46:27 +00:00
|
|
|
return result.ok();
|
|
|
|
}
|
|
|
|
|
2018-11-21 21:19:18 +00:00
|
|
|
MaybeHandle<AsmWasmData> WasmEngine::SyncCompileTranslatedAsmJs(
|
2018-01-18 10:52:52 +00:00
|
|
|
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
|
2018-11-21 21:19:18 +00:00
|
|
|
Vector<const byte> asm_js_offset_table_bytes,
|
|
|
|
Handle<HeapNumber> uses_bitset) {
|
2018-07-20 12:55:40 +00:00
|
|
|
ModuleResult result =
|
2018-08-08 14:54:44 +00:00
|
|
|
DecodeWasmModule(kAsmjsWasmFeatures, bytes.start(), bytes.end(), false,
|
|
|
|
kAsmJsOrigin, isolate->counters(), allocator());
|
2018-01-18 10:52:52 +00:00
|
|
|
CHECK(!result.failed());
|
|
|
|
|
2018-04-27 09:01:06 +00:00
|
|
|
// Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated
|
2018-11-21 21:19:18 +00:00
|
|
|
// in {CompileToNativeModule}.
|
|
|
|
Handle<FixedArray> export_wrappers;
|
|
|
|
std::unique_ptr<NativeModule> native_module =
|
|
|
|
CompileToNativeModule(isolate, kAsmjsWasmFeatures, thrower,
|
|
|
|
std::move(result).value(), bytes, &export_wrappers);
|
|
|
|
if (!native_module) return {};
|
|
|
|
|
|
|
|
// Create heap objects for asm.js offset table to be stored in the module
|
|
|
|
// object.
|
|
|
|
Handle<ByteArray> asm_js_offset_table =
|
|
|
|
isolate->factory()->NewByteArray(asm_js_offset_table_bytes.length());
|
|
|
|
asm_js_offset_table->copy_in(0, asm_js_offset_table_bytes.start(),
|
|
|
|
asm_js_offset_table_bytes.length());
|
|
|
|
|
|
|
|
return AsmWasmData::New(isolate, std::move(native_module), export_wrappers,
|
|
|
|
asm_js_offset_table, uses_bitset);
|
|
|
|
}
|
|
|
|
|
|
|
|
Handle<WasmModuleObject> WasmEngine::FinalizeTranslatedAsmJs(
|
|
|
|
Isolate* isolate, Handle<AsmWasmData> asm_wasm_data,
|
|
|
|
Handle<Script> script) {
|
|
|
|
std::shared_ptr<NativeModule> native_module =
|
|
|
|
asm_wasm_data->managed_native_module()->get();
|
|
|
|
Handle<FixedArray> export_wrappers =
|
|
|
|
handle(asm_wasm_data->export_wrappers(), isolate);
|
|
|
|
size_t code_size_estimate =
|
|
|
|
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
|
|
|
|
native_module->module());
|
|
|
|
|
|
|
|
Handle<WasmModuleObject> module_object =
|
|
|
|
WasmModuleObject::New(isolate, std::move(native_module), script,
|
|
|
|
export_wrappers, code_size_estimate);
|
|
|
|
module_object->set_asm_js_offset_table(asm_wasm_data->asm_js_offset_table());
|
|
|
|
return module_object;
|
2018-01-18 10:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled, ErrorThrower* thrower,
|
|
|
|
const ModuleWireBytes& bytes) {
|
2018-07-20 12:55:40 +00:00
|
|
|
ModuleResult result =
|
2018-08-08 14:54:44 +00:00
|
|
|
DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin,
|
2018-07-20 12:55:40 +00:00
|
|
|
isolate->counters(), allocator());
|
2018-01-18 10:52:52 +00:00
|
|
|
if (result.failed()) {
|
|
|
|
thrower->CompileFailed("Wasm decoding failed", result);
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2018-04-27 09:01:06 +00:00
|
|
|
// Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated
|
2018-01-18 10:52:52 +00:00
|
|
|
// in {CompileToModuleObject}.
|
2018-11-21 21:19:18 +00:00
|
|
|
Handle<FixedArray> export_wrappers;
|
|
|
|
std::unique_ptr<NativeModule> native_module =
|
|
|
|
CompileToNativeModule(isolate, enabled, thrower,
|
|
|
|
std::move(result).value(), bytes, &export_wrappers);
|
|
|
|
if (!native_module) return {};
|
|
|
|
|
|
|
|
Handle<Script> script =
|
|
|
|
CreateWasmScript(isolate, bytes, native_module->module()->source_map_url);
|
|
|
|
size_t code_size_estimate =
|
|
|
|
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
|
|
|
|
native_module->module());
|
|
|
|
|
|
|
|
// Create the module object.
|
|
|
|
// TODO(clemensh): For the same module (same bytes / same hash), we should
|
|
|
|
// only have one WasmModuleObject. Otherwise, we might only set
|
|
|
|
// breakpoints on a (potentially empty) subset of the instances.
|
|
|
|
|
|
|
|
// Create the compiled module object and populate with compiled functions
|
|
|
|
// and information needed at instantiation time. This object needs to be
|
|
|
|
// serializable. Instantiation may occur off a deserialized version of this
|
|
|
|
// object.
|
|
|
|
Handle<WasmModuleObject> module_object =
|
|
|
|
WasmModuleObject::New(isolate, std::move(native_module), script,
|
|
|
|
export_wrappers, code_size_estimate);
|
|
|
|
|
|
|
|
// Finish the Wasm script now and make it public to the debugger.
|
|
|
|
isolate->debug()->OnAfterCompile(script);
|
|
|
|
return module_object;
|
2018-01-18 10:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
|
|
|
|
Isolate* isolate, ErrorThrower* thrower,
|
|
|
|
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
|
|
|
|
MaybeHandle<JSArrayBuffer> memory) {
|
|
|
|
return InstantiateToInstanceObject(isolate, thrower, module_object, imports,
|
|
|
|
memory);
|
|
|
|
}
|
|
|
|
|
2018-05-24 21:22:27 +00:00
|
|
|
void WasmEngine::AsyncInstantiate(
|
|
|
|
Isolate* isolate, std::unique_ptr<InstantiationResultResolver> resolver,
|
|
|
|
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports) {
|
2018-08-07 10:00:21 +00:00
|
|
|
ErrorThrower thrower(isolate, "WebAssembly Instantiation");
|
2018-06-08 11:51:33 +00:00
|
|
|
// Instantiate a TryCatch so that caught exceptions won't progagate out.
|
|
|
|
// They will still be set as pending exceptions on the isolate.
|
|
|
|
// TODO(clemensh): Avoid TryCatch, use Execution::TryCall internally to invoke
|
|
|
|
// start function and report thrown exception explicitly via out argument.
|
|
|
|
v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
|
|
|
|
catcher.SetVerbose(false);
|
|
|
|
catcher.SetCaptureMessage(false);
|
|
|
|
|
2018-01-18 10:52:52 +00:00
|
|
|
MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
|
|
|
|
isolate, &thrower, module_object, imports, Handle<JSArrayBuffer>::null());
|
2018-06-08 11:51:33 +00:00
|
|
|
|
|
|
|
if (!instance_object.is_null()) {
|
|
|
|
resolver->OnInstantiationSucceeded(instance_object.ToHandleChecked());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-07 10:00:21 +00:00
|
|
|
if (isolate->has_pending_exception()) {
|
|
|
|
// The JS code executed during instantiation has thrown an exception.
|
|
|
|
// We have to move the exception to the promise chain.
|
2018-06-08 11:51:33 +00:00
|
|
|
Handle<Object> exception(isolate->pending_exception(), isolate);
|
|
|
|
isolate->clear_pending_exception();
|
|
|
|
DCHECK(*isolate->external_caught_exception_address());
|
|
|
|
*isolate->external_caught_exception_address() = false;
|
|
|
|
resolver->OnInstantiationFailed(exception);
|
2018-08-07 10:00:21 +00:00
|
|
|
thrower.Reset();
|
|
|
|
} else {
|
|
|
|
DCHECK(thrower.error());
|
|
|
|
resolver->OnInstantiationFailed(thrower.Reify());
|
2018-01-18 10:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-24 21:22:27 +00:00
|
|
|
void WasmEngine::AsyncCompile(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver,
|
2018-05-24 21:22:27 +00:00
|
|
|
const ModuleWireBytes& bytes, bool is_shared) {
|
2018-01-18 10:52:52 +00:00
|
|
|
if (!FLAG_wasm_async_compilation) {
|
|
|
|
// Asynchronous compilation disabled; fall back on synchronous compilation.
|
|
|
|
ErrorThrower thrower(isolate, "WasmCompile");
|
|
|
|
MaybeHandle<WasmModuleObject> module_object;
|
|
|
|
if (is_shared) {
|
|
|
|
// Make a copy of the wire bytes to avoid concurrent modification.
|
|
|
|
std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
|
|
|
|
memcpy(copy.get(), bytes.start(), bytes.length());
|
2018-08-02 09:50:08 +00:00
|
|
|
ModuleWireBytes bytes_copy(copy.get(), copy.get() + bytes.length());
|
2018-08-08 14:54:44 +00:00
|
|
|
module_object = SyncCompile(isolate, enabled, &thrower, bytes_copy);
|
2018-01-18 10:52:52 +00:00
|
|
|
} else {
|
|
|
|
// The wire bytes are not shared, OK to use them directly.
|
2018-08-08 14:54:44 +00:00
|
|
|
module_object = SyncCompile(isolate, enabled, &thrower, bytes);
|
2018-01-18 10:52:52 +00:00
|
|
|
}
|
|
|
|
if (thrower.error()) {
|
2018-05-24 21:22:27 +00:00
|
|
|
resolver->OnCompilationFailed(thrower.Reify());
|
2018-01-18 10:52:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
Handle<WasmModuleObject> module = module_object.ToHandleChecked();
|
2018-05-24 21:22:27 +00:00
|
|
|
resolver->OnCompilationSucceeded(module);
|
2018-01-18 10:52:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FLAG_wasm_test_streaming) {
|
|
|
|
std::shared_ptr<StreamingDecoder> streaming_decoder =
|
2018-08-08 14:54:44 +00:00
|
|
|
StartStreamingCompilation(isolate, enabled,
|
|
|
|
handle(isolate->context(), isolate),
|
|
|
|
std::move(resolver));
|
2018-01-18 10:52:52 +00:00
|
|
|
streaming_decoder->OnBytesReceived(bytes.module_bytes());
|
|
|
|
streaming_decoder->Finish();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Make a copy of the wire bytes in case the user program changes them
|
|
|
|
// during asynchronous compilation.
|
|
|
|
std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
|
|
|
|
memcpy(copy.get(), bytes.start(), bytes.length());
|
2018-05-09 13:48:47 +00:00
|
|
|
|
2018-06-11 09:53:20 +00:00
|
|
|
AsyncCompileJob* job = CreateAsyncCompileJob(
|
2018-08-08 14:54:44 +00:00
|
|
|
isolate, enabled, std::move(copy), bytes.length(),
|
2018-06-11 09:53:20 +00:00
|
|
|
handle(isolate->context(), isolate), std::move(resolver));
|
2018-05-09 13:48:47 +00:00
|
|
|
job->Start();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<StreamingDecoder> WasmEngine::StartStreamingCompilation(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver) {
|
2018-05-24 21:22:27 +00:00
|
|
|
AsyncCompileJob* job =
|
2018-08-08 14:54:44 +00:00
|
|
|
CreateAsyncCompileJob(isolate, enabled, std::unique_ptr<byte[]>(nullptr),
|
|
|
|
0, context, std::move(resolver));
|
2018-05-09 13:48:47 +00:00
|
|
|
return job->CreateStreamingDecoder();
|
2018-01-18 10:52:52 +00:00
|
|
|
}
|
|
|
|
|
2018-12-12 15:18:38 +00:00
|
|
|
void WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module,
|
2018-08-21 15:01:31 +00:00
|
|
|
uint32_t function_index, ExecutionTier tier) {
|
2018-08-23 14:44:28 +00:00
|
|
|
// Note we assume that "one-off" compilations can discard detected features.
|
|
|
|
WasmFeatures detected = kNoWasmFeatures;
|
2018-12-12 15:18:38 +00:00
|
|
|
WasmCompilationUnit::CompileWasmFunction(
|
2018-10-30 12:46:04 +00:00
|
|
|
isolate, native_module, &detected,
|
2018-08-21 15:01:31 +00:00
|
|
|
&native_module->module()->functions[function_index], tier);
|
2018-08-17 12:35:29 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 08:16:22 +00:00
|
|
|
std::shared_ptr<NativeModule> WasmEngine::ExportNativeModule(
|
|
|
|
Handle<WasmModuleObject> module_object) {
|
2018-12-11 10:37:32 +00:00
|
|
|
return module_object->shared_native_module();
|
2018-07-31 08:16:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Handle<WasmModuleObject> WasmEngine::ImportNativeModule(
|
2018-09-07 11:04:24 +00:00
|
|
|
Isolate* isolate, std::shared_ptr<NativeModule> shared_module) {
|
2018-12-10 13:00:02 +00:00
|
|
|
ModuleWireBytes wire_bytes(shared_module->wire_bytes());
|
2018-09-13 19:19:30 +00:00
|
|
|
const WasmModule* module = shared_module->module();
|
|
|
|
Handle<Script> script =
|
|
|
|
CreateWasmScript(isolate, wire_bytes, module->source_map_url);
|
2018-11-12 14:00:26 +00:00
|
|
|
size_t code_size = shared_module->committed_code_space();
|
|
|
|
Handle<WasmModuleObject> module_object = WasmModuleObject::New(
|
|
|
|
isolate, std::move(shared_module), script, code_size);
|
2018-12-07 15:04:59 +00:00
|
|
|
CompileJsToWasmWrappers(isolate, module_object->native_module()->module(),
|
2018-11-21 21:19:18 +00:00
|
|
|
handle(module_object->export_wrappers(), isolate));
|
2018-07-31 08:16:22 +00:00
|
|
|
return module_object;
|
|
|
|
}
|
|
|
|
|
2018-07-10 13:15:29 +00:00
|
|
|
CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-07-10 13:15:29 +00:00
|
|
|
if (compilation_stats_ == nullptr) {
|
|
|
|
compilation_stats_.reset(new CompilationStatistics());
|
|
|
|
}
|
|
|
|
return compilation_stats_.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WasmEngine::DumpAndResetTurboStatistics() {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-07-10 13:15:29 +00:00
|
|
|
if (compilation_stats_ != nullptr) {
|
|
|
|
StdoutStream os;
|
|
|
|
os << AsPrintableStatistics{*compilation_stats_.get(), false} << std::endl;
|
|
|
|
}
|
|
|
|
compilation_stats_.reset();
|
|
|
|
}
|
|
|
|
|
2018-07-16 11:52:11 +00:00
|
|
|
CodeTracer* WasmEngine::GetCodeTracer() {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-07-16 11:52:11 +00:00
|
|
|
if (code_tracer_ == nullptr) code_tracer_.reset(new CodeTracer(-1));
|
|
|
|
return code_tracer_.get();
|
|
|
|
}
|
|
|
|
|
2018-05-09 13:48:47 +00:00
|
|
|
AsyncCompileJob* WasmEngine::CreateAsyncCompileJob(
|
2018-08-08 14:54:44 +00:00
|
|
|
Isolate* isolate, const WasmFeatures& enabled,
|
|
|
|
std::unique_ptr<byte[]> bytes_copy, size_t length, Handle<Context> context,
|
2018-08-13 13:35:54 +00:00
|
|
|
std::shared_ptr<CompilationResultResolver> resolver) {
|
2018-08-08 14:54:44 +00:00
|
|
|
AsyncCompileJob* job =
|
|
|
|
new AsyncCompileJob(isolate, enabled, std::move(bytes_copy), length,
|
|
|
|
context, std::move(resolver));
|
2018-05-09 13:48:47 +00:00
|
|
|
// Pass ownership to the unique_ptr in {jobs_}.
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-05-09 13:48:47 +00:00
|
|
|
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
|
|
|
|
return job;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
|
|
|
|
AsyncCompileJob* job) {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-05-09 13:48:47 +00:00
|
|
|
auto item = jobs_.find(job);
|
|
|
|
DCHECK(item != jobs_.end());
|
|
|
|
std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
|
|
|
|
jobs_.erase(item);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-08-01 12:36:38 +00:00
|
|
|
bool WasmEngine::HasRunningCompileJob(Isolate* isolate) {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-09-25 11:24:09 +00:00
|
|
|
DCHECK_EQ(1, isolates_.count(isolate));
|
2018-08-01 12:36:38 +00:00
|
|
|
for (auto& entry : jobs_) {
|
|
|
|
if (entry.first->isolate() == isolate) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-07-26 13:08:04 +00:00
|
|
|
void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-09-25 11:24:09 +00:00
|
|
|
DCHECK_EQ(1, isolates_.count(isolate));
|
2018-07-26 13:08:04 +00:00
|
|
|
for (auto it = jobs_.begin(); it != jobs_.end();) {
|
|
|
|
if (it->first->isolate() == isolate) {
|
|
|
|
it = jobs_.erase(it);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-25 11:24:09 +00:00
|
|
|
void WasmEngine::AddIsolate(Isolate* isolate) {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-09-25 11:24:09 +00:00
|
|
|
DCHECK_EQ(0, isolates_.count(isolate));
|
|
|
|
isolates_.insert(isolate);
|
|
|
|
}
|
|
|
|
|
|
|
|
void WasmEngine::RemoveIsolate(Isolate* isolate) {
|
2018-10-12 13:52:49 +00:00
|
|
|
base::MutexGuard guard(&mutex_);
|
2018-09-25 11:24:09 +00:00
|
|
|
DCHECK_EQ(1, isolates_.count(isolate));
|
|
|
|
isolates_.erase(isolate);
|
|
|
|
}
|
|
|
|
|
2018-07-24 15:58:31 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
struct WasmEnginePointerConstructTrait final {
|
|
|
|
static void Construct(void* raw_ptr) {
|
|
|
|
auto engine_ptr = reinterpret_cast<std::shared_ptr<WasmEngine>*>(raw_ptr);
|
|
|
|
*engine_ptr = std::shared_ptr<WasmEngine>();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Holds the global shared pointer to the single {WasmEngine} that is intended
|
|
|
|
// to be shared among Isolates within the same process. The {LazyStaticInstance}
|
|
|
|
// here is required because {std::shared_ptr} has a non-trivial initializer.
|
|
|
|
base::LazyStaticInstance<std::shared_ptr<WasmEngine>,
|
|
|
|
WasmEnginePointerConstructTrait>::type
|
|
|
|
global_wasm_engine;
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2018-09-25 11:24:09 +00:00
|
|
|
// static
|
2018-07-24 15:58:31 +00:00
|
|
|
void WasmEngine::InitializeOncePerProcess() {
|
|
|
|
if (!FLAG_wasm_shared_engine) return;
|
2018-09-18 13:05:45 +00:00
|
|
|
global_wasm_engine.Pointer()->reset(new WasmEngine());
|
2018-07-24 15:58:31 +00:00
|
|
|
}
|
|
|
|
|
2018-09-25 11:24:09 +00:00
|
|
|
// static
|
2018-07-24 15:58:31 +00:00
|
|
|
void WasmEngine::GlobalTearDown() {
|
|
|
|
if (!FLAG_wasm_shared_engine) return;
|
|
|
|
global_wasm_engine.Pointer()->reset();
|
|
|
|
}
|
|
|
|
|
2018-09-25 11:24:09 +00:00
|
|
|
// static
|
2018-07-24 15:58:31 +00:00
|
|
|
std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() {
|
|
|
|
if (FLAG_wasm_shared_engine) return global_wasm_engine.Get();
|
2018-09-18 13:05:45 +00:00
|
|
|
return std::shared_ptr<WasmEngine>(new WasmEngine());
|
2018-07-24 15:58:31 +00:00
|
|
|
}
|
|
|
|
|
2018-10-30 12:32:17 +00:00
|
|
|
// {max_mem_pages} is declared in wasm-limits.h.
|
|
|
|
uint32_t max_mem_pages() {
|
|
|
|
STATIC_ASSERT(kV8MaxWasmMemoryPages <= kMaxUInt32);
|
|
|
|
return std::min(uint32_t{kV8MaxWasmMemoryPages}, FLAG_wasm_max_mem_pages);
|
|
|
|
}
|
|
|
|
|
2018-01-17 14:46:27 +00:00
|
|
|
} // namespace wasm
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|