[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:
parent
f29cae45ce
commit
291f8dcfd5
2
BUILD.gn
2
BUILD.gn
@ -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",
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
|
32
src/wasm/compilation-manager.cc
Normal file
32
src/wasm/compilation-manager.cc
Normal 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
|
44
src/wasm/compilation-manager.h
Normal file
44
src/wasm/compilation-manager.h
Normal 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_
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user