Commit adad7e6e authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Remove the state from tasks of an AsyncCompileJob

There exists a hidden assumption in V8 that neither foreground nor
background tasks own any memory. For asynchronous WebAssembly
compilation this assumption was wrong, which causes crashes when V8 shut
down before the compilation finished.

With this CL I change the way asynchrous compilation happens. In the
existing implementation each compilation stage provided its own task
which could be spawned either in foreground or background. With this CL
each stage only provides a state, and a generic CompileTask executes on
that state. There exists exactly one state at a time.

To have exactly one state at a time I combined the stages
ExecuteCompilationUnits and FinishCompilationUnits to a single stage. In
addition I removed the WaitForBackgroundTasks stage and added a
CancelableTaskManager to the AsyncCompileJob instead to do the waiting.

BUG=v8:6436
R=clemensh@chromium.org, mtrofin@chromium.org

Change-Id: I2eb61f74235c65524ce720c474eaf99ae7472c81
Reviewed-on: https://chromium-review.googlesource.com/532993
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45908}
parent 2c65b0be
This diff is collapsed.
...@@ -257,6 +257,20 @@ class AsyncCompileJob { ...@@ -257,6 +257,20 @@ class AsyncCompileJob {
~AsyncCompileJob(); ~AsyncCompileJob();
private: private:
class CompileTask;
class CompileState;
// States of the AsyncCompileJob.
class DecodeModule;
class DecodeFail;
class PrepareAndStartCompile;
class ExecuteAndFinishCompilationUnits;
class WaitForBackgroundTasks;
class FinishCompilationUnits;
class FinishCompile;
class CompileWrappers;
class FinishModule;
Isolate* isolate_; Isolate* isolate_;
std::shared_ptr<Counters> counters_shared_; std::shared_ptr<Counters> counters_shared_;
Counters* counters_; Counters* counters_;
...@@ -267,7 +281,6 @@ class AsyncCompileJob { ...@@ -267,7 +281,6 @@ class AsyncCompileJob {
std::unique_ptr<ModuleCompiler> compiler_; std::unique_ptr<ModuleCompiler> compiler_;
std::unique_ptr<ModuleBytesEnv> module_bytes_env_; std::unique_ptr<ModuleBytesEnv> module_bytes_env_;
bool failed_ = false;
std::vector<DeferredHandles*> deferred_handles_; std::vector<DeferredHandles*> deferred_handles_;
Handle<WasmModuleObject> module_object_; Handle<WasmModuleObject> module_object_;
Handle<FixedArray> function_tables_; Handle<FixedArray> function_tables_;
...@@ -276,7 +289,12 @@ class AsyncCompileJob { ...@@ -276,7 +289,12 @@ class AsyncCompileJob {
Handle<FixedArray> code_table_; Handle<FixedArray> code_table_;
std::unique_ptr<WasmInstance> temp_instance_ = nullptr; std::unique_ptr<WasmInstance> temp_instance_ = nullptr;
size_t outstanding_units_ = 0; size_t outstanding_units_ = 0;
size_t num_background_tasks_ = 0; std::unique_ptr<CompileState> state_;
CancelableTaskManager background_task_manager_;
#if DEBUG
// Counts the number of pending foreground tasks.
int32_t num_pending_foreground_tasks_ = 0;
#endif
void ReopenHandlesInDeferredScope(); void ReopenHandlesInDeferredScope();
...@@ -287,22 +305,10 @@ class AsyncCompileJob { ...@@ -287,22 +305,10 @@ class AsyncCompileJob {
template <typename Task, typename... Args> template <typename Task, typename... Args>
void DoSync(Args&&... args); void DoSync(Args&&... args);
void StartForegroundTask();
template <typename Task, typename... Args> template <typename Task, typename... Args>
void DoAsync(Args&&... args); void DoAsync(Args&&... args);
class CompileTask;
class AsyncCompileTask;
class SyncCompileTask;
class DecodeModule;
class DecodeFail;
class PrepareAndStartCompile;
class ExecuteCompilationUnits;
class WaitForBackgroundTasks;
class FinishCompilationUnits;
class FailCompile;
class FinishCompile;
class CompileWrappers;
class FinishModule;
}; };
} // namespace wasm } // namespace wasm
......
// Copyright 2017 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.
// Flags: --expose-wasm --wasm-async-compilation
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
(function CompileFunctionsTest() {
// Create a big module.
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
for (i = 0; i < 100; i++) {
builder.addFunction("sub" + i, kSig_i_i)
.addBody([ // --
kExprGetLocal, 0, // --
kExprI32Const, i % 61, // --
kExprI32Sub]) // --
.exportFunc()
}
var buffer = builder.toBuffer();
// Start the compilation but do not wait for the promise to resolve
// with assertPromiseResult. This should not cause a crash.
WebAssembly.compile(buffer).then(
() => { print("success")},
() => { print("failed"); });
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment