[wasm] Fix loop condition in serialization

JobDelegate::ShouldYield() should not be called anymore after it has
already returned true. This CL changes the deserialization of
WebAssembly to remember when ShouldYield() returned for the first time,
and does not call ShouldYield() afterwards anymore.

R=thibaudm@chromium.org

Bug: chromium:1277962
Change-Id: Ie84abf30b20d302a19f3192c3859796be1cccd97
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3647361
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80522}
This commit is contained in:
Andreas Haas 2022-05-13 13:28:59 +02:00 committed by V8 LUCI CQ
parent 2c40f3af4f
commit 3970c447de

View File

@ -588,9 +588,10 @@ class DeserializeCodeTask : public JobTask {
void Run(JobDelegate* delegate) override {
CodeSpaceWriteScope code_space_write_scope(deserializer_->native_module_);
do {
bool finished = false;
while (!finished) {
// Repeatedly publish everything that was copied already.
TryPublishing(delegate);
finished = TryPublishing(delegate);
auto batch = reloc_queue_->Pop();
if (batch.empty()) break;
@ -599,7 +600,7 @@ class DeserializeCodeTask : public JobTask {
}
publish_queue_.Add(std::move(batch));
delegate->NotifyConcurrencyIncrease();
} while (!delegate->ShouldYield());
}
}
size_t GetMaxConcurrency(size_t /* worker_count */) const override {
@ -611,9 +612,9 @@ class DeserializeCodeTask : public JobTask {
}
private:
void TryPublishing(JobDelegate* delegate) {
bool TryPublishing(JobDelegate* delegate) {
// Publishing is sequential, so only start publishing if no one else is.
if (publishing_.exchange(true, std::memory_order_relaxed)) return;
if (publishing_.exchange(true, std::memory_order_relaxed)) return false;
WasmCodeRefScope code_scope;
while (true) {
@ -625,13 +626,14 @@ class DeserializeCodeTask : public JobTask {
yield = delegate->ShouldYield();
}
publishing_.store(false, std::memory_order_relaxed);
if (yield) break;
if (yield) return true;
// After finishing publishing, check again if new work arrived in the mean
// time. If so, continue publishing.
if (publish_queue_.NumBatches() == 0) break;
if (publishing_.exchange(true, std::memory_order_relaxed)) break;
// We successfully reset {publishing_} from {false} to {true}.
}
return false;
}
NativeModuleDeserializer* const deserializer_;