[wasm] Introduce a compilation manager for WebAssembly

This CL is the first step in introducing a compilation manager for
asynchronous compile jobs in WebAssembly.

The compilation manager holds a list of currently active
AsyncCompileJobs. With the compilation manager these compile jobs get
deallocated when the isolate shuts down. Note that this CL is not enough
to provide a graceful isolate shutdown. For this we have to wait for all
compilation tasks to finish before we shut down, and we have to make the
tasks stateless. I plan to do these changes in separate CLs.

R=clemensh@chromium.org, mtrofin@chromium.org

BUG=v8:6436

Change-Id: I9a6e165dd2ef6d33944ca303fed49f7940eea7a2
Reviewed-on: https://chromium-review.googlesource.com/528079
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45858}
This commit is contained in:
Andreas Haas 2017-06-09 10:35:01 +02:00 committed by Commit Bot
parent f29cae45ce
commit 291f8dcfd5
8 changed files with 106 additions and 14 deletions

View File

@ -2013,6 +2013,8 @@ v8_source_set("v8_base") {
"src/visitors.h", "src/visitors.h",
"src/vm-state-inl.h", "src/vm-state-inl.h",
"src/vm-state.h", "src/vm-state.h",
"src/wasm/compilation-manager.cc",
"src/wasm/compilation-manager.h",
"src/wasm/decoder.h", "src/wasm/decoder.h",
"src/wasm/function-body-decoder-impl.h", "src/wasm/function-body-decoder-impl.h",
"src/wasm/function-body-decoder.cc", "src/wasm/function-body-decoder.cc",

View File

@ -52,6 +52,7 @@
#include "src/version.h" #include "src/version.h"
#include "src/visitors.h" #include "src/visitors.h"
#include "src/vm-state-inl.h" #include "src/vm-state-inl.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/wasm-module.h" #include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-objects.h"
#include "src/zone/accounting-allocator.h" #include "src/zone/accounting-allocator.h"
@ -2341,6 +2342,7 @@ Isolate::Isolate(bool enable_serializer)
use_counter_callback_(NULL), use_counter_callback_(NULL),
basic_block_profiler_(NULL), basic_block_profiler_(NULL),
cancelable_task_manager_(new CancelableTaskManager()), cancelable_task_manager_(new CancelableTaskManager()),
wasm_compilation_manager_(new wasm::CompilationManager()),
abort_on_uncaught_exception_callback_(NULL), abort_on_uncaught_exception_callback_(NULL),
total_regexp_code_generated_(0) { total_regexp_code_generated_(0) {
{ {
@ -2431,17 +2433,14 @@ void Isolate::Deinit() {
debug()->Unload(); debug()->Unload();
FreeThreadResources();
// Release managed objects before shutting down the heap. The finalizer might
// need to access heap objects.
ReleaseManagedObjects();
if (concurrent_recompilation_enabled()) { if (concurrent_recompilation_enabled()) {
optimizing_compile_dispatcher_->Stop(); optimizing_compile_dispatcher_->Stop();
delete optimizing_compile_dispatcher_; delete optimizing_compile_dispatcher_;
optimizing_compile_dispatcher_ = NULL; optimizing_compile_dispatcher_ = NULL;
} }
wasm_compilation_manager_->TearDown();
heap_.mark_compact_collector()->EnsureSweepingCompleted(); heap_.mark_compact_collector()->EnsureSweepingCompleted();
DumpAndResetStats(); DumpAndResetStats();
@ -2458,6 +2457,11 @@ void Isolate::Deinit() {
sampler::Sampler* sampler = logger_->sampler(); sampler::Sampler* sampler = logger_->sampler();
if (sampler && sampler->IsActive()) sampler->Stop(); if (sampler && sampler->IsActive()) sampler->Stop();
FreeThreadResources();
// Release managed objects before shutting down the heap. The finalizer might
// need to access heap objects.
ReleaseManagedObjects();
delete deoptimizer_data_; delete deoptimizer_data_;
deoptimizer_data_ = NULL; deoptimizer_data_ = NULL;
builtins_.TearDown(); builtins_.TearDown();

View File

@ -107,6 +107,10 @@ namespace interpreter {
class Interpreter; class Interpreter;
} }
namespace wasm {
class CompilationManager;
}
#define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate) \ #define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate) \
do { \ do { \
Isolate* __isolate__ = (isolate); \ Isolate* __isolate__ = (isolate); \
@ -1212,6 +1216,10 @@ class Isolate {
return cancelable_task_manager_; return cancelable_task_manager_;
} }
wasm::CompilationManager* wasm_compilation_manager() {
return wasm_compilation_manager_.get();
}
const AstStringConstants* ast_string_constants() const { const AstStringConstants* ast_string_constants() const {
return ast_string_constants_; return ast_string_constants_;
} }
@ -1569,6 +1577,8 @@ class Isolate {
CancelableTaskManager* cancelable_task_manager_; CancelableTaskManager* cancelable_task_manager_;
std::unique_ptr<wasm::CompilationManager> wasm_compilation_manager_;
debug::ConsoleDelegate* console_delegate_ = nullptr; debug::ConsoleDelegate* console_delegate_ = nullptr;
v8::Isolate::AbortOnUncaughtExceptionCallback v8::Isolate::AbortOnUncaughtExceptionCallback

View File

@ -1473,6 +1473,8 @@
'visitors.h', 'visitors.h',
'vm-state-inl.h', 'vm-state-inl.h',
'vm-state.h', 'vm-state.h',
'wasm/compilation-manager.cc',
'wasm/compilation-manager.h',
'wasm/decoder.h', 'wasm/decoder.h',
'wasm/function-body-decoder.cc', 'wasm/function-body-decoder.cc',
'wasm/function-body-decoder.h', 'wasm/function-body-decoder.h',

View File

@ -0,0 +1,32 @@
// 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.
#include "src/wasm/compilation-manager.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
namespace wasm {
void CompilationManager::StartAsyncCompileJob(
Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, size_t length,
Handle<Context> context, Handle<JSPromise> promise) {
std::shared_ptr<AsyncCompileJob> job(new AsyncCompileJob(
isolate, std::move(bytes_copy), length, context, promise));
jobs_.insert({job.get(), job});
job->Start();
}
void CompilationManager::RemoveJob(AsyncCompileJob* job) {
size_t num_removed = jobs_.erase(job);
USE(num_removed);
DCHECK_EQ(1, num_removed);
}
void CompilationManager::TearDown() { jobs_.clear(); }
} // namespace wasm
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,44 @@
// 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.
#ifndef V8_WASM_COMPILATION_MANAGER_H_
#define V8_WASM_COMPILATION_MANAGER_H_
#include <vector>
#include "src/handles.h"
#include "src/isolate.h"
#include "src/wasm/module-compiler.h"
namespace v8 {
namespace internal {
namespace wasm {
// The CompilationManager manages a list of active WebAssembly compile jobs. The
// manager owns the memory of the compile jobs and can trigger the abortion of
// compile jobs. If the isolate tears down, the CompilationManager makes sure
// that all compile jobs finish executing before the isolate becomes
// unavailable.
class CompilationManager {
public:
void StartAsyncCompileJob(Isolate* isolate,
std::unique_ptr<byte[]> bytes_copy, size_t length,
Handle<Context> context, Handle<JSPromise> promise);
// Removes {job} from the list of active compile jobs. This will delete {job}.
void RemoveJob(AsyncCompileJob* job);
void TearDown();
private:
// We use an AsyncCompileJob as the key for itself so that we can delete the
// job from the map when it is finished.
std::unordered_map<AsyncCompileJob*, std::shared_ptr<AsyncCompileJob>> jobs_;
};
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_COMPILATION_MANAGER_H_

View File

@ -8,6 +8,7 @@
#include "src/asmjs/asm-js.h" #include "src/asmjs/asm-js.h"
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/property-descriptor.h" #include "src/property-descriptor.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-decoder.h" #include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h" #include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h" #include "src/wasm/wasm-module.h"
@ -1880,16 +1881,12 @@ void AsyncCompileJob::ReopenHandlesInDeferredScope() {
void AsyncCompileJob::AsyncCompileFailed(ErrorThrower& thrower) { void AsyncCompileJob::AsyncCompileFailed(ErrorThrower& thrower) {
RejectPromise(isolate_, context_, thrower, module_promise_); RejectPromise(isolate_, context_, thrower, module_promise_);
// The AsyncCompileJob is finished, we resolved the promise, we do not need isolate_->wasm_compilation_manager()->RemoveJob(this);
// the data anymore. We can delete the AsyncCompileJob object.
delete this;
} }
void AsyncCompileJob::AsyncCompileSucceeded(Handle<Object> result) { void AsyncCompileJob::AsyncCompileSucceeded(Handle<Object> result) {
ResolvePromise(isolate_, context_, module_promise_, result); ResolvePromise(isolate_, context_, module_promise_, result);
// The AsyncCompileJob is finished, we resolved the promise, we do not need isolate_->wasm_compilation_manager()->RemoveJob(this);
// the data anymore. We can delete the AsyncCompileJob object.
delete this;
} }
// A closure to run a compilation step (either as foreground or background // A closure to run a compilation step (either as foreground or background

View File

@ -14,6 +14,7 @@
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/v8.h" #include "src/v8.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-compiler.h" #include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h" #include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-code-specialization.h" #include "src/wasm/wasm-code-specialization.h"
@ -873,9 +874,9 @@ void wasm::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
// during asynchronous compilation. // during asynchronous compilation.
std::unique_ptr<byte[]> copy(new byte[bytes.length()]); std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length()); memcpy(copy.get(), bytes.start(), bytes.length());
auto job = new AsyncCompileJob(isolate, std::move(copy), bytes.length(), isolate->wasm_compilation_manager()->StartAsyncCompileJob(
handle(isolate->context()), promise); isolate, std::move(copy), bytes.length(), handle(isolate->context()),
job->Start(); promise);
} }
Handle<Code> wasm::CompileLazy(Isolate* isolate) { Handle<Code> wasm::CompileLazy(Isolate* isolate) {