Commit 148039e6 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Reset callbacks after last event

Callbacks can keep embedder objects alive, hence clear them after
delivering the final event.

R=ahaas@chromium.org

Bug: chromium:912764
Change-Id: I9ac739bbce32cb1026991610e0720210717c333e
Reviewed-on: https://chromium-review.googlesource.com/c/1371565
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58168}
parent d1c15973
...@@ -79,7 +79,11 @@ class WireBytesStorage { ...@@ -79,7 +79,11 @@ class WireBytesStorage {
enum class CompilationEvent : uint8_t { enum class CompilationEvent : uint8_t {
kFinishedBaselineCompilation, kFinishedBaselineCompilation,
kFinishedTopTierCompilation, kFinishedTopTierCompilation,
kFailedCompilation kFailedCompilation,
// Marker:
// After an event >= kFirstFinalEvent, no further events are generated.
kFirstFinalEvent = kFinishedTopTierCompilation
}; };
// The implementation of {CompilationState} lives in module-compiler.cc. // The implementation of {CompilationState} lives in module-compiler.cc.
......
...@@ -206,6 +206,18 @@ class CompilationStateImpl { ...@@ -206,6 +206,18 @@ class CompilationStateImpl {
std::vector<WasmCode*> code_to_log_; std::vector<WasmCode*> code_to_log_;
}; };
class FreeCallbacksTask : public Task {
public:
explicit FreeCallbacksTask(
std::vector<CompilationState::callback_t> callbacks)
: callbacks_(std::move(callbacks)) {}
void Run() override { callbacks_.clear(); }
private:
std::vector<CompilationState::callback_t> callbacks_;
};
void NotifyOnEvent(CompilationEvent event, const VoidResult* error_result); void NotifyOnEvent(CompilationEvent event, const VoidResult* error_result);
std::vector<std::unique_ptr<WasmCompilationUnit>>& finish_units() { std::vector<std::unique_ptr<WasmCompilationUnit>>& finish_units() {
...@@ -3205,6 +3217,14 @@ void CompilationStateImpl::Abort() { ...@@ -3205,6 +3217,14 @@ void CompilationStateImpl::Abort() {
} }
} }
background_task_manager_.CancelAndWait(); background_task_manager_.CancelAndWait();
// No more callbacks after abort. Don't free the std::function objects here,
// since this might clear references in the embedder, which is only allowed on
// the main thread.
if (!callbacks_.empty()) {
foreground_task_runner_->PostTask(
base::make_unique<FreeCallbacksTask>(std::move(callbacks_)));
}
DCHECK(callbacks_.empty());
} }
void CompilationStateImpl::SetError(uint32_t func_index, void CompilationStateImpl::SetError(uint32_t func_index,
...@@ -3228,6 +3248,10 @@ void CompilationStateImpl::NotifyOnEvent(CompilationEvent event, ...@@ -3228,6 +3248,10 @@ void CompilationStateImpl::NotifyOnEvent(CompilationEvent event,
const VoidResult* error_result) { const VoidResult* error_result) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
for (auto& callback : callbacks_) callback(event, error_result); for (auto& callback : callbacks_) callback(event, error_result);
// 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
// foreground tasks.
if (event >= CompilationEvent::kFirstFinalEvent) callbacks_.clear();
} }
void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module, void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* 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