[wasm] Force liftoff compilation after deserialization

The serialized module contains information for each function whether the
serialized code for the function exists, and whether the function has
been executed before serialization. The latter information is used to
decide if the function should get compiled eagerly after deserialization
(in case the function has been executed before serialization), or if the
function should get compiled lazily because it will probably not be
executed anytime soon.

So far this code only worked for eager compilation. When lazy compilation
was enabled, all functions would get compiled lazily after
deserialization. With this CL the behavior described above is extended to
lazy compilation.

R=clemensb@chromium.org

Bug: v8:12926
Change-Id: Ifd6f400396222105feffa472c2e8787e1358220e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3807583
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82171}
This commit is contained in:
Andreas Haas 2022-08-03 14:59:45 +02:00 committed by V8 LUCI CQ
parent ce83994ed8
commit 5c7e3230ab
2 changed files with 9 additions and 9 deletions

View File

@ -3242,9 +3242,8 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
auto* module = native_module_->module();
auto enabled_features = native_module_->enabled_features();
const bool lazy_module = IsLazyModule(module);
base::Optional<CodeSpaceWriteScope> lazy_code_space_write_scope;
if (lazy_module || !lazy_functions.empty()) {
if (IsLazyModule(module) || !lazy_functions.empty()) {
lazy_code_space_write_scope.emplace(native_module_);
}
{
@ -3255,7 +3254,7 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
RequiredTopTierField::encode(ExecutionTier::kTurbofan) |
ReachedTierField::encode(ExecutionTier::kTurbofan);
finished_events_.Add(CompilationEvent::kFinishedExportWrappers);
if (liftoff_functions.empty() || lazy_module) {
if (liftoff_functions.empty()) {
// We have to trigger the compilation events to finish compilation.
// Typically the events get triggered when a CompilationUnit finishes, but
// with lazy compilation there are no compilation units.
@ -3274,16 +3273,17 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization(
func_index);
}
for (auto func_index : liftoff_functions) {
if (lazy_module) {
native_module_->UseLazyStub(func_index);
}
// Check that {func_index} is not contained in {lazy_functions}.
DCHECK_EQ(
compilation_progress_[declared_function_index(module, func_index)],
kProgressAfterTurbofanDeserialization);
// We want to force Liftoff compilation here, as we have a strong hint
// that the function will be needed anyways. Therefore we disable
// lazy compilation.
constexpr bool kNoLazyCompilation = false;
compilation_progress_[declared_function_index(module, func_index)] =
SetupCompilationProgressForFunction(lazy_module, native_module_,
enabled_features, func_index);
SetupCompilationProgressForFunction(
kNoLazyCompilation, native_module_, enabled_features, func_index);
}
}
auto builder = std::make_unique<CompilationUnitBuilder>(native_module_);

View File

@ -32,7 +32,7 @@ function serializeModule() {
const module = new WebAssembly.Module(wire_bytes);
let instance = new WebAssembly.Instance(module, {foo: {bar: () => 1}});
// Execute {f1} until it gets tiered up.
while (%IsLiftoffFunction(instance.exports.f1)) {
while (!%IsTurboFanFunction(instance.exports.f1)) {
instance.exports.f1();
}
// Execute {f2} once, so that the module knows that this is a used function.