diff --git a/BUILD.gn b/BUILD.gn index 8d9044288b..b73bfef12d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2013,6 +2013,8 @@ v8_source_set("v8_base") { "src/visitors.h", "src/vm-state-inl.h", "src/vm-state.h", + "src/wasm/compilation-manager.cc", + "src/wasm/compilation-manager.h", "src/wasm/decoder.h", "src/wasm/function-body-decoder-impl.h", "src/wasm/function-body-decoder.cc", diff --git a/src/isolate.cc b/src/isolate.cc index 69c84e82e5..194e85c73a 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -52,6 +52,7 @@ #include "src/version.h" #include "src/visitors.h" #include "src/vm-state-inl.h" +#include "src/wasm/compilation-manager.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects.h" #include "src/zone/accounting-allocator.h" @@ -2341,6 +2342,7 @@ Isolate::Isolate(bool enable_serializer) use_counter_callback_(NULL), basic_block_profiler_(NULL), cancelable_task_manager_(new CancelableTaskManager()), + wasm_compilation_manager_(new wasm::CompilationManager()), abort_on_uncaught_exception_callback_(NULL), total_regexp_code_generated_(0) { { @@ -2431,17 +2433,14 @@ void Isolate::Deinit() { debug()->Unload(); - FreeThreadResources(); - // Release managed objects before shutting down the heap. The finalizer might - // need to access heap objects. - ReleaseManagedObjects(); - if (concurrent_recompilation_enabled()) { optimizing_compile_dispatcher_->Stop(); delete optimizing_compile_dispatcher_; optimizing_compile_dispatcher_ = NULL; } + wasm_compilation_manager_->TearDown(); + heap_.mark_compact_collector()->EnsureSweepingCompleted(); DumpAndResetStats(); @@ -2458,6 +2457,11 @@ void Isolate::Deinit() { sampler::Sampler* sampler = logger_->sampler(); 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_; deoptimizer_data_ = NULL; builtins_.TearDown(); diff --git a/src/isolate.h b/src/isolate.h index aad853dc08..f5bcf916c6 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -107,6 +107,10 @@ namespace interpreter { class Interpreter; } +namespace wasm { +class CompilationManager; +} + #define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate) \ do { \ Isolate* __isolate__ = (isolate); \ @@ -1212,6 +1216,10 @@ class Isolate { return cancelable_task_manager_; } + wasm::CompilationManager* wasm_compilation_manager() { + return wasm_compilation_manager_.get(); + } + const AstStringConstants* ast_string_constants() const { return ast_string_constants_; } @@ -1569,6 +1577,8 @@ class Isolate { CancelableTaskManager* cancelable_task_manager_; + std::unique_ptr wasm_compilation_manager_; + debug::ConsoleDelegate* console_delegate_ = nullptr; v8::Isolate::AbortOnUncaughtExceptionCallback diff --git a/src/v8.gyp b/src/v8.gyp index 5fa53a107b..7e5c03eff3 100644 --- a/src/v8.gyp +++ b/src/v8.gyp @@ -1473,6 +1473,8 @@ 'visitors.h', 'vm-state-inl.h', 'vm-state.h', + 'wasm/compilation-manager.cc', + 'wasm/compilation-manager.h', 'wasm/decoder.h', 'wasm/function-body-decoder.cc', 'wasm/function-body-decoder.h', diff --git a/src/wasm/compilation-manager.cc b/src/wasm/compilation-manager.cc new file mode 100644 index 0000000000..01e0755e14 --- /dev/null +++ b/src/wasm/compilation-manager.cc @@ -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 bytes_copy, size_t length, + Handle context, Handle promise) { + std::shared_ptr 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 diff --git a/src/wasm/compilation-manager.h b/src/wasm/compilation-manager.h new file mode 100644 index 0000000000..85b6fd5ce2 --- /dev/null +++ b/src/wasm/compilation-manager.h @@ -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 + +#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 bytes_copy, size_t length, + Handle context, Handle 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> jobs_; +}; + +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif // V8_WASM_COMPILATION_MANAGER_H_ diff --git a/src/wasm/module-compiler.cc b/src/wasm/module-compiler.cc index a5abd29691..8574e618e6 100644 --- a/src/wasm/module-compiler.cc +++ b/src/wasm/module-compiler.cc @@ -8,6 +8,7 @@ #include "src/asmjs/asm-js.h" #include "src/assembler-inl.h" #include "src/property-descriptor.h" +#include "src/wasm/compilation-manager.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-js.h" #include "src/wasm/wasm-module.h" @@ -1880,16 +1881,12 @@ void AsyncCompileJob::ReopenHandlesInDeferredScope() { void AsyncCompileJob::AsyncCompileFailed(ErrorThrower& thrower) { RejectPromise(isolate_, context_, thrower, module_promise_); - // The AsyncCompileJob is finished, we resolved the promise, we do not need - // the data anymore. We can delete the AsyncCompileJob object. - delete this; + isolate_->wasm_compilation_manager()->RemoveJob(this); } void AsyncCompileJob::AsyncCompileSucceeded(Handle result) { ResolvePromise(isolate_, context_, module_promise_, result); - // The AsyncCompileJob is finished, we resolved the promise, we do not need - // the data anymore. We can delete the AsyncCompileJob object. - delete this; + isolate_->wasm_compilation_manager()->RemoveJob(this); } // A closure to run a compilation step (either as foreground or background diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc index a0c4a383fc..c6ab0bc18d 100644 --- a/src/wasm/wasm-module.cc +++ b/src/wasm/wasm-module.cc @@ -14,6 +14,7 @@ #include "src/snapshot/snapshot.h" #include "src/v8.h" +#include "src/wasm/compilation-manager.h" #include "src/wasm/module-compiler.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-code-specialization.h" @@ -873,9 +874,9 @@ void wasm::AsyncCompile(Isolate* isolate, Handle promise, // during asynchronous compilation. std::unique_ptr copy(new byte[bytes.length()]); memcpy(copy.get(), bytes.start(), bytes.length()); - auto job = new AsyncCompileJob(isolate, std::move(copy), bytes.length(), - handle(isolate->context()), promise); - job->Start(); + isolate->wasm_compilation_manager()->StartAsyncCompileJob( + isolate, std::move(copy), bytes.length(), handle(isolate->context()), + promise); } Handle wasm::CompileLazy(Isolate* isolate) {