Commit 8b450f59 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Add test for async compilation with shared WasmEngine.

R=ahaas@chromium.org
TEST=cctest/test-wasm-shared-engine
BUG=v8:7424

Change-Id: Idad7bcfe2734df7395c62ec56fb737e180035c76
Reviewed-on: https://chromium-review.googlesource.com/1152918
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54808}
parent 5ce32920
...@@ -222,12 +222,14 @@ AsyncCompileJob* WasmEngine::CreateAsyncCompileJob( ...@@ -222,12 +222,14 @@ AsyncCompileJob* WasmEngine::CreateAsyncCompileJob(
AsyncCompileJob* job = new AsyncCompileJob( AsyncCompileJob* job = new AsyncCompileJob(
isolate, std::move(bytes_copy), length, context, std::move(resolver)); isolate, std::move(bytes_copy), length, context, std::move(resolver));
// Pass ownership to the unique_ptr in {jobs_}. // Pass ownership to the unique_ptr in {jobs_}.
base::LockGuard<base::Mutex> guard(&mutex_);
jobs_[job] = std::unique_ptr<AsyncCompileJob>(job); jobs_[job] = std::unique_ptr<AsyncCompileJob>(job);
return job; return job;
} }
std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob( std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob(
AsyncCompileJob* job) { AsyncCompileJob* job) {
base::LockGuard<base::Mutex> guard(&mutex_);
auto item = jobs_.find(job); auto item = jobs_.find(job);
DCHECK(item != jobs_.end()); DCHECK(item != jobs_.end());
std::unique_ptr<AsyncCompileJob> result = std::move(item->second); std::unique_ptr<AsyncCompileJob> result = std::move(item->second);
...@@ -239,15 +241,19 @@ void WasmEngine::AbortCompileJobsOnIsolate(Isolate* isolate) { ...@@ -239,15 +241,19 @@ void WasmEngine::AbortCompileJobsOnIsolate(Isolate* isolate) {
// Iterate over a copy of {jobs_}, because {job->Abort} modifies {jobs_}. // Iterate over a copy of {jobs_}, because {job->Abort} modifies {jobs_}.
std::vector<AsyncCompileJob*> isolate_jobs; std::vector<AsyncCompileJob*> isolate_jobs;
for (auto& entry : jobs_) { {
if (entry.first->isolate() != isolate) continue; base::LockGuard<base::Mutex> guard(&mutex_);
isolate_jobs.push_back(entry.first); for (auto& entry : jobs_) {
if (entry.first->isolate() != isolate) continue;
isolate_jobs.push_back(entry.first);
}
} }
for (auto* job : isolate_jobs) job->Abort(); for (auto* job : isolate_jobs) job->Abort();
} }
void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) { void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
base::LockGuard<base::Mutex> guard(&mutex_);
for (auto it = jobs_.begin(); it != jobs_.end();) { for (auto it = jobs_.begin(); it != jobs_.end();) {
if (it->first->isolate() == isolate) { if (it->first->isolate() == isolate) {
it = jobs_.erase(it); it = jobs_.erase(it);
......
...@@ -149,9 +149,6 @@ class V8_EXPORT_PRIVATE WasmEngine { ...@@ -149,9 +149,6 @@ class V8_EXPORT_PRIVATE WasmEngine {
std::unique_ptr<CompilationResultResolver> resolver); std::unique_ptr<CompilationResultResolver> resolver);
void TearDown(); void TearDown();
// 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_; std::unique_ptr<WasmCodeManager> code_manager_;
WasmMemoryTracker memory_tracker_; WasmMemoryTracker memory_tracker_;
AccountingAllocator allocator_; AccountingAllocator allocator_;
...@@ -163,6 +160,10 @@ class V8_EXPORT_PRIVATE WasmEngine { ...@@ -163,6 +160,10 @@ class V8_EXPORT_PRIVATE WasmEngine {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Protected by {mutex_}: // Protected by {mutex_}:
// 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_;
// Contains all CancelableTaskManagers that run tasks that are dependent // Contains all CancelableTaskManagers that run tasks that are dependent
// on the engine. Will be canceled on engine tear down. // on the engine. Will be canceled on engine tear down.
std::list<CancelableTaskManager*> task_managers_; std::list<CancelableTaskManager*> task_managers_;
......
...@@ -141,6 +141,61 @@ ZoneBuffer* BuildReturnConstantModule(Zone* zone, int constant) { ...@@ -141,6 +141,61 @@ ZoneBuffer* BuildReturnConstantModule(Zone* zone, int constant) {
return buffer; return buffer;
} }
class MockInstantiationResolver : public InstantiationResultResolver {
public:
explicit MockInstantiationResolver(Handle<Object>* out_instance)
: out_instance_(out_instance) {}
virtual void OnInstantiationSucceeded(Handle<WasmInstanceObject> result) {
*out_instance_->location() = *result;
}
virtual void OnInstantiationFailed(Handle<Object> error_reason) {
UNREACHABLE();
}
private:
Handle<Object>* out_instance_;
};
class MockCompilationResolver : public CompilationResultResolver {
public:
MockCompilationResolver(SharedEngineIsolate& isolate,
Handle<Object>* out_instance)
: isolate_(isolate), out_instance_(out_instance) {}
virtual void OnCompilationSucceeded(Handle<WasmModuleObject> result) {
isolate_.isolate()->wasm_engine()->AsyncInstantiate(
isolate_.isolate(),
base::make_unique<MockInstantiationResolver>(out_instance_), result,
{});
}
virtual void OnCompilationFailed(Handle<Object> error_reason) {
UNREACHABLE();
}
private:
SharedEngineIsolate& isolate_;
Handle<Object>* out_instance_;
};
void PumpMessageLoop(SharedEngineIsolate& isolate) {
v8::platform::PumpMessageLoop(i::V8::GetCurrentPlatform(),
isolate.v8_isolate(),
platform::MessageLoopBehavior::kWaitForWork);
isolate.isolate()->RunMicrotasks();
}
Handle<WasmInstanceObject> CompileAndInstantiateAsync(
SharedEngineIsolate& isolate, ZoneBuffer* buffer) {
Handle<Object> maybe_instance = handle(Smi::kZero, isolate.isolate());
isolate.isolate()->wasm_engine()->AsyncCompile(
isolate.isolate(),
base::make_unique<MockCompilationResolver>(isolate, &maybe_instance),
ModuleWireBytes(buffer->begin(), buffer->end()), true);
while (!maybe_instance->IsWasmInstanceObject()) PumpMessageLoop(isolate);
Handle<WasmInstanceObject> instance =
Handle<WasmInstanceObject>::cast(maybe_instance);
return instance;
}
} // namespace } // namespace
TEST(SharedEngineUseCount) { TEST(SharedEngineUseCount) {
...@@ -201,7 +256,7 @@ TEST(SharedEngineRunImported) { ...@@ -201,7 +256,7 @@ TEST(SharedEngineRunImported) {
CHECK_EQ(1, module.use_count()); CHECK_EQ(1, module.use_count());
} }
TEST(SharedEngineRunThreadedBuilding) { TEST(SharedEngineRunThreadedBuildingSync) {
SharedEngine engine; SharedEngine engine;
SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) { SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) {
HandleScope scope(isolate.isolate()); HandleScope scope(isolate.isolate());
...@@ -221,6 +276,28 @@ TEST(SharedEngineRunThreadedBuilding) { ...@@ -221,6 +276,28 @@ TEST(SharedEngineRunThreadedBuilding) {
thread2.Join(); thread2.Join();
} }
TEST(SharedEngineRunThreadedBuildingAsync) {
SharedEngine engine;
SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) {
HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
Handle<WasmInstanceObject> instance =
CompileAndInstantiateAsync(isolate, buffer);
CHECK_EQ(23, isolate.Run(instance));
});
SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) {
HandleScope scope(isolate.isolate());
ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42);
Handle<WasmInstanceObject> instance =
CompileAndInstantiateAsync(isolate, buffer);
CHECK_EQ(42, isolate.Run(instance));
});
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
}
TEST(SharedEngineRunThreadedExecution) { TEST(SharedEngineRunThreadedExecution) {
SharedEngine engine; SharedEngine engine;
SharedModule module; SharedModule module;
......
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