Commit af7f20fb authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm] Refactor deserialization

Reorder deserialization steps: instead of processing functions one by
one, run each step individually on all functions (read & allocate, copy
& relocate, publish). This prepares for moving some steps to background
tasks.

R=ahaas@chromium.org
CC=clemensb@chromium.org

Bug: v8:11164
Change-Id: Ic6e1e387b6a60ab16efc91f8e0d45cb2acded2a8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2543929
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71288}
parent 0a95a992
......@@ -1176,7 +1176,7 @@ WasmCode* NativeModule::PublishCodeLocked(std::unique_ptr<WasmCode> code) {
return result;
}
WasmCode* NativeModule::AddDeserializedCode(
std::unique_ptr<WasmCode> NativeModule::AllocateDeserializedCode(
int index, Vector<const byte> instructions, int stack_slots,
int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset,
......@@ -1184,23 +1184,15 @@ WasmCode* NativeModule::AddDeserializedCode(
Vector<const byte> protected_instructions_data,
Vector<const byte> reloc_info, Vector<const byte> source_position_table,
WasmCode::Kind kind, ExecutionTier tier) {
// CodeSpaceWriteScope is provided by the caller.
Vector<uint8_t> dst_code_bytes =
code_allocator_.AllocateForCode(this, instructions.size());
UpdateCodeSize(dst_code_bytes.size(), tier, kNoDebugging);
base::Memcpy(dst_code_bytes.begin(), instructions.begin(),
instructions.size());
std::unique_ptr<WasmCode> code{new WasmCode{
return std::unique_ptr<WasmCode>{new WasmCode{
this, index, dst_code_bytes, stack_slots, tagged_parameter_slots,
safepoint_table_offset, handler_table_offset, constant_pool_offset,
code_comments_offset, unpadded_binary_size, protected_instructions_data,
reloc_info, source_position_table, kind, tier, kNoDebugging}};
// Note: we do not flush the i-cache here, since the code needs to be
// relocated anyway. The caller is responsible for flushing the i-cache later.
return PublishCode(std::move(code));
}
std::vector<WasmCode*> NativeModule::SnapshotCodeTable() const {
......
......@@ -497,7 +497,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
WasmCode* PublishCode(std::unique_ptr<WasmCode>);
std::vector<WasmCode*> PublishCode(Vector<std::unique_ptr<WasmCode>>);
WasmCode* AddDeserializedCode(
std::unique_ptr<WasmCode> AllocateDeserializedCode(
int index, Vector<const byte> instructions, int stack_slots,
int tagged_parameter_slots, int safepoint_table_offset,
int handler_table_offset, int constant_pool_offset,
......
......@@ -468,6 +468,11 @@ bool WasmSerializer::SerializeNativeModule(Vector<byte> buffer) const {
return true;
}
struct DeserializationUnit {
Vector<const byte> src_code_buffer;
std::unique_ptr<WasmCode> code;
};
class V8_EXPORT_PRIVATE NativeModuleDeserializer {
public:
explicit NativeModuleDeserializer(NativeModule*);
......@@ -478,7 +483,9 @@ class V8_EXPORT_PRIVATE NativeModuleDeserializer {
private:
bool ReadHeader(Reader* reader);
void ReadCode(int fn_index, Reader* reader);
DeserializationUnit ReadCodeAndAlloc(int fn_index, Reader* reader);
void CopyAndRelocate(const DeserializationUnit& unit);
void Publish(DeserializationUnit unit);
NativeModule* const native_module_;
bool read_called_;
......@@ -495,8 +502,21 @@ bool NativeModuleDeserializer::Read(Reader* reader) {
uint32_t total_fns = native_module_->num_functions();
uint32_t first_wasm_fn = native_module_->num_imported_functions();
WasmCodeRefScope wasm_code_ref_scope;
std::vector<DeserializationUnit> units;
for (uint32_t i = first_wasm_fn; i < total_fns; ++i) {
ReadCode(i, reader);
DeserializationUnit unit = ReadCodeAndAlloc(i, reader);
if (unit.code) {
units.push_back(std::move(unit));
}
}
{
CODE_SPACE_WRITE_SCOPE
for (DeserializationUnit& unit : units) {
CopyAndRelocate(unit);
}
}
for (DeserializationUnit& unit : units) {
Publish(std::move(unit));
}
return reader->current_size() == 0;
}
......@@ -508,13 +528,14 @@ bool NativeModuleDeserializer::ReadHeader(Reader* reader) {
imports == native_module_->num_imported_functions();
}
void NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
DeserializationUnit NativeModuleDeserializer::ReadCodeAndAlloc(int fn_index,
Reader* reader) {
bool has_code = reader->Read<bool>();
if (!has_code) {
DCHECK(FLAG_wasm_lazy_compilation ||
native_module_->enabled_features().has_compilation_hints());
native_module_->UseLazyStub(fn_index);
return;
return {{}, nullptr};
}
int constant_pool_offset = reader->Read<int>();
int safepoint_table_offset = reader->Read<int>();
......@@ -530,18 +551,24 @@ void NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
WasmCode::Kind kind = reader->Read<WasmCode::Kind>();
ExecutionTier tier = reader->Read<ExecutionTier>();
auto code_buffer = reader->ReadVector<byte>(code_size);
DeserializationUnit unit;
unit.src_code_buffer = reader->ReadVector<byte>(code_size);
auto reloc_info = reader->ReadVector<byte>(reloc_size);
auto source_pos = reader->ReadVector<byte>(source_position_size);
auto protected_instructions =
reader->ReadVector<byte>(protected_instructions_size);
CODE_SPACE_WRITE_SCOPE
WasmCode* code = native_module_->AddDeserializedCode(
fn_index, code_buffer, stack_slot_count, tagged_parameter_slots,
unit.code = native_module_->AllocateDeserializedCode(
fn_index, unit.src_code_buffer, stack_slot_count, tagged_parameter_slots,
safepoint_table_offset, handler_table_offset, constant_pool_offset,
code_comment_offset, unpadded_binary_size, protected_instructions,
std::move(reloc_info), std::move(source_pos), kind, tier);
reloc_info, source_pos, kind, tier);
return unit;
}
void NativeModuleDeserializer::CopyAndRelocate(
const DeserializationUnit& unit) {
base::Memcpy(unit.code->instructions().begin(), unit.src_code_buffer.begin(),
unit.src_code_buffer.size());
// Relocate the code.
int mask = RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
......@@ -550,9 +577,9 @@ void NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED);
auto jump_tables_ref = native_module_->FindJumpTablesForRegion(
base::AddressRegionOf(code->instructions()));
for (RelocIterator iter(code->instructions(), code->reloc_info(),
code->constant_pool(), mask);
base::AddressRegionOf(unit.code->instructions()));
for (RelocIterator iter(unit.code->instructions(), unit.code->reloc_info(),
unit.code->constant_pool(), mask);
!iter.done(); iter.next()) {
RelocInfo::Mode mode = iter.rinfo()->rmode();
switch (mode) {
......@@ -580,7 +607,7 @@ void NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
case RelocInfo::INTERNAL_REFERENCE:
case RelocInfo::INTERNAL_REFERENCE_ENCODED: {
Address offset = iter.rinfo()->target_internal_reference();
Address target = code->instruction_start() + offset;
Address target = unit.code->instruction_start() + offset;
Assembler::deserialization_set_target_internal_reference_at(
iter.rinfo()->pc(), target, mode);
break;
......@@ -590,12 +617,15 @@ void NativeModuleDeserializer::ReadCode(int fn_index, Reader* reader) {
}
}
code->MaybePrint();
code->Validate();
// Finally, flush the icache for that code.
FlushInstructionCache(code->instructions().begin(),
code->instructions().size());
FlushInstructionCache(unit.code->instructions().begin(),
unit.code->instructions().size());
}
void NativeModuleDeserializer::Publish(DeserializationUnit unit) {
WasmCode* published_code = native_module_->PublishCode(std::move(unit).code);
published_code->MaybePrint();
published_code->Validate();
}
bool IsSupportedVersion(Vector<const byte> header) {
......
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