Commit 0263383d authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Move the CompilationManager into the WasmEngine

The CompilationManager was introduced to manage the memory of
AsyncCompileJobs. However, by now this can be done better by the new
WasmEngine.

This CL just moves the code to wasm-engine.[h,cc] and adjusts the
callsites.

R=titzer@chromium.org

Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: Icd2c1f19feeaa854c74e020b41e314b8ad00cea5
Reviewed-on: https://chromium-review.googlesource.com/1052109Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53112}
parent aae0732c
......@@ -2378,8 +2378,6 @@ v8_source_set("v8_base") {
"src/wasm/baseline/liftoff-compiler.cc",
"src/wasm/baseline/liftoff-compiler.h",
"src/wasm/baseline/liftoff-register.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",
......
......@@ -78,7 +78,6 @@
#include "src/value-serializer.h"
#include "src/version.h"
#include "src/vm-state-inl.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/streaming-decoder.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-objects-inl.h"
......@@ -7516,11 +7515,8 @@ WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
i::Handle<i::JSPromise> promise = Utils::OpenHandle(*GetPromise());
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
streaming_decoder_ =
i_isolate->wasm_engine()
->compilation_manager()
->StartStreamingCompilation(i_isolate, handle(i_isolate->context()),
promise);
streaming_decoder_ = i_isolate->wasm_engine()->StartStreamingCompilation(
i_isolate, handle(i_isolate->context()), promise);
}
Local<Promise> WasmModuleObjectBuilderStreaming::GetPromise() {
......@@ -8688,7 +8684,7 @@ int Isolate::ContextDisposedNotification(bool dependant_context) {
if (!dependant_context) {
// We left the current context, we can abort all running WebAssembly
// compilations.
isolate->wasm_engine()->compilation_manager()->AbortAllJobs();
isolate->wasm_engine()->AbortAllCompileJobs();
}
// TODO(ahaas): move other non-heap activity out of the heap call.
return isolate->heap()->NotifyContextDisposed(dependant_context);
......
......@@ -2998,11 +2998,10 @@ void Shell::CompleteMessageLoop(Isolate* isolate) {
base::LockGuard<base::Mutex> guard(isolate_status_lock_.Pointer());
DCHECK_GT(isolate_status_.count(isolate), 0);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::wasm::CompilationManager* wasm_compilation_manager =
i_isolate->wasm_engine()->compilation_manager();
bool should_wait = (options.wait_for_wasm &&
wasm_compilation_manager->HasRunningCompileJob()) ||
isolate_status_[isolate];
i::wasm::WasmEngine* wasm_engine = i_isolate->wasm_engine();
bool should_wait =
(options.wait_for_wasm && wasm_engine->HasRunningCompileJob()) ||
isolate_status_[isolate];
return should_wait ? platform::MessageLoopBehavior::kWaitForWork
: platform::MessageLoopBehavior::kDoNotWait;
};
......
......@@ -57,7 +57,6 @@
#include "src/version.h"
#include "src/visitors.h"
#include "src/vm-state-inl.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-objects.h"
......
// 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/wasm/module-compiler.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
namespace wasm {
AsyncCompileJob* CompilationManager::CreateAsyncCompileJob(
Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, size_t length,
Handle<Context> context, Handle<JSPromise> promise) {
AsyncCompileJob* job = new AsyncCompileJob(isolate, std::move(bytes_copy),
length, context, promise);
// Pass ownership to the unique_ptr in {jobs_}.
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
return job;
}
void CompilationManager::StartAsyncCompileJob(
Isolate* isolate, std::unique_ptr<byte[]> bytes_copy, size_t length,
Handle<Context> context, Handle<JSPromise> promise) {
AsyncCompileJob* job = CreateAsyncCompileJob(isolate, std::move(bytes_copy),
length, context, promise);
job->Start();
}
std::shared_ptr<StreamingDecoder> CompilationManager::StartStreamingCompilation(
Isolate* isolate, Handle<Context> context, Handle<JSPromise> promise) {
AsyncCompileJob* job = CreateAsyncCompileJob(
isolate, std::unique_ptr<byte[]>(nullptr), 0, context, promise);
return job->CreateStreamingDecoder();
}
std::unique_ptr<AsyncCompileJob> CompilationManager::RemoveJob(
AsyncCompileJob* job) {
auto item = jobs_.find(job);
DCHECK(item != jobs_.end());
std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
jobs_.erase(item);
return result;
}
void CompilationManager::TearDown() { jobs_.clear(); }
void CompilationManager::AbortAllJobs() {
// Iterate over a copy of {jobs_}, because {job->Abort} modifies {jobs_}.
std::vector<AsyncCompileJob*> copy;
copy.reserve(jobs_.size());
for (auto& entry : jobs_) copy.push_back(entry.first);
for (auto* job : copy) job->Abort();
}
} // namespace wasm
} // namespace internal
} // namespace v8
// 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 <unordered_map>
#include "src/handles.h"
#include "src/isolate.h"
namespace v8 {
namespace internal {
namespace wasm {
class AsyncCompileJob;
// 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);
std::shared_ptr<StreamingDecoder> StartStreamingCompilation(
Isolate* isolate, Handle<Context> context, Handle<JSPromise> promise);
// Remove {job} from the list of active compile jobs.
std::unique_ptr<AsyncCompileJob> RemoveJob(AsyncCompileJob* job);
// Cancel all AsyncCompileJobs and delete their state immediately.
void TearDown();
// Cancel all AsyncCompileJobs so that they are not processed any further,
// but delay the deletion of their state until all tasks accessing the
// AsyncCompileJob finish their execution.
void AbortAllJobs();
// Returns true if at lease one AsyncCompileJob is currently running.
bool HasRunningCompileJob() const { return !jobs_.empty(); }
private:
AsyncCompileJob* CreateAsyncCompileJob(Isolate* isolate,
std::unique_ptr<byte[]> bytes_copy,
size_t length, Handle<Context> context,
Handle<JSPromise> promise);
// 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::unique_ptr<AsyncCompileJob>> jobs_;
};
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_COMPILATION_MANAGER_H_
......@@ -17,7 +17,6 @@
#include "src/identity-map.h"
#include "src/property-descriptor.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/streaming-decoder.h"
#include "src/wasm/wasm-code-manager.h"
......@@ -2760,7 +2759,7 @@ void AsyncCompileJob::Abort() {
}
if (num_pending_foreground_tasks_ == 0) {
// No task is pending, we can just remove the AsyncCompileJob.
isolate_->wasm_engine()->compilation_manager()->RemoveJob(this);
isolate_->wasm_engine()->RemoveCompileJob(this);
} else {
// There is still a compilation task in the task queue. We enter the
// AbortCompilation state and wait for this compilation task to abort the
......@@ -2871,7 +2870,7 @@ void AsyncCompileJob::AsyncCompileFailed(Handle<Object> error_reason) {
if (stream_) stream_->NotifyError();
// {job} keeps the {this} pointer alive.
std::shared_ptr<AsyncCompileJob> job =
isolate_->wasm_engine()->compilation_manager()->RemoveJob(this);
isolate_->wasm_engine()->RemoveCompileJob(this);
MaybeHandle<Object> promise_result =
JSPromise::Reject(module_promise_, error_reason);
CHECK_EQ(promise_result.is_null(), isolate_->has_pending_exception());
......@@ -3198,7 +3197,7 @@ class AsyncCompileJob::FinishModule : public CompileStep {
num_functions == 0) {
// If we do not tier up, the async compile job is done here and
// can be deleted.
job_->isolate_->wasm_engine()->compilation_manager()->RemoveJob(job_);
job_->isolate_->wasm_engine()->RemoveCompileJob(job_);
return;
}
// If background tiering compilation finished before we resolved the
......@@ -3221,14 +3220,14 @@ class AsyncCompileJob::UpdateToTopTierCompiledCode : public CompileStep {
TRACE_COMPILE("(7) Update native module to use optimized code...\n");
UpdateAllCompiledModulesWithTopTierCode(job_->compiled_module_);
job_->isolate_->wasm_engine()->compilation_manager()->RemoveJob(job_);
job_->isolate_->wasm_engine()->RemoveCompileJob(job_);
}
};
class AsyncCompileJob::AbortCompilation : public CompileStep {
void RunInForeground() override {
TRACE_COMPILE("Abort asynchronous compilation ...\n");
job_->isolate_->wasm_engine()->compilation_manager()->RemoveJob(job_);
job_->isolate_->wasm_engine()->RemoveCompileJob(job_);
}
};
......
......@@ -106,7 +106,6 @@ void WasmEngine::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
if (FLAG_wasm_test_streaming) {
std::shared_ptr<StreamingDecoder> streaming_decoder =
isolate->wasm_engine()
->compilation_manager()
->StartStreamingCompilation(isolate, handle(isolate->context()),
promise);
streaming_decoder->OnBytesReceived(bytes.module_bytes());
......@@ -117,9 +116,18 @@ void WasmEngine::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
// during asynchronous compilation.
std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
isolate->wasm_engine()->compilation_manager()->StartAsyncCompileJob(
isolate, std::move(copy), bytes.length(), handle(isolate->context()),
promise);
AsyncCompileJob* job =
CreateAsyncCompileJob(isolate, std::move(copy), bytes.length(),
handle(isolate->context()), promise);
job->Start();
}
std::shared_ptr<StreamingDecoder> WasmEngine::StartStreamingCompilation(
Isolate* isolate, Handle<Context> context, Handle<JSPromise> promise) {
AsyncCompileJob* job = CreateAsyncCompileJob(
isolate, std::unique_ptr<byte[]>(nullptr), 0, context, promise);
return job->CreateStreamingDecoder();
}
void WasmEngine::Register(CancelableTaskManager* task_manager) {
......@@ -130,6 +138,35 @@ 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, Handle<JSPromise> promise) {
AsyncCompileJob* job = new AsyncCompileJob(isolate, std::move(bytes_copy),
length, context, promise);
// Pass ownership to the unique_ptr in {jobs_}.
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
return job;
}
std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
AsyncCompileJob* job) {
auto item = jobs_.find(job);
DCHECK(item != jobs_.end());
std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
jobs_.erase(item);
return result;
}
void WasmEngine::AbortAllCompileJobs() {
// Iterate over a copy of {jobs_}, because {job->Abort} modifies {jobs_}.
std::vector<AsyncCompileJob*> copy;
copy.reserve(jobs_.size());
for (auto& entry : jobs_) copy.push_back(entry.first);
for (auto* job : copy) job->Abort();
}
void WasmEngine::TearDown() {
// Cancel all registered task managers.
for (auto task_manager : task_managers_) {
......@@ -137,7 +174,7 @@ void WasmEngine::TearDown() {
}
// Cancel all AsyncCompileJobs.
compilation_manager_.TearDown();
jobs_.clear();
}
} // namespace wasm
......
......@@ -7,7 +7,6 @@
#include <memory>
#include "src/wasm/compilation-manager.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-memory.h"
......@@ -67,7 +66,8 @@ class V8_EXPORT_PRIVATE WasmEngine {
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports);
CompilationManager* compilation_manager() { return &compilation_manager_; }
std::shared_ptr<StreamingDecoder> StartStreamingCompilation(
Isolate* isolate, Handle<Context> context, Handle<JSPromise> promise);
WasmCodeManager* code_manager() const { return code_manager_.get(); }
......@@ -79,10 +79,29 @@ class V8_EXPORT_PRIVATE WasmEngine {
void Register(CancelableTaskManager* task_manager);
void Unregister(CancelableTaskManager* task_manager);
// Remove {job} from the list of active compile jobs.
std::unique_ptr<AsyncCompileJob> RemoveCompileJob(AsyncCompileJob* job);
// Returns true if at lease one AsyncCompileJob is currently running.
bool HasRunningCompileJob() const { return !jobs_.empty(); }
// Cancel all AsyncCompileJobs so that they are not processed any further,
// but delay the deletion of their state until all tasks accessing the
// AsyncCompileJob finish their execution. This is used to clean-up the
// isolate to be reused.
void AbortAllCompileJobs();
void TearDown();
private:
CompilationManager compilation_manager_;
AsyncCompileJob* CreateAsyncCompileJob(Isolate* isolate,
std::unique_ptr<byte[]> bytes_copy,
size_t length, Handle<Context> context,
Handle<JSPromise> promise);
// 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::unique_ptr<AsyncCompileJob>> jobs_;
std::unique_ptr<WasmCodeManager> code_manager_;
WasmMemoryTracker memory_tracker_;
......
......@@ -16,7 +16,6 @@
#include "src/simulator.h"
#include "src/snapshot/snapshot.h"
#include "src/v8.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-code-specialization.h"
......
......@@ -7,7 +7,6 @@
#include "src/v8.h"
#include "src/vector.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/streaming-decoder.h"
#include "src/wasm/wasm-engine.h"
......@@ -99,7 +98,6 @@ class StreamTester {
i::Handle<i::JSPromise> i_promise = v8::Utils::OpenHandle(*promise_);
stream_ = i_isolate->wasm_engine()
->compilation_manager()
->StartStreamingCompilation(
i_isolate, v8::Utils::OpenHandle(*context), i_promise);
}
......
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