[wasm] Cancel compilation only per context

At the moment we cancel all {AsyncCompileJobs} when a context of an
isolate gets disposed. However, there can be multiple contexts per
isolate, which meant that in some cases we canceled compilations even
though their context was still alive.

With this CL we only abort the compilations of the native context,
which is typically the context that is being disposed.

This is a small change that can be merged back. I plan to do a proper
change later which extends the V8 API so that the embedder provides
a handle to the context that is disposed.

R=clemensh@chromium.org

Bug: chromium:980876
Change-Id: I278bc30f084fe31fa409f1d4f913f1186b4809ec
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1692939
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62627}
This commit is contained in:
Andreas Haas 2019-07-10 12:56:53 +02:00 committed by Commit Bot
parent b6b96bf49c
commit cb024babdd
4 changed files with 33 additions and 3 deletions

View File

@ -8342,9 +8342,14 @@ void Isolate::LowMemoryNotification() {
int Isolate::ContextDisposedNotification(bool dependant_context) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
if (!dependant_context) {
// We left the current context, we can abort all WebAssembly compilations on
// that isolate.
isolate->wasm_engine()->DeleteCompileJobsOnIsolate(isolate);
if (!isolate->context().is_null()) {
// We left the current context, we can abort all WebAssembly compilations
// of that context.
// A handle scope for the native context.
i::HandleScope handle_scope(isolate);
isolate->wasm_engine()->DeleteCompileJobsOnContext(
isolate->native_context());
}
}
// TODO(ahaas): move other non-heap activity out of the heap call.
return isolate->heap()->NotifyContextDisposed(dependant_context);

View File

@ -119,6 +119,8 @@ class AsyncCompileJob {
Isolate* isolate() const { return isolate_; }
Handle<Context> context() const { return native_context_; }
private:
class CompileTask;
class CompileStep;

View File

@ -541,6 +541,24 @@ bool WasmEngine::HasRunningCompileJob(Isolate* isolate) {
return false;
}
void WasmEngine::DeleteCompileJobsOnContext(Handle<Context> context) {
// Under the mutex get all jobs to delete. Then delete them without holding
// the mutex, such that deletion can reenter the WasmEngine.
std::vector<std::unique_ptr<AsyncCompileJob>> jobs_to_delete;
{
base::MutexGuard guard(&mutex_);
for (auto it = async_compile_jobs_.begin();
it != async_compile_jobs_.end();) {
if (!it->first->context().is_identical_to(context)) {
++it;
continue;
}
jobs_to_delete.push_back(std::move(it->second));
it = async_compile_jobs_.erase(it);
}
}
}
void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) {
// Under the mutex get all jobs to delete. Then delete them without holding
// the mutex, such that deletion can reenter the WasmEngine.

View File

@ -140,6 +140,11 @@ class V8_EXPORT_PRIVATE WasmEngine {
// Isolate is currently running.
bool HasRunningCompileJob(Isolate* isolate);
// Deletes all AsyncCompileJobs that belong to the given context. All
// compilation is aborted, no more callbacks will be triggered. This is used
// when a context is disposed, e.g. because of browser navigation.
void DeleteCompileJobsOnContext(Handle<Context> context);
// Deletes all AsyncCompileJobs that belong to the given Isolate. All
// compilation is aborted, no more callbacks will be triggered. This is used
// for tearing down an isolate, or to clean it up to be reused.