[wasm] Optimize EvaluateInitExpression

This should mitigate some of the regressions introduced in
https://chromium-review.googlesource.com/c/v8/v8/+/2972910.
Changes:
- Use a single Zone for all init. expressions in InstanceBuilder.
- Specialize DecodeFunctionBody() for init. expressions.

Bug: v8:11895, chromium:1226551
Change-Id: Ie39f981efeaa89e57f8ccb68903c6e7cc1cb7f09
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3009465
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75597}
This commit is contained in:
Manos Koukoutos 2021-07-07 09:19:44 +00:00 committed by V8 LUCI CQ
parent 71cb8b331c
commit 6c68cd14e6
2 changed files with 21 additions and 13 deletions

View File

@ -2271,12 +2271,20 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
DCHECK(control_.empty());
control_.emplace_back(kControlBlock, 0, 0, this->pc_, kReachable);
Control* c = &control_.back();
InitMerge(&c->start_merge, 0, [](uint32_t) -> Value { UNREACHABLE(); });
InitMerge(&c->end_merge,
static_cast<uint32_t>(this->sig_->return_count()),
[&](uint32_t i) {
return Value{this->pc_, this->sig_->GetReturn(i)};
});
if (decoding_mode == kFunctionBody) {
InitMerge(&c->start_merge, 0, [](uint32_t) -> Value { UNREACHABLE(); });
InitMerge(&c->end_merge,
static_cast<uint32_t>(this->sig_->return_count()),
[&](uint32_t i) {
return Value{this->pc_, this->sig_->GetReturn(i)};
});
} else {
DCHECK_EQ(this->sig_->parameter_count(), 0);
DCHECK_EQ(this->sig_->return_count(), 1);
c->start_merge.arity = 0;
c->end_merge.arity = 1;
c->end_merge.vals.first = Value{this->pc_, this->sig_->GetReturn(0)};
}
CALL_INTERFACE_IF_OK_AND_REACHABLE(StartFunctionBody, c);
}

View File

@ -291,6 +291,7 @@ class InstanceBuilder {
std::vector<Handle<WasmExceptionObject>> exception_wrappers_;
Handle<WasmExportedFunction> start_function_;
std::vector<SanitizedImport> sanitized_imports_;
Zone init_expr_zone_;
// Helper routines to print out errors with imports.
#define ERROR_THROWER_WITH_MESSAGE(TYPE) \
@ -434,7 +435,8 @@ InstanceBuilder::InstanceBuilder(Isolate* isolate,
thrower_(thrower),
module_object_(module_object),
ffi_(ffi),
memory_buffer_(memory_buffer) {
memory_buffer_(memory_buffer),
init_expr_zone_(isolate_->allocator(), "init. expression zone") {
sanitized_imports_.reserve(module_->import_table.size());
}
@ -1538,19 +1540,17 @@ T* InstanceBuilder::GetRawUntaggedGlobalPtr(const WasmGlobal& global) {
WasmValue InstanceBuilder::EvaluateInitExpression(
WireBytesRef init, ValueType expected,
Handle<WasmInstanceObject> instance) {
AccountingAllocator allocator;
Zone zone(&allocator, "consume_init_expr");
base::Vector<const byte> module_bytes =
instance->module_object().native_module()->wire_bytes();
FunctionBody body(FunctionSig::Build(&zone, {expected}, {}), init.offset(),
module_bytes.begin() + init.offset(),
FunctionBody body(FunctionSig::Build(&init_expr_zone_, {expected}, {}),
init.offset(), module_bytes.begin() + init.offset(),
module_bytes.begin() + init.end_offset());
WasmFeatures detected;
// We use kFullValidation so we do not have to create another instance of
// WasmFullDecoder, which would cost us >50Kb binary code size.
WasmFullDecoder<Decoder::kFullValidation, InitExprInterface, kInitExpression>
decoder(&zone, module_, WasmFeatures::All(), &detected, body, module_,
isolate_, instance, tagged_globals_, untagged_globals_);
decoder(&init_expr_zone_, module_, WasmFeatures::All(), &detected, body,
module_, isolate_, instance, tagged_globals_, untagged_globals_);
decoder.DecodeFunctionBody();