[wasm] Remove friendship between NativeModule and (de)serializer

This CL removes the friendship between {NativeModule} and
{NativeModuleSerializer}/{NativeModuleDeserializer}.
Instead, it adds a new public method ({AddDeserializedCode}) which is
being called from the deserializer.

Drive-by: Unify the argument order to {AddCode}, {AddOwnedCode} and
{WasmCode}.

R=mstarzinger@chromium.org

Bug: chromium:856938
Change-Id: I88943c90c45650e21ae6bc17395a17f86319c046
Reviewed-on: https://chromium-review.googlesource.com/1117075
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54084}
This commit is contained in:
Clemens Hammacher 2018-06-28 11:45:22 +02:00 committed by Commit Bot
parent 38ea669732
commit 37ca8c3d2d
7 changed files with 124 additions and 96 deletions

View File

@ -1048,8 +1048,9 @@ PipelineWasmCompilationJob::Status PipelineWasmCompilationJob::FinalizeJobImpl(
code_generator->tasm()->GetCode(isolate, &code_desc);
wasm::WasmCode* code = native_module_->AddCode(
code_desc, code_generator->frame()->GetTotalFrameSlotCount(),
data_.wasm_function_index(), code_generator->GetSafepointTableOffset(),
data_.wasm_function_index(), code_desc,
code_generator->frame()->GetTotalFrameSlotCount(),
code_generator->GetSafepointTableOffset(),
code_generator->GetHandlerTableOffset(),
data_.wasm_compilation_data()->GetProtectedInstructions(),
code_generator->GetSourcePositionTable(), wasm::WasmCode::kTurbofan);

View File

@ -1880,7 +1880,7 @@ wasm::WasmCode* LiftoffCompilationUnit::FinishCompilation(
OwnedVector<trap_handler::ProtectedInstructionData>::Of(
protected_instructions_);
wasm::WasmCode* code = wasm_unit_->native_module_->AddCode(
desc, asm_.GetTotalFrameSlotCount(), wasm_unit_->func_index_,
wasm_unit_->func_index_, desc, asm_.GetTotalFrameSlotCount(),
safepoint_table_offset_, 0, std::move(protected_instructions_copy),
std::move(source_positions), wasm::WasmCode::kLiftoff);

View File

@ -146,30 +146,28 @@ bool WasmCode::ShouldBeLogged(Isolate* isolate) {
void WasmCode::LogCode(Isolate* isolate) const {
DCHECK(ShouldBeLogged(isolate));
if (index_.IsJust()) {
uint32_t index = this->index();
ModuleWireBytes wire_bytes(native_module()->wire_bytes());
// TODO(herhut): Allow to log code without on-heap round-trip of the name.
ModuleEnv* module_env = GetModuleEnv(native_module()->compilation_state());
WireBytesRef name_ref = module_env->module->LookupName(wire_bytes, index);
WasmName name_vec = wire_bytes.GetName(name_ref);
MaybeHandle<String> maybe_name = isolate->factory()->NewStringFromUtf8(
Vector<const char>::cast(name_vec));
Handle<String> name;
if (!maybe_name.ToHandle(&name)) {
name = isolate->factory()->NewStringFromAsciiChecked("<name too long>");
}
int name_length;
auto cname =
name->ToCString(AllowNullsFlag::DISALLOW_NULLS,
RobustnessFlag::ROBUST_STRING_TRAVERSAL, &name_length);
PROFILE(isolate,
CodeCreateEvent(CodeEventListener::FUNCTION_TAG, this,
{cname.get(), static_cast<size_t>(name_length)}));
if (!source_positions().is_empty()) {
LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(instruction_start(),
source_positions()));
}
if (IsAnonymous()) return;
ModuleWireBytes wire_bytes(native_module()->wire_bytes());
// TODO(herhut): Allow to log code without on-heap round-trip of the name.
ModuleEnv* module_env = GetModuleEnv(native_module()->compilation_state());
WireBytesRef name_ref = module_env->module->LookupName(wire_bytes, index());
WasmName name_vec = wire_bytes.GetName(name_ref);
MaybeHandle<String> maybe_name =
isolate->factory()->NewStringFromUtf8(Vector<const char>::cast(name_vec));
Handle<String> name;
if (!maybe_name.ToHandle(&name)) {
name = isolate->factory()->NewStringFromAsciiChecked("<name too long>");
}
int name_length;
auto cname =
name->ToCString(AllowNullsFlag::DISALLOW_NULLS,
RobustnessFlag::ROBUST_STRING_TRAVERSAL, &name_length);
PROFILE(isolate,
CodeCreateEvent(CodeEventListener::FUNCTION_TAG, this,
{cname.get(), static_cast<size_t>(name_length)}));
if (!source_positions().is_empty()) {
LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(instruction_start(),
source_positions()));
}
}
@ -229,7 +227,7 @@ void WasmCode::Print(const char* name) const {
void WasmCode::Disassemble(const char* name, std::ostream& os,
Address current_pc) const {
if (name) os << "name: " << name << "\n";
if (index_.IsJust()) os << "index: " << index_.FromJust() << "\n";
if (!IsAnonymous()) os << "index: " << index() << "\n";
os << "kind: " << GetWasmCodeKindAsString(kind_) << "\n";
os << "compiler: " << (is_liftoff() ? "Liftoff" : "TurboFan") << "\n";
size_t body_size = instructions().size();
@ -350,27 +348,29 @@ void NativeModule::LogWasmCodes(Isolate* isolate) {
}
WasmCode* NativeModule::AddOwnedCode(
Vector<const byte> orig_instructions, OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_pos, Maybe<uint32_t> index,
WasmCode::Kind kind, size_t constant_pool_offset, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
Maybe<uint32_t> index, Vector<const byte> instructions,
uint32_t stack_slots, size_t safepoint_table_offset,
size_t handler_table_offset, size_t constant_pool_offset,
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
WasmCode::Tier tier, WasmCode::FlushICache flush_icache) {
// both allocation and insertion in owned_code_ happen in the same critical
// section, thus ensuring owned_code_'s elements are rarely if ever moved.
base::LockGuard<base::Mutex> lock(&allocation_mutex_);
Address executable_buffer = AllocateForCode(orig_instructions.size());
Address executable_buffer = AllocateForCode(instructions.size());
if (executable_buffer == kNullAddress) {
V8::FatalProcessOutOfMemory(nullptr, "NativeModule::AddOwnedCode");
UNREACHABLE();
}
memcpy(reinterpret_cast<void*>(executable_buffer), orig_instructions.start(),
orig_instructions.size());
memcpy(reinterpret_cast<void*>(executable_buffer), instructions.start(),
instructions.size());
std::unique_ptr<WasmCode> code(new WasmCode(
{reinterpret_cast<byte*>(executable_buffer), orig_instructions.size()},
std::move(reloc_info), std::move(source_pos), this, index, kind,
constant_pool_offset, stack_slots, safepoint_table_offset,
handler_table_offset, std::move(protected_instructions), tier));
this, index,
{reinterpret_cast<byte*>(executable_buffer), instructions.size()},
stack_slots, safepoint_table_offset, handler_table_offset,
constant_pool_offset, std::move(protected_instructions),
std::move(reloc_info), std::move(source_position_table), kind, tier));
WasmCode* ret = code.get();
// TODO(mtrofin): We allocate in increasing address order, and
@ -448,23 +448,23 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code,
OwnedVector<byte> source_pos =
OwnedVector<byte>::New(source_pos_table->length());
source_pos_table->copy_out(0, source_pos.start(), source_pos_table->length());
Vector<const byte> orig_instructions(
Vector<const byte> instructions(
reinterpret_cast<byte*>(code->InstructionStart()),
static_cast<size_t>(code->InstructionSize()));
int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0;
int safepoint_table_offset =
code->has_safepoint_info() ? code->safepoint_table_offset() : 0;
WasmCode* ret =
AddOwnedCode(orig_instructions, // instructions
std::move(reloc_info), // reloc_info
std::move(source_pos), // source positions
Nothing<uint32_t>(), // index
kind, // kind
code->constant_pool_offset(), // constant_pool_offset
AddOwnedCode(Nothing<uint32_t>(), // index
instructions, // instructions
stack_slots, // stack_slots
safepoint_table_offset, // safepoint_table_offset
code->handler_table_offset(), // handler_table_offset
code->constant_pool_offset(), // constant_pool_offset
{}, // protected_instructions
std::move(reloc_info), // reloc_info
std::move(source_pos), // source positions
kind, // kind
WasmCode::kOther, // kind
WasmCode::kNoFlushICache); // flush_icache
@ -499,19 +499,20 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code,
}
WasmCode* NativeModule::AddCode(
const CodeDesc& desc, uint32_t frame_slots, uint32_t index,
uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
OwnedVector<byte> source_pos_table, WasmCode::Tier tier) {
OwnedVector<const byte> source_pos_table, WasmCode::Tier tier) {
OwnedVector<byte> reloc_info = OwnedVector<byte>::New(desc.reloc_size);
memcpy(reloc_info.start(), desc.buffer + desc.buffer_size - desc.reloc_size,
desc.reloc_size);
WasmCode* ret = AddOwnedCode(
{desc.buffer, static_cast<size_t>(desc.instr_size)},
std::move(reloc_info), std::move(source_pos_table), Just(index),
WasmCode::kFunction, desc.instr_size - desc.constant_pool_size,
frame_slots, safepoint_table_offset, handler_table_offset,
std::move(protected_instructions), tier, WasmCode::kNoFlushICache);
Just(index), {desc.buffer, static_cast<size_t>(desc.instr_size)},
stack_slots, safepoint_table_offset, handler_table_offset,
desc.instr_size - desc.constant_pool_size,
std::move(protected_instructions), std::move(reloc_info),
std::move(source_pos_table), WasmCode::kFunction, tier,
WasmCode::kNoFlushICache);
// Apply the relocation delta by iterating over the RelocInfo.
intptr_t delta = ret->instructions().start() - desc.buffer;
@ -553,22 +554,43 @@ WasmCode* NativeModule::AddCode(
return ret;
}
WasmCode* NativeModule::AddDeserializedCode(
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
size_t constant_pool_offset,
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Tier tier) {
WasmCode* code =
AddOwnedCode(Just(index), instructions, stack_slots,
safepoint_table_offset, handler_table_offset,
constant_pool_offset, std::move(protected_instructions),
std::move(reloc_info), std::move(source_position_table),
WasmCode::kFunction, tier, WasmCode::kNoFlushICache);
set_code(index, code);
PatchJumpTable(index, code->instruction_start(), WasmCode::kFlushICache);
// 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 code;
}
WasmCode* NativeModule::CreateEmptyJumpTable(uint32_t num_wasm_functions) {
// Only call this if we really need a jump table.
DCHECK_LT(0, num_wasm_functions);
OwnedVector<byte> instructions = OwnedVector<byte>::New(
num_wasm_functions * JumpTableAssembler::kJumpTableSlotSize);
memset(instructions.start(), 0, instructions.size());
return AddOwnedCode(instructions.as_vector(), // instructions
{}, // reloc_info
{}, // source_pos
Nothing<uint32_t>(), // index
WasmCode::kJumpTable, // kind
0, // constant_pool_offset
return AddOwnedCode(Nothing<uint32_t>(), // index
instructions.as_vector(), // instructions
0, // stack_slots
0, // safepoint_table_offset
0, // handler_table_offset
0, // constant_pool_offset
{}, // protected_instructions
{}, // reloc_info
{}, // source_pos
WasmCode::kJumpTable, // kind
WasmCode::kOther, // tier
WasmCode::kNoFlushICache); // flush_icache
}

View File

@ -159,17 +159,17 @@ class V8_EXPORT_PRIVATE WasmCode final {
private:
friend class NativeModule;
WasmCode(Vector<byte> instructions, OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_pos, NativeModule* native_module,
Maybe<uint32_t> index, Kind kind, size_t constant_pool_offset,
uint32_t stack_slots, size_t safepoint_table_offset,
size_t handler_table_offset,
WasmCode(NativeModule* native_module, Maybe<uint32_t> index,
Vector<byte> instructions, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
size_t constant_pool_offset,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
Tier tier)
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, Kind kind, Tier tier)
: instructions_(instructions),
reloc_info_(std::move(reloc_info)),
source_position_table_(std::move(source_pos)),
source_position_table_(std::move(source_position_table)),
native_module_(native_module),
index_(index),
kind_(kind),
@ -219,13 +219,22 @@ const char* GetWasmCodeKindAsString(WasmCode::Kind);
class V8_EXPORT_PRIVATE NativeModule final {
public:
WasmCode* AddCode(const CodeDesc& desc, uint32_t frame_count, uint32_t index,
WasmCode* AddCode(uint32_t index, const CodeDesc& desc, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<byte> source_position_table,
OwnedVector<const byte> source_position_table,
WasmCode::Tier tier);
WasmCode* AddDeserializedCode(
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
size_t constant_pool_offset,
OwnedVector<trap_handler::ProtectedInstructionData>
protected_instructions,
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Tier tier);
// A way to copy over JS-allocated code. This is because we compile
// certain wrappers using a different pipeline.
WasmCode* AddCodeCopy(Handle<Code> code, WasmCode::Kind kind, uint32_t index);
@ -233,7 +242,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
// Add an interpreter entry. For the same reason as AddCodeCopy, we
// currently compile these using a different pipeline and we can't get a
// CodeDesc here. When adding interpreter wrappers, we do not insert them in
// the code_table, however, we let them self-identify as the {index} function
// the code_table, however, we let them self-identify as the {index} function.
WasmCode* AddInterpreterEntry(Handle<Code> code, uint32_t index);
// When starting lazy compilation, provide the WasmLazyCompile builtin by
@ -319,8 +328,6 @@ class V8_EXPORT_PRIVATE NativeModule final {
private:
friend class WasmCode;
friend class WasmCodeManager;
friend class NativeModuleSerializer;
friend class NativeModuleDeserializer;
friend class NativeModuleModificationScope;
NativeModule(Isolate* isolate, uint32_t num_functions,
@ -335,15 +342,14 @@ class V8_EXPORT_PRIVATE NativeModule final {
// module is owned by that module. Various callers get to decide on how the
// code is obtained (CodeDesc vs, as a point in time, Code*), the kind,
// whether it has an index or is anonymous, etc.
WasmCode* AddOwnedCode(Vector<const byte> orig_instructions,
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_pos,
Maybe<uint32_t> index, WasmCode::Kind kind,
size_t constant_pool_offset, uint32_t stack_slots,
size_t safepoint_table_offset,
WasmCode* AddOwnedCode(Maybe<uint32_t> index, Vector<const byte> instructions,
uint32_t stack_slots, size_t safepoint_table_offset,
size_t handler_table_offset,
size_t constant_pool_offset,
OwnedVector<trap_handler::ProtectedInstructionData>,
WasmCode::Tier, WasmCode::FlushICache);
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table,
WasmCode::Kind, WasmCode::Tier, WasmCode::FlushICache);
WasmCode* CreateEmptyJumpTable(uint32_t num_wasm_functions);

View File

@ -453,21 +453,19 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
OwnedVector<trap_handler::ProtectedInstructionData>::New(
protected_instructions_size);
reader->ReadVector(Vector<byte>::cast(protected_instructions.as_vector()));
WasmCode* ret = native_module_->AddOwnedCode(
code_buffer, std::move(reloc_info), std::move(source_pos), Just(fn_index),
WasmCode::kFunction, constant_pool_offset, stack_slot_count,
safepoint_table_offset, handler_table_offset,
std::move(protected_instructions), tier, WasmCode::kNoFlushICache);
native_module_->set_code(fn_index, ret);
native_module_->PatchJumpTable(fn_index, ret->instruction_start(),
WasmCode::kFlushICache);
WasmCode* code = native_module_->AddDeserializedCode(
fn_index, code_buffer, stack_slot_count, safepoint_table_offset,
handler_table_offset, constant_pool_offset,
std::move(protected_instructions), std::move(reloc_info),
std::move(source_pos), tier);
// Relocate the code.
int mask = RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE);
for (RelocIterator iter(ret->instructions(), ret->reloc_info(),
ret->constant_pool(), mask);
for (RelocIterator iter(code->instructions(), code->reloc_info(),
code->constant_pool(), mask);
!iter.done(); iter.next()) {
RelocInfo::Mode mode = iter.rinfo()->rmode();
switch (mode) {
@ -499,12 +497,13 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
}
}
// Flush the i-cache here instead of in AddOwnedCode, to include the changes
// made while iterating over the RelocInfo above.
Assembler::FlushICache(ret->instructions().start(),
ret->instructions().size());
if (FLAG_print_code || FLAG_print_wasm_code) ret->Print();
ret->Validate();
if (FLAG_print_code || FLAG_print_wasm_code) code->Print();
code->Validate();
// Finally, flush the icache for that code.
Assembler::FlushICache(code->instructions().start(),
code->instructions().size());
return true;
}

View File

@ -3438,7 +3438,7 @@ TEST(Liftoff_tier_up) {
memcpy(buffer.get(), sub_code->instructions().start(), sub_size);
desc.buffer = buffer.get();
desc.instr_size = static_cast<int>(sub_size);
native_module->AddCode(desc, 0, add.function_index(), 0, 0, {},
native_module->AddCode(add.function_index(), desc, 0, 0, 0, {},
OwnedVector<byte>(), WasmCode::kOther);
// Second run should now execute {sub}.

View File

@ -176,7 +176,7 @@ class WasmCodeManagerTest : public TestWithContext,
std::unique_ptr<byte[]> exec_buff(new byte[size]);
desc.buffer = exec_buff.get();
desc.instr_size = static_cast<int>(size);
return native_module->AddCode(desc, 0, index, 0, 0, {}, OwnedVector<byte>(),
return native_module->AddCode(index, desc, 0, 0, 0, {}, OwnedVector<byte>(),
WasmCode::kOther);
}