[wasm] Avoid re-validation after deserialization
As we do not ship lazy validation, we can expect that most modules are fully validated when they are serialized. We should use that information and not re-validate functions after deserialization. We do so by writing out a single boolean value that encodes whether all functions have been validated. This value is expected to be true in all relevant cases. On deserialization we then mark all functions as validated if the value is set. R=ahaas@chromium.org Bug: v8:13565 Change-Id: I18bdd6b04b607ba4521d36d3ca2fd35b4a6df7dd Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4152489 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/main@{#85244}
This commit is contained in:
parent
8a646573d9
commit
c48cc5bab5
@ -656,6 +656,15 @@ struct V8_EXPORT_PRIVATE WasmModule {
|
||||
}
|
||||
}
|
||||
|
||||
void set_all_functions_validated() const {
|
||||
DCHECK_EQ(kWasmOrigin, origin);
|
||||
DCHECK_NOT_NULL(validated_functions);
|
||||
size_t num_words = (num_declared_functions + 7) / 8;
|
||||
for (size_t i = 0; i < num_words; ++i) {
|
||||
validated_functions[i].store(0xff, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
base::Vector<const WasmFunction> declared_functions() const {
|
||||
return base::VectorOf(functions) + num_imported_functions;
|
||||
}
|
||||
|
@ -187,7 +187,8 @@ uint32_t GetWasmCalleeTag(RelocInfo* rinfo) {
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr size_t kHeaderSize = sizeof(size_t); // total code size
|
||||
constexpr size_t kHeaderSize = sizeof(size_t) + // total code size
|
||||
sizeof(bool); // all functions validated
|
||||
|
||||
constexpr size_t kCodeHeaderSize = sizeof(uint8_t) + // code kind
|
||||
sizeof(int) + // offset of constant pool
|
||||
@ -331,6 +332,20 @@ void NativeModuleSerializer::WriteHeader(Writer* writer,
|
||||
// handler was used or not when serializing.
|
||||
|
||||
writer->Write(total_code_size);
|
||||
|
||||
// We do not ship lazy validation, so in most cases all functions will be
|
||||
// validated. Thus only write out a single bit instead of serializing the
|
||||
// information per function.
|
||||
const bool fully_validated = !v8_flags.wasm_lazy_validation;
|
||||
writer->Write(fully_validated);
|
||||
#ifdef DEBUG
|
||||
if (fully_validated) {
|
||||
const WasmModule* module = native_module_->module();
|
||||
for (auto& function : module->declared_functions()) {
|
||||
DCHECK(module->function_was_validated(function.func_index));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
|
||||
@ -583,6 +598,7 @@ class V8_EXPORT_PRIVATE NativeModuleDeserializer {
|
||||
|
||||
// Updated in {ReadCode}.
|
||||
size_t remaining_code_size_ = 0;
|
||||
bool all_functions_validated_ = false;
|
||||
base::Vector<byte> current_code_space_;
|
||||
NativeModule::JumpTablesRef current_jump_tables_;
|
||||
std::vector<int> lazy_functions_;
|
||||
@ -665,6 +681,10 @@ bool NativeModuleDeserializer::Read(Reader* reader) {
|
||||
uint32_t total_fns = native_module_->num_functions();
|
||||
uint32_t first_wasm_fn = native_module_->num_imported_functions();
|
||||
|
||||
if (all_functions_validated_) {
|
||||
native_module_->module()->set_all_functions_validated();
|
||||
}
|
||||
|
||||
WasmCodeRefScope wasm_code_ref_scope;
|
||||
|
||||
DeserializationQueue reloc_queue;
|
||||
@ -718,6 +738,7 @@ bool NativeModuleDeserializer::Read(Reader* reader) {
|
||||
|
||||
void NativeModuleDeserializer::ReadHeader(Reader* reader) {
|
||||
remaining_code_size_ = reader->Read<size_t>();
|
||||
all_functions_validated_ = reader->Read<bool>();
|
||||
}
|
||||
|
||||
DeserializationUnit NativeModuleDeserializer::ReadCode(int fn_index,
|
||||
|
Loading…
Reference in New Issue
Block a user