[wasm] Remove kFinishedTopTierCompilation event

This fully removes the kFinishedTopTierCompilation event, and any
handling of it. In a dynamic tiering world, that event has no meaning
any more.

R=ahaas@chromium.org

Bug: v8:12899
Change-Id: I36484e36f7c36f2ac4fcb111e67a14509c2eefef
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3667081
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80930}
This commit is contained in:
Clemens Backes 2022-06-02 17:13:31 +02:00 committed by V8 LUCI CQ
parent 51d662f712
commit 13567f5f3a
6 changed files with 32 additions and 80 deletions

View File

@ -111,14 +111,12 @@ class WireBytesStorage {
virtual base::Optional<ModuleWireBytes> GetModuleBytes() const = 0;
};
// Callbacks will receive either {kFailedCompilation} or both
// {kFinishedBaselineCompilation} and {kFinishedTopTierCompilation}, in that
// order. If tier up is off, both events are delivered right after each other.
// Callbacks will receive either {kFailedCompilation} or
// {kFinishedBaselineCompilation}.
enum class CompilationEvent : uint8_t {
kFinishedBaselineCompilation,
kFinishedExportWrappers,
kFinishedCompilationChunk,
kFinishedTopTierCompilation,
kFailedCompilation,
kFinishedRecompilation
};
@ -169,7 +167,6 @@ class V8_EXPORT_PRIVATE CompilationState {
bool failed() const;
bool baseline_compilation_finished() const;
bool top_tier_compilation_finished() const;
bool recompilation_finished() const;
void set_compilation_id(int compilation_id);

View File

@ -646,11 +646,6 @@ class CompilationStateImpl {
outstanding_export_wrappers_ == 0;
}
bool top_tier_compilation_finished() const {
base::MutexGuard guard(&callbacks_mutex_);
return outstanding_top_tier_functions_ == 0;
}
bool recompilation_finished() const {
base::MutexGuard guard(&callbacks_mutex_);
return outstanding_recompilation_functions_ == 0;
@ -873,10 +868,6 @@ bool CompilationState::baseline_compilation_finished() const {
return Impl(this)->baseline_compilation_finished();
}
bool CompilationState::top_tier_compilation_finished() const {
return Impl(this)->top_tier_compilation_finished();
}
bool CompilationState::recompilation_finished() const {
return Impl(this)->recompilation_finished();
}
@ -2371,11 +2362,6 @@ class AsyncCompileJob::CompilationStateCallback
DCHECK(CompilationEvent::kFinishedBaselineCompilation == last_event_ ||
CompilationEvent::kFinishedCompilationChunk == last_event_);
break;
case CompilationEvent::kFinishedTopTierCompilation:
DCHECK(CompilationEvent::kFinishedBaselineCompilation == last_event_);
// At this point, the job will already be gone, thus do not access it
// here.
break;
case CompilationEvent::kFailedCompilation:
DCHECK(!last_event_.has_value() ||
last_event_ == CompilationEvent::kFinishedExportWrappers);
@ -2389,8 +2375,7 @@ class AsyncCompileJob::CompilationStateCallback
}
break;
case CompilationEvent::kFinishedRecompilation:
// This event can happen either before or after
// {kFinishedTopTierCompilation}, hence don't remember this in
// This event can happen out of order, hence don't remember this in
// {last_event_}.
return;
}
@ -3295,13 +3280,6 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
// The {kFinishedBaselineCompilation} event is needed for module
// compilation to finish.
finished_events_.Add(CompilationEvent::kFinishedBaselineCompilation);
if (liftoff_functions.empty() && lazy_functions.empty()) {
// All functions exist now as TurboFan functions, so we can trigger the
// {kFinishedTopTierCompilation} event.
// The {kFinishedTopTierCompilation} event is needed for the C-API so
// that {serialize()} works after {deserialize()}.
finished_events_.Add(CompilationEvent::kFinishedTopTierCompilation);
}
}
compilation_progress_.assign(module->num_declared_functions,
kProgressAfterTurbofanDeserialization);
@ -3418,14 +3396,12 @@ void CompilationStateImpl::AddCallback(
// Immediately trigger events that already happened.
for (auto event : {CompilationEvent::kFinishedExportWrappers,
CompilationEvent::kFinishedBaselineCompilation,
CompilationEvent::kFinishedTopTierCompilation,
CompilationEvent::kFailedCompilation}) {
if (finished_events_.contains(event)) {
callback->call(event);
}
}
constexpr base::EnumSet<CompilationEvent> kFinalEvents{
CompilationEvent::kFinishedTopTierCompilation,
CompilationEvent::kFailedCompilation};
if (!finished_events_.contains_any(kFinalEvents)) {
callbacks_.emplace_back(std::move(callback));
@ -3636,17 +3612,17 @@ void CompilationStateImpl::TriggerCallbacks(
triggered_events.Add(CompilationEvent::kFinishedExportWrappers);
if (outstanding_baseline_units_ == 0) {
triggered_events.Add(CompilationEvent::kFinishedBaselineCompilation);
if (!dynamic_tiering_ && outstanding_top_tier_functions_ == 0) {
triggered_events.Add(CompilationEvent::kFinishedTopTierCompilation);
}
}
}
// For dynamic tiering, trigger "compilation chunk finished" after a new chunk
// of size {FLAG_wasm_caching_threshold}.
if (dynamic_tiering_ && static_cast<size_t>(FLAG_wasm_caching_threshold) <
bytes_since_last_chunk_) {
triggered_events.Add(CompilationEvent::kFinishedCompilationChunk);
bytes_since_last_chunk_ = 0;
}
if (compile_failed_.load(std::memory_order_relaxed)) {
// *Only* trigger the "failed" event.
triggered_events =
@ -3670,8 +3646,6 @@ void CompilationStateImpl::TriggerCallbacks(
"wasm.ExportWrappersFinished"),
std::make_pair(CompilationEvent::kFinishedBaselineCompilation,
"wasm.BaselineFinished"),
std::make_pair(CompilationEvent::kFinishedTopTierCompilation,
"wasm.TopTierFinished"),
std::make_pair(CompilationEvent::kFinishedCompilationChunk,
"wasm.CompilationChunkFinished"),
std::make_pair(CompilationEvent::kFinishedRecompilation,
@ -3854,15 +3828,8 @@ void CompilationStateImpl::WaitForCompilationEvent(
};
WaitForEventDelegate delegate{done};
// Everything except for top-tier units will be processed with kBaselineOnly
// (including wrappers). Hence we choose this for any event except
// {kFinishedTopTierCompilation}.
auto compile_tiers =
expect_event == CompilationEvent::kFinishedTopTierCompilation
? kBaselineOrTopTier
: kBaselineOnly;
ExecuteCompilationUnits(native_module_weak_, async_counters_.get(), &delegate,
compile_tiers);
kBaselineOnly);
semaphore->Wait();
}

View File

@ -332,10 +332,7 @@ class CompilationChunkFinishedCallback : public CompilationEventCallback {
}
void call(CompilationEvent event) override {
if (event != CompilationEvent::kFinishedCompilationChunk &&
event != CompilationEvent::kFinishedTopTierCompilation) {
return;
}
if (event != CompilationEvent::kFinishedCompilationChunk) return;
// If the native module is still alive, get back a shared ptr and call the
// callback.
if (std::shared_ptr<NativeModule> native_module = native_module_.lock()) {

View File

@ -1705,15 +1705,11 @@ void NativeModule::SetWireBytes(base::OwnedVector<const uint8_t> wire_bytes) {
}
void NativeModule::UpdateCPUDuration(size_t cpu_duration, ExecutionTier tier) {
if (tier == WasmCompilationUnit::GetBaselineExecutionTier(this->module())) {
if (!compilation_state_->baseline_compilation_finished()) {
baseline_compilation_cpu_duration_.fetch_add(cpu_duration,
std::memory_order_relaxed);
}
if (!compilation_state_->baseline_compilation_finished()) {
baseline_compilation_cpu_duration_.fetch_add(cpu_duration,
std::memory_order_relaxed);
} else if (tier == ExecutionTier::kTurbofan) {
if (!compilation_state_->top_tier_compilation_finished()) {
tier_up_cpu_duration_.fetch_add(cpu_duration, std::memory_order_relaxed);
}
tier_up_cpu_duration_.fetch_add(cpu_duration, std::memory_order_relaxed);
}
}

View File

@ -195,7 +195,6 @@ TEST(Run_WasmModule_CompilationHintsNoTiering) {
CHECK_EQ(expected_tier, actual_tier);
auto* compilation_state = native_module->compilation_state();
CHECK(compilation_state->baseline_compilation_finished());
CHECK(compilation_state->top_tier_compilation_finished());
}
Cleanup();
}
@ -247,19 +246,14 @@ TEST(Run_WasmModule_CompilationHintsTierUp) {
CHECK(compilation_state->baseline_compilation_finished());
}
// Busy wait for top tier compilation to finish.
while (!compilation_state->top_tier_compilation_finished()) {
}
// Expect top tier code.
// Tier-up is happening in the background. Eventually we should have top
// tier code.
ExecutionTier top_tier = ExecutionTier::kTurbofan;
{
ExecutionTier actual_tier = ExecutionTier::kNone;
while (actual_tier != top_tier) {
CHECK(native_module->HasCode(kFuncIndex));
WasmCodeRefScope code_ref_scope;
ExecutionTier actual_tier = native_module->GetCode(kFuncIndex)->tier();
CHECK_EQ(top_tier, actual_tier);
CHECK(compilation_state->baseline_compilation_finished());
CHECK(compilation_state->top_tier_compilation_finished());
actual_tier = native_module->GetCode(kFuncIndex)->tier();
}
}
Cleanup();
@ -301,23 +295,19 @@ TEST(Run_WasmModule_CompilationHintsLazyBaselineEagerTopTier) {
NativeModule* native_module = module.ToHandleChecked()->native_module();
auto* compilation_state = native_module->compilation_state();
// Busy wait for top tier compilation to finish.
while (!compilation_state->top_tier_compilation_finished()) {
}
// Expect top tier code.
// We have no code initially (because of lazy baseline), but eventually we
// should have TurboFan ready (because of eager top tier).
static_assert(ExecutionTier::kLiftoff < ExecutionTier::kTurbofan,
"Assume an order on execution tiers");
static const int kFuncIndex = 0;
ExecutionTier top_tier = ExecutionTier::kTurbofan;
{
CHECK(native_module->HasCode(kFuncIndex));
WasmCodeRefScope code_ref_scope;
ExecutionTier actual_tier = native_module->GetCode(kFuncIndex)->tier();
CHECK_EQ(top_tier, actual_tier);
CHECK(compilation_state->baseline_compilation_finished());
CHECK(compilation_state->top_tier_compilation_finished());
constexpr int kFuncIndex = 0;
WasmCodeRefScope code_ref_scope;
while (true) {
auto* code = native_module->GetCode(kFuncIndex);
if (!code) continue;
CHECK_EQ(ExecutionTier::kTurbofan, code->tier());
break;
}
CHECK(compilation_state->baseline_compilation_finished());
}
Cleanup();
}

View File

@ -1322,6 +1322,11 @@ STREAM_TEST(TestFunctionSectionWithoutCodeSection) {
}
STREAM_TEST(TestSetModuleCompiledCallback) {
// The "module compiled" callback (to be renamed to "top tier chunk finished"
// or similar) will only be triggered with dynamic tiering, so skip this test
// if dynamic tiering is disabled.
if (!FLAG_wasm_dynamic_tiering) return;
// Reduce the caching threshold so that our three small functions trigger
// caching.
FlagScope<int> caching_treshold(&FLAG_wasm_caching_threshold, 10);