Commit ea8da506 authored by Andreas Haas's avatar Andreas Haas Committed by V8 LUCI CQ

[wasm] Adjust EstimateNativeModuleCodeSize to dynamic tiering

With dynamic tiering, the total amount of code generated for a
WebAssembly module decreases significantly. However, the amount of
code space we reserved for generated code has not been adjusted yet.
This CL adds a parameter for dynamic tiering to
EstimateNativeModuleCodeSize. If dynamic tiering is used, then the code
space reserved for TurboFan gets reduced to a quarter of the code space
without dynamic tiering.

Reserving a quarter of the space seems to be still quite generous. Even
Google Earth, seems to use a lot of its code, only needs less than 20%.

R=clemensb@chromium.org

Bug: chromium:1285334
Change-Id: I7dce0821b5e46d7240dfb1523031de84b1fe1348
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3420307Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78826}
parent 99a871d8
......@@ -1882,9 +1882,12 @@ std::shared_ptr<NativeModule> CompileToNativeModule(
// Create a new {NativeModule} first.
const bool include_liftoff = module->origin == kWasmOrigin && FLAG_liftoff;
DynamicTiering dynamic_tiering = isolate->IsWasmDynamicTieringEnabled()
? DynamicTiering::kEnabled
: DynamicTiering::kDisabled;
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get(),
include_liftoff);
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
module.get(), include_liftoff, dynamic_tiering);
native_module =
engine->NewNativeModule(isolate, enabled, module, code_size_estimate);
native_module->SetWireBytes(std::move(wire_bytes_copy));
......@@ -1955,6 +1958,9 @@ AsyncCompileJob::AsyncCompileJob(
: isolate_(isolate),
api_method_name_(api_method_name),
enabled_features_(enabled),
dynamic_tiering_(isolate_->IsWasmDynamicTieringEnabled()
? DynamicTiering::kEnabled
: DynamicTiering::kDisabled),
wasm_lazy_compilation_(FLAG_wasm_lazy_compilation),
start_time_(base::TimeTicks::Now()),
bytes_copy_(std::move(bytes_copy)),
......@@ -2489,8 +2495,8 @@ class AsyncCompileJob::DecodeModule : public AsyncCompileJob::CompileStep {
std::shared_ptr<WasmModule> module = std::move(result).value();
const bool include_liftoff = FLAG_liftoff;
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get(),
include_liftoff);
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
module.get(), include_liftoff, job->dynamic_tiering_);
job->DoSync<PrepareAndStartCompile>(std::move(module), true,
code_size_estimate);
}
......@@ -2791,7 +2797,7 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader(
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
num_functions, num_imported_functions, code_section_length,
include_liftoff);
include_liftoff, job_->dynamic_tiering_);
job_->DoImmediately<AsyncCompileJob::PrepareAndStartCompile>(
decoder_.shared_module(), false, code_size_estimate);
......@@ -2894,7 +2900,7 @@ void AsyncStreamingProcessor::OnFinishedStream(
const bool include_liftoff = FLAG_liftoff;
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
result.value().get(), include_liftoff);
result.value().get(), include_liftoff, job_->dynamic_tiering_);
job_->DoSync<AsyncCompileJob::PrepareAndStartCompile>(
std::move(result).value(), true, code_size_estimate);
return;
......
......@@ -215,6 +215,7 @@ class AsyncCompileJob {
Isolate* const isolate_;
const char* const api_method_name_;
const WasmFeatures enabled_features_;
const DynamicTiering dynamic_tiering_;
const bool wasm_lazy_compilation_;
base::TimeTicks start_time_;
// Copy of the module wire bytes, moved into the {native_module_} on its
......
......@@ -2043,8 +2043,9 @@ size_t WasmCodeManager::EstimateLiftoffCodeSize(int body_size) {
}
// static
size_t WasmCodeManager::EstimateNativeModuleCodeSize(const WasmModule* module,
bool include_liftoff) {
size_t WasmCodeManager::EstimateNativeModuleCodeSize(
const WasmModule* module, bool include_liftoff,
DynamicTiering dynamic_tiering) {
int num_functions = static_cast<int>(module->num_declared_functions);
int num_imported_functions = static_cast<int>(module->num_imported_functions);
int code_section_length = 0;
......@@ -2056,25 +2057,40 @@ size_t WasmCodeManager::EstimateNativeModuleCodeSize(const WasmModule* module,
static_cast<int>(last_fn->code.end_offset() - first_fn->code.offset());
}
return EstimateNativeModuleCodeSize(num_functions, num_imported_functions,
code_section_length, include_liftoff);
code_section_length, include_liftoff,
dynamic_tiering);
}
// static
size_t WasmCodeManager::EstimateNativeModuleCodeSize(int num_functions,
int num_imported_functions,
int code_section_length,
bool include_liftoff) {
const size_t overhead_per_function =
kTurbofanFunctionOverhead + kCodeAlignment / 2 +
(include_liftoff ? kLiftoffFunctionOverhead + kCodeAlignment / 2 : 0);
const size_t overhead_per_code_byte =
kTurbofanCodeSizeMultiplier +
(include_liftoff ? kLiftoffCodeSizeMultiplier : 0);
size_t WasmCodeManager::EstimateNativeModuleCodeSize(
int num_functions, int num_imported_functions, int code_section_length,
bool include_liftoff, DynamicTiering dynamic_tiering) {
// Note that the size for jump tables is added later, in {ReservationSize} /
// {OverheadPerCodeSpace}.
return overhead_per_function * num_functions // per function
+ overhead_per_code_byte * code_section_length // per code byte
+ kImportSize * num_imported_functions; // per import
const size_t size_of_imports = kImportSize * num_imported_functions;
const size_t overhead_per_function_turbofan =
kTurbofanFunctionOverhead + kCodeAlignment / 2;
size_t size_of_turbofan = overhead_per_function_turbofan * num_functions +
kTurbofanCodeSizeMultiplier * code_section_length;
const size_t overhead_per_function_liftoff =
kLiftoffFunctionOverhead + kCodeAlignment / 2;
size_t size_of_liftoff = overhead_per_function_liftoff * num_functions +
kLiftoffCodeSizeMultiplier * code_section_length;
if (!include_liftoff) {
size_of_liftoff = 0;
}
// With dynamic tiering we don't expect to compile more than 25% with
// TurboFan. If there is no liftoff though then all code will get generated
// by TurboFan.
if (include_liftoff && dynamic_tiering == DynamicTiering::kEnabled) {
size_of_turbofan /= 4;
}
return size_of_imports + size_of_liftoff + size_of_turbofan;
}
// static
......
......@@ -1031,13 +1031,15 @@ class V8_EXPORT_PRIVATE WasmCodeManager final {
static size_t EstimateLiftoffCodeSize(int body_size);
// Estimate the needed code space from a completely decoded module.
static size_t EstimateNativeModuleCodeSize(const WasmModule* module,
bool include_liftoff);
bool include_liftoff,
DynamicTiering dynamic_tiering);
// Estimate the needed code space from the number of functions and total code
// section length.
static size_t EstimateNativeModuleCodeSize(int num_functions,
int num_imported_functions,
int code_section_length,
bool include_liftoff);
bool include_liftoff,
DynamicTiering dynamic_tiering);
// Estimate the size of meta data needed for the NativeModule, excluding
// generated code. This data still be stored on the C++ heap.
static size_t EstimateNativeModuleMetaDataSize(const WasmModule* module);
......
......@@ -2191,8 +2191,8 @@ Handle<AsmWasmData> AsmWasmData::New(
const WasmModule* module = native_module->module();
const bool kUsesLiftoff = false;
size_t memory_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module,
kUsesLiftoff) +
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
module, kUsesLiftoff, wasm::DynamicTiering::kDisabled) +
wasm::WasmCodeManager::EstimateNativeModuleMetaDataSize(module);
Handle<Managed<wasm::NativeModule>> managed_native_module =
Managed<wasm::NativeModule>::FromSharedPtr(isolate, memory_estimate,
......
......@@ -873,10 +873,13 @@ MaybeHandle<WasmModuleObject> DeserializeNativeModule(
auto shared_native_module = wasm_engine->MaybeGetNativeModule(
module->origin, owned_wire_bytes.as_vector(), isolate);
if (shared_native_module == nullptr) {
const bool kIncludeLiftoff = false;
DynamicTiering dynamic_tiering = isolate->IsWasmDynamicTieringEnabled()
? DynamicTiering::kEnabled
: DynamicTiering::kDisabled;
const bool kIncludeLiftoff = dynamic_tiering == DynamicTiering::kDisabled;
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get(),
kIncludeLiftoff);
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
module.get(), kIncludeLiftoff, dynamic_tiering);
shared_native_module = wasm_engine->NewNativeModule(
isolate, enabled_features, std::move(module), code_size_estimate);
// We have to assign a compilation ID here, as it is required for a
......
......@@ -360,9 +360,12 @@ const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
const bool kUsesLiftoff = true;
DynamicTiering dynamic_tiering = FLAG_wasm_dynamic_tiering
? DynamicTiering::kEnabled
: DynamicTiering::kDisabled;
size_t code_size_estimate =
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(test_module_.get(),
kUsesLiftoff);
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(
test_module_.get(), kUsesLiftoff, dynamic_tiering);
auto native_module = GetWasmEngine()->NewNativeModule(
isolate_, enabled_features_, test_module_, code_size_estimate);
native_module->SetWireBytes(base::OwnedVector<const uint8_t>());
......
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