summaryrefslogtreecommitdiff
path: root/chromium/v8/src/wasm/wasm-engine.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-24 11:30:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-10-30 12:56:19 +0000
commit6036726eb981b6c4b42047513b9d3f4ac865daac (patch)
tree673593e70678e7789766d1f732eb51f613a2703b /chromium/v8/src/wasm/wasm-engine.cc
parent466052c4e7c052268fd931888cd58961da94c586 (diff)
downloadqtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/v8/src/wasm/wasm-engine.cc')
-rw-r--r--chromium/v8/src/wasm/wasm-engine.cc190
1 files changed, 129 insertions, 61 deletions
diff --git a/chromium/v8/src/wasm/wasm-engine.cc b/chromium/v8/src/wasm/wasm-engine.cc
index 717c5defd79..4f772d9bdd3 100644
--- a/chromium/v8/src/wasm/wasm-engine.cc
+++ b/chromium/v8/src/wasm/wasm-engine.cc
@@ -8,10 +8,11 @@
#include "src/compilation-statistics.h"
#include "src/objects-inl.h"
#include "src/objects/js-promise.h"
+#include "src/wasm/function-compiler.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/streaming-decoder.h"
-#include "src/wasm/wasm-objects.h"
+#include "src/wasm/wasm-objects-inl.h"
namespace v8 {
namespace internal {
@@ -20,13 +21,18 @@ namespace wasm {
WasmEngine::WasmEngine()
: code_manager_(&memory_tracker_, kMaxWasmCodeMemory) {}
-WasmEngine::~WasmEngine() = default;
+WasmEngine::~WasmEngine() {
+ // All AsyncCompileJobs have been canceled.
+ DCHECK(jobs_.empty());
+}
-bool WasmEngine::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) {
+bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
+ const ModuleWireBytes& bytes) {
// TODO(titzer): remove dependency on the isolate.
if (bytes.start() == nullptr || bytes.length() == 0) return false;
- ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
- bytes.end(), true, kWasmOrigin);
+ ModuleResult result =
+ DecodeWasmModule(enabled, bytes.start(), bytes.end(), true, kWasmOrigin,
+ isolate->counters(), allocator());
return result.ok();
}
@@ -34,20 +40,24 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
- ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
- bytes.end(), false, kAsmJsOrigin);
+ 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, thrower, std::move(result.val), bytes,
- asm_js_script, asm_js_offset_table_bytes);
+ return CompileToModuleObject(isolate, kAsmjsWasmFeatures, thrower,
+ std::move(result.val), bytes, asm_js_script,
+ asm_js_offset_table_bytes);
}
MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
- Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes) {
- ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
- bytes.end(), false, kWasmOrigin);
+ Isolate* isolate, const WasmFeatures& enabled, ErrorThrower* thrower,
+ const ModuleWireBytes& bytes) {
+ ModuleResult result =
+ DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin,
+ isolate->counters(), allocator());
if (result.failed()) {
thrower->CompileFailed("Wasm decoding failed", result);
return {};
@@ -55,8 +65,8 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
// Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated
// in {CompileToModuleObject}.
- return CompileToModuleObject(isolate, thrower, std::move(result.val), bytes,
- Handle<Script>(), Vector<const byte>());
+ return CompileToModuleObject(isolate, enabled, thrower, std::move(result.val),
+ bytes, Handle<Script>(), Vector<const byte>());
}
MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
@@ -70,7 +80,7 @@ MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
void WasmEngine::AsyncInstantiate(
Isolate* isolate, std::unique_ptr<InstantiationResultResolver> resolver,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports) {
- ErrorThrower thrower(isolate, nullptr);
+ ErrorThrower thrower(isolate, "WebAssembly Instantiation");
// 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
@@ -87,24 +97,24 @@ void WasmEngine::AsyncInstantiate(
return;
}
- // We either have a pending exception (if the start function threw), or an
- // exception in the ErrorThrower.
- DCHECK_EQ(1, isolate->has_pending_exception() + thrower.error());
- if (thrower.error()) {
- resolver->OnInstantiationFailed(thrower.Reify());
- } else {
- // The start function has thrown an exception. We have to move the
- // exception to the promise chain.
+ 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.
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);
+ thrower.Reset();
+ } else {
+ DCHECK(thrower.error());
+ resolver->OnInstantiationFailed(thrower.Reify());
}
}
void WasmEngine::AsyncCompile(
- Isolate* isolate, std::unique_ptr<CompilationResultResolver> resolver,
+ Isolate* isolate, const WasmFeatures& enabled,
+ std::shared_ptr<CompilationResultResolver> resolver,
const ModuleWireBytes& bytes, bool is_shared) {
if (!FLAG_wasm_async_compilation) {
// Asynchronous compilation disabled; fall back on synchronous compilation.
@@ -114,12 +124,11 @@ void WasmEngine::AsyncCompile(
// 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());
- i::wasm::ModuleWireBytes bytes_copy(copy.get(),
- copy.get() + bytes.length());
- module_object = SyncCompile(isolate, &thrower, bytes_copy);
+ ModuleWireBytes bytes_copy(copy.get(), copy.get() + bytes.length());
+ module_object = SyncCompile(isolate, enabled, &thrower, bytes_copy);
} else {
// The wire bytes are not shared, OK to use them directly.
- module_object = SyncCompile(isolate, &thrower, bytes);
+ module_object = SyncCompile(isolate, enabled, &thrower, bytes);
}
if (thrower.error()) {
resolver->OnCompilationFailed(thrower.Reify());
@@ -132,8 +141,9 @@ void WasmEngine::AsyncCompile(
if (FLAG_wasm_test_streaming) {
std::shared_ptr<StreamingDecoder> streaming_decoder =
- isolate->wasm_engine()->StartStreamingCompilation(
- isolate, handle(isolate->context(), isolate), std::move(resolver));
+ StartStreamingCompilation(isolate, enabled,
+ handle(isolate->context(), isolate),
+ std::move(resolver));
streaming_decoder->OnBytesReceived(bytes.module_bytes());
streaming_decoder->Finish();
return;
@@ -144,20 +154,53 @@ void WasmEngine::AsyncCompile(
memcpy(copy.get(), bytes.start(), bytes.length());
AsyncCompileJob* job = CreateAsyncCompileJob(
- isolate, std::move(copy), bytes.length(),
+ isolate, enabled, std::move(copy), bytes.length(),
handle(isolate->context(), isolate), std::move(resolver));
job->Start();
}
std::shared_ptr<StreamingDecoder> WasmEngine::StartStreamingCompilation(
- Isolate* isolate, Handle<Context> context,
- std::unique_ptr<CompilationResultResolver> resolver) {
+ Isolate* isolate, const WasmFeatures& enabled, Handle<Context> context,
+ std::shared_ptr<CompilationResultResolver> resolver) {
AsyncCompileJob* job =
- CreateAsyncCompileJob(isolate, std::unique_ptr<byte[]>(nullptr), 0,
- context, std::move(resolver));
+ CreateAsyncCompileJob(isolate, enabled, std::unique_ptr<byte[]>(nullptr),
+ 0, context, std::move(resolver));
return job->CreateStreamingDecoder();
}
+bool 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()),
+ &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();
+}
+
+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();
+ Handle<Script> script = CreateWasmScript(isolate, wire_bytes);
+ Handle<WasmModuleObject> module_object =
+ WasmModuleObject::New(isolate, 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);
+ return module_object;
+}
+
CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() {
base::LockGuard<base::Mutex> guard(&mutex_);
if (compilation_stats_ == nullptr) {
@@ -181,27 +224,22 @@ CodeTracer* WasmEngine::GetCodeTracer() {
return code_tracer_.get();
}
-void WasmEngine::Register(CancelableTaskManager* task_manager) {
- task_managers_.emplace_back(task_manager);
-}
-
-void WasmEngine::Unregister(CancelableTaskManager* task_manager) {
- task_managers_.remove(task_manager);
-}
-
AsyncCompileJob* WasmEngine::CreateAsyncCompileJob(
- Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, size_t length,
- Handle<Context> context,
- std::unique_ptr<CompilationResultResolver> resolver) {
- AsyncCompileJob* job = new AsyncCompileJob(
- isolate, std::move(bytes_copy), length, context, std::move(resolver));
+ Isolate* isolate, const WasmFeatures& enabled,
+ std::unique_ptr<byte[]> bytes_copy, size_t length, Handle<Context> context,
+ std::shared_ptr<CompilationResultResolver> resolver) {
+ AsyncCompileJob* job =
+ 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_);
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
return job;
}
std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
AsyncCompileJob* job) {
+ base::LockGuard<base::Mutex> guard(&mutex_);
auto item = jobs_.find(job);
DCHECK(item != jobs_.end());
std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
@@ -209,26 +247,56 @@ std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
return result;
}
-void WasmEngine::AbortCompileJobsOnIsolate(Isolate* isolate) {
- // Iterate over a copy of {jobs_}, because {job->Abort} modifies {jobs_}.
- std::vector<AsyncCompileJob*> isolate_jobs;
-
+bool WasmEngine::HasRunningCompileJob(Isolate* isolate) {
+ base::LockGuard<base::Mutex> guard(&mutex_);
for (auto& entry : jobs_) {
- if (entry.first->isolate() != isolate) continue;
- isolate_jobs.push_back(entry.first);
+ if (entry.first->isolate() == isolate) return true;
}
+ return false;
+}
- for (auto* job : isolate_jobs) job->Abort();
+void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
+ base::LockGuard<base::Mutex> guard(&mutex_);
+ for (auto it = jobs_.begin(); it != jobs_.end();) {
+ if (it->first->isolate() == isolate) {
+ it = jobs_.erase(it);
+ } else {
+ ++it;
+ }
+ }
}
-void WasmEngine::TearDown() {
- // Cancel all registered task managers.
- for (auto task_manager : task_managers_) {
- task_manager->CancelAndWait();
+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
+
+void WasmEngine::InitializeOncePerProcess() {
+ if (!FLAG_wasm_shared_engine) return;
+ global_wasm_engine.Pointer()->reset(new WasmEngine());
+}
+
+void WasmEngine::GlobalTearDown() {
+ if (!FLAG_wasm_shared_engine) return;
+ global_wasm_engine.Pointer()->reset();
+}
- // Cancel all AsyncCompileJobs.
- jobs_.clear();
+std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() {
+ if (FLAG_wasm_shared_engine) return global_wasm_engine.Get();
+ return std::shared_ptr<WasmEngine>(new WasmEngine());
}
} // namespace wasm