aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/wasm-engine.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/wasm-engine.cc')
-rw-r--r--deps/v8/src/wasm/wasm-engine.cc155
1 files changed, 101 insertions, 54 deletions
diff --git a/deps/v8/src/wasm/wasm-engine.cc b/deps/v8/src/wasm/wasm-engine.cc
index dc78797365..d948157a12 100644
--- a/deps/v8/src/wasm/wasm-engine.cc
+++ b/deps/v8/src/wasm/wasm-engine.cc
@@ -7,10 +7,13 @@
#include "src/code-tracer.h"
#include "src/compilation-statistics.h"
#include "src/objects-inl.h"
+#include "src/objects/heap-number.h"
#include "src/objects/js-promise.h"
+#include "src/ostreams.h"
#include "src/wasm/function-compiler.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
+#include "src/wasm/module-instantiate.h"
#include "src/wasm/streaming-decoder.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -19,7 +22,7 @@ namespace internal {
namespace wasm {
WasmEngine::WasmEngine()
- : code_manager_(&memory_tracker_, kMaxWasmCodeMemory) {}
+ : code_manager_(&memory_tracker_, FLAG_wasm_max_code_space * MB) {}
WasmEngine::~WasmEngine() {
// All AsyncCompileJobs have been canceled.
@@ -38,20 +41,50 @@ bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
return result.ok();
}
-MaybeHandle<WasmModuleObject> WasmEngine::SyncCompileTranslatedAsmJs(
+MaybeHandle<AsmWasmData> WasmEngine::SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
- Handle<Script> asm_js_script,
- Vector<const byte> asm_js_offset_table_bytes) {
+ Vector<const byte> asm_js_offset_table_bytes,
+ Handle<HeapNumber> uses_bitset) {
ModuleResult result =
DecodeWasmModule(kAsmjsWasmFeatures, bytes.start(), bytes.end(), false,
kAsmJsOrigin, isolate->counters(), allocator());
CHECK(!result.failed());
// Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated
- // in {CompileToModuleObject}.
- return CompileToModuleObject(isolate, kAsmjsWasmFeatures, thrower,
- std::move(result.val), bytes, asm_js_script,
- asm_js_offset_table_bytes);
+ // 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;
}
MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
@@ -61,14 +94,40 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin,
isolate->counters(), allocator());
if (result.failed()) {
- thrower->CompileFailed("Wasm decoding failed", result);
+ thrower->CompileFailed("Wasm decoding failed", result.error());
return {};
}
// Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated
// in {CompileToModuleObject}.
- return CompileToModuleObject(isolate, enabled, thrower, std::move(result.val),
- bytes, Handle<Script>(), Vector<const byte>());
+ 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;
}
MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
@@ -170,43 +229,36 @@ std::shared_ptr<StreamingDecoder> WasmEngine::StartStreamingCompilation(
return job->CreateStreamingDecoder();
}
-bool WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module,
+void WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module,
uint32_t function_index, ExecutionTier tier) {
- ErrorThrower thrower(isolate, "Manually requested tier up");
// Note we assume that "one-off" compilations can discard detected features.
WasmFeatures detected = kNoWasmFeatures;
- WasmCode* ret = WasmCompilationUnit::CompileWasmFunction(
- isolate, native_module, &detected, &thrower,
- GetModuleEnv(native_module->compilation_state()),
+ WasmCompilationUnit::CompileWasmFunction(
+ isolate, native_module, &detected,
&native_module->module()->functions[function_index], tier);
- return ret != nullptr;
}
std::shared_ptr<NativeModule> WasmEngine::ExportNativeModule(
Handle<WasmModuleObject> module_object) {
- return module_object->managed_native_module()->get();
+ return module_object->shared_native_module();
}
Handle<WasmModuleObject> WasmEngine::ImportNativeModule(
Isolate* isolate, std::shared_ptr<NativeModule> shared_module) {
- CHECK_EQ(code_manager(), shared_module->code_manager());
- Vector<const byte> wire_bytes = shared_module->wire_bytes();
+ ModuleWireBytes wire_bytes(shared_module->wire_bytes());
const WasmModule* module = shared_module->module();
Handle<Script> script =
CreateWasmScript(isolate, wire_bytes, module->source_map_url);
- Handle<WasmModuleObject> module_object =
- WasmModuleObject::New(isolate, std::move(shared_module), script);
-
- // TODO(6792): Wrappers below might be cloned using {Factory::CopyCode}.
- // This requires unlocking the code space here. This should eventually be
- // moved into the allocator.
- CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
- CompileJsToWasmWrappers(isolate, module_object);
+ size_t code_size = shared_module->committed_code_space();
+ Handle<WasmModuleObject> module_object = WasmModuleObject::New(
+ isolate, std::move(shared_module), script, code_size);
+ CompileJsToWasmWrappers(isolate, module_object->native_module()->module(),
+ handle(module_object->export_wrappers(), isolate));
return module_object;
}
CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
if (compilation_stats_ == nullptr) {
compilation_stats_.reset(new CompilationStatistics());
}
@@ -214,7 +266,7 @@ CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() {
}
void WasmEngine::DumpAndResetTurboStatistics() {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
if (compilation_stats_ != nullptr) {
StdoutStream os;
os << AsPrintableStatistics{*compilation_stats_.get(), false} << std::endl;
@@ -223,7 +275,7 @@ void WasmEngine::DumpAndResetTurboStatistics() {
}
CodeTracer* WasmEngine::GetCodeTracer() {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
if (code_tracer_ == nullptr) code_tracer_.reset(new CodeTracer(-1));
return code_tracer_.get();
}
@@ -236,14 +288,14 @@ AsyncCompileJob* WasmEngine::CreateAsyncCompileJob(
new AsyncCompileJob(isolate, enabled, std::move(bytes_copy), length,
context, std::move(resolver));
// Pass ownership to the unique_ptr in {jobs_}.
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
return job;
}
std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
AsyncCompileJob* job) {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
auto item = jobs_.find(job);
DCHECK(item != jobs_.end());
std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
@@ -252,7 +304,7 @@ std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
}
bool WasmEngine::HasRunningCompileJob(Isolate* isolate) {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
DCHECK_EQ(1, isolates_.count(isolate));
for (auto& entry : jobs_) {
if (entry.first->isolate() == isolate) return true;
@@ -261,7 +313,7 @@ bool WasmEngine::HasRunningCompileJob(Isolate* isolate) {
}
void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
DCHECK_EQ(1, isolates_.count(isolate));
for (auto it = jobs_.begin(); it != jobs_.end();) {
if (it->first->isolate() == isolate) {
@@ -273,51 +325,46 @@ void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
}
void WasmEngine::AddIsolate(Isolate* isolate) {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
DCHECK_EQ(0, isolates_.count(isolate));
isolates_.insert(isolate);
}
void WasmEngine::RemoveIsolate(Isolate* isolate) {
- base::LockGuard<base::Mutex> guard(&mutex_);
+ base::MutexGuard guard(&mutex_);
DCHECK_EQ(1, isolates_.count(isolate));
isolates_.erase(isolate);
}
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;
+DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::shared_ptr<WasmEngine>,
+ GetSharedWasmEngine);
} // namespace
// static
void WasmEngine::InitializeOncePerProcess() {
if (!FLAG_wasm_shared_engine) return;
- global_wasm_engine.Pointer()->reset(new WasmEngine());
+ *GetSharedWasmEngine() = std::make_shared<WasmEngine>();
}
// static
void WasmEngine::GlobalTearDown() {
if (!FLAG_wasm_shared_engine) return;
- global_wasm_engine.Pointer()->reset();
+ GetSharedWasmEngine()->reset();
}
// static
std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() {
- if (FLAG_wasm_shared_engine) return global_wasm_engine.Get();
- return std::shared_ptr<WasmEngine>(new WasmEngine());
+ if (FLAG_wasm_shared_engine) return *GetSharedWasmEngine();
+ return std::make_shared<WasmEngine>();
+}
+
+// {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);
}
} // namespace wasm