[wasm] Call callbacks from background
The CompilationState should not be bound to a specific isolate. Hence it cannot start foreground task. Instead, the callbacks themselves should do this if they are specific to one Isolate. R=mstarzinger@chromium.org Bug: v8:8689, v8:8050 Change-Id: Ic86bba1dd645401b2b284a9f26eec87718b011e1 Reviewed-on: https://chromium-review.googlesource.com/c/1445977 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#59225}
This commit is contained in:
parent
7a2394686f
commit
5f6de71a37
@ -1087,9 +1087,14 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
case CompilationEvent::kFinishedBaselineCompilation:
|
||||
DCHECK(!last_event_.has_value());
|
||||
if (job_->DecrementAndCheckFinisherCount()) {
|
||||
SaveContext saved_context(job_->isolate());
|
||||
job_->isolate()->set_context(*job_->native_context_);
|
||||
job_->FinishCompile();
|
||||
AsyncCompileJob* job = job_;
|
||||
job->foreground_task_runner_->PostTask(
|
||||
MakeCancelableTask(job->isolate_, [job] {
|
||||
HandleScope scope(job->isolate_);
|
||||
SaveContext saved_context(job->isolate_);
|
||||
job->isolate_->set_context(*job->native_context_);
|
||||
job->FinishCompile();
|
||||
}));
|
||||
}
|
||||
break;
|
||||
case CompilationEvent::kFinishedTopTierCompilation:
|
||||
@ -1097,15 +1102,21 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
// This callback should not react to top tier finished callbacks, since
|
||||
// the job might already be gone then.
|
||||
break;
|
||||
case CompilationEvent::kFailedCompilation:
|
||||
case CompilationEvent::kFailedCompilation: {
|
||||
DCHECK(!last_event_.has_value());
|
||||
// Tier-up compilation should not fail if baseline compilation
|
||||
// did not fail.
|
||||
DCHECK(!Impl(job_->native_module_->compilation_state())
|
||||
->baseline_compilation_finished());
|
||||
|
||||
job_->DoSync<CompileFailed, kUseExistingForegroundTask>();
|
||||
AsyncCompileJob* job = job_;
|
||||
job->foreground_task_runner_->PostTask(
|
||||
MakeCancelableTask(job->isolate_, [job] {
|
||||
job->DoSync<CompileFailed, kUseExistingForegroundTask>();
|
||||
}));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1117,6 +1128,8 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
private:
|
||||
AsyncCompileJob* job_;
|
||||
#ifdef DEBUG
|
||||
// This will be modified by different threads, but they externally
|
||||
// synchronize, so no explicit synchronization (currently) needed here.
|
||||
base::Optional<CompilationEvent> last_event_;
|
||||
#endif
|
||||
};
|
||||
@ -1699,9 +1712,6 @@ void CompilationStateImpl::OnFinishedUnit(ExecutionTier tier, WasmCode* code) {
|
||||
// tiering units.
|
||||
DCHECK_IMPLIES(!is_tiering_mode, outstanding_tiering_units_ == 0);
|
||||
|
||||
// Bitset of events to deliver.
|
||||
base::EnumSet<CompilationEvent> events;
|
||||
|
||||
if (is_tiering_unit) {
|
||||
DCHECK_LT(0, outstanding_tiering_units_);
|
||||
--outstanding_tiering_units_;
|
||||
@ -1709,35 +1719,23 @@ void CompilationStateImpl::OnFinishedUnit(ExecutionTier tier, WasmCode* code) {
|
||||
// If baseline compilation has not finished yet, then also trigger
|
||||
// {kFinishedBaselineCompilation}.
|
||||
if (outstanding_baseline_units_ > 0) {
|
||||
events.Add(CompilationEvent::kFinishedBaselineCompilation);
|
||||
NotifyOnEvent(CompilationEvent::kFinishedBaselineCompilation);
|
||||
}
|
||||
events.Add(CompilationEvent::kFinishedTopTierCompilation);
|
||||
NotifyOnEvent(CompilationEvent::kFinishedTopTierCompilation);
|
||||
}
|
||||
} else {
|
||||
DCHECK_LT(0, outstanding_baseline_units_);
|
||||
--outstanding_baseline_units_;
|
||||
if (outstanding_baseline_units_ == 0) {
|
||||
events.Add(CompilationEvent::kFinishedBaselineCompilation);
|
||||
NotifyOnEvent(CompilationEvent::kFinishedBaselineCompilation);
|
||||
// If we are not tiering, then we also trigger the "top tier finished"
|
||||
// event when baseline compilation is finished.
|
||||
if (!is_tiering_mode) {
|
||||
events.Add(CompilationEvent::kFinishedTopTierCompilation);
|
||||
NotifyOnEvent(CompilationEvent::kFinishedTopTierCompilation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!events.empty()) {
|
||||
auto notify_events = [this, events] {
|
||||
for (auto event : {CompilationEvent::kFinishedBaselineCompilation,
|
||||
CompilationEvent::kFinishedTopTierCompilation}) {
|
||||
if (!events.contains(event)) continue;
|
||||
NotifyOnEvent(event);
|
||||
}
|
||||
};
|
||||
foreground_task_runner_->PostTask(
|
||||
MakeCancelableTask(&foreground_task_manager_, notify_events));
|
||||
}
|
||||
|
||||
if (should_log_code_ && code != nullptr) {
|
||||
engine_->LogCode(code);
|
||||
}
|
||||
@ -1840,13 +1838,10 @@ void CompilationStateImpl::SetError(uint32_t func_index,
|
||||
compile_error.release();
|
||||
// Schedule a foreground task to call the callback and notify users about the
|
||||
// compile error.
|
||||
foreground_task_runner_->PostTask(MakeCancelableTask(
|
||||
&foreground_task_manager_,
|
||||
[this] { NotifyOnEvent(CompilationEvent::kFailedCompilation); }));
|
||||
NotifyOnEvent(CompilationEvent::kFailedCompilation);
|
||||
}
|
||||
|
||||
void CompilationStateImpl::NotifyOnEvent(CompilationEvent event) {
|
||||
HandleScope scope(isolate_);
|
||||
for (auto& callback : callbacks_) callback(event);
|
||||
// If no more events are expected after this one, clear the callbacks to free
|
||||
// memory. We can safely do this here, as this method is only called from
|
||||
|
@ -19,7 +19,9 @@
|
||||
#include "src/objects/js-promise-inl.h"
|
||||
#include "src/objects/templates.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/task-utils.h"
|
||||
#include "src/trap-handler/trap-handler.h"
|
||||
#include "src/v8.h"
|
||||
#include "src/wasm/streaming-decoder.h"
|
||||
#include "src/wasm/wasm-engine.h"
|
||||
#include "src/wasm/wasm-limits.h"
|
||||
@ -69,15 +71,24 @@ class WasmStreaming::WasmStreamingImpl {
|
||||
|
||||
void SetClient(std::shared_ptr<Client> client) {
|
||||
// There are no other event notifications so just pass client to decoder.
|
||||
// Wrap the client with a callback here so we can also wrap the result.
|
||||
// Wrap the client with a callback to trigger the callback in a new
|
||||
// foreground task.
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
|
||||
v8::Platform* platform = i::V8::GetCurrentPlatform();
|
||||
std::shared_ptr<TaskRunner> foreground_task_runner =
|
||||
platform->GetForegroundTaskRunner(isolate_);
|
||||
streaming_decoder_->SetModuleCompiledCallback(
|
||||
[client](const std::shared_ptr<i::wasm::NativeModule>& native_module) {
|
||||
client->OnModuleCompiled(Utils::Convert(native_module));
|
||||
[client, i_isolate, foreground_task_runner](
|
||||
const std::shared_ptr<i::wasm::NativeModule>& native_module) {
|
||||
foreground_task_runner->PostTask(
|
||||
i::MakeCancelableTask(i_isolate, [client, native_module] {
|
||||
client->OnModuleCompiled(Utils::Convert(native_module));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
Isolate* isolate_ = nullptr;
|
||||
Isolate* const isolate_;
|
||||
std::shared_ptr<internal::wasm::StreamingDecoder> streaming_decoder_;
|
||||
std::shared_ptr<internal::wasm::CompilationResultResolver> resolver_;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user