[wasm] Make NativeModule::LinkAll to use CodeSpecialization

- Update CodeSpecialization::RelocateDirectCalls and ApplyToWholeInstance to take a native module instead
- Use CodeSpecialization on NativeModule::LinkAll

Bug: v8:7539
Change-Id: I71ceb3114e8a0fca71dfa32f0721ef5fb4485eb4
Reviewed-on: https://chromium-review.googlesource.com/959592
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51937}
This commit is contained in:
Junliang Yan 2018-03-14 12:54:35 -04:00 committed by Commit Bot
parent a07b245e01
commit 25363b8f2e
6 changed files with 35 additions and 55 deletions

View File

@ -631,7 +631,7 @@ const wasm::WasmCode* LazyCompilationOrchestrator::CompileFunction(
// Now specialize the generated code for this instance.
Zone specialization_zone(isolate->allocator(), ZONE_NAME);
CodeSpecialization code_specialization(isolate, &specialization_zone);
code_specialization.RelocateDirectCalls(instance);
code_specialization.RelocateDirectCalls(compiled_module->GetNativeModule());
code_specialization.ApplyToWasmCode(wasm_code, SKIP_ICACHE_FLUSH);
int64_t func_size =
static_cast<int64_t>(func->code.end_offset() - func->code.offset());
@ -1794,8 +1794,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
}
// Patch all code with the relocations registered in code_specialization.
code_specialization.RelocateDirectCalls(instance);
code_specialization.ApplyToWholeInstance(*instance, SKIP_ICACHE_FLUSH);
code_specialization.RelocateDirectCalls(native_module);
code_specialization.ApplyToWholeModule(native_module, SKIP_ICACHE_FLUSH);
FlushICache(native_module);
FlushICache(wrapper_table);

View File

@ -16,6 +16,7 @@
#include "src/globals.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
#include "src/wasm/wasm-code-specialization.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-objects.h"
@ -550,29 +551,11 @@ WasmCode* NativeModule::AddExportedWrapper(Handle<Code> code, uint32_t index) {
}
void NativeModule::LinkAll() {
for (uint32_t index = 0; index < code_table_.size(); ++index) {
Link(index);
}
}
void NativeModule::Link(uint32_t index) {
WasmCode* code = code_table_[index];
// skip imports
if (!code) return;
int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_CALL);
for (RelocIterator it(code->instructions(), code->reloc_info(),
code->constant_pool(), mode_mask);
!it.done(); it.next()) {
uint32_t index = GetWasmCalleeTag(it.rinfo());
const WasmCode* target = GetCode(index);
if (target == nullptr) continue;
Address target_addr = target->instructions().start();
DCHECK_NOT_NULL(target);
it.rinfo()->set_wasm_call_address(target_addr,
ICacheFlushMode::SKIP_ICACHE_FLUSH);
}
Assembler::FlushICache(code->instructions().start(),
code->instructions().size());
Isolate* isolate = compiled_module()->GetIsolate();
Zone specialization_zone(isolate->allocator(), ZONE_NAME);
CodeSpecialization code_specialization(isolate, &specialization_zone);
code_specialization.RelocateDirectCalls(this);
code_specialization.ApplyToWholeModule(this);
}
Address NativeModule::AllocateForCode(size_t size) {

View File

@ -247,7 +247,6 @@ class V8_EXPORT_PRIVATE NativeModule final {
// on the fly, and bypass the instance builder pipeline.
void ResizeCodeTableForTest(size_t);
void LinkAll();
void Link(uint32_t index);
// TODO(mstarzinger): needed until we sort out source positions, which are
// still on the GC-heap.

View File

@ -43,23 +43,23 @@ int AdvanceSourcePositionTableIterator(SourcePositionTableIterator& iterator,
class PatchDirectCallsHelper {
public:
PatchDirectCallsHelper(WasmInstanceObject* instance, const WasmCode* code)
PatchDirectCallsHelper(NativeModule* native_module, const WasmCode* code)
: source_pos_it(ByteArray::cast(
instance->compiled_module()->source_positions()->get(
native_module->compiled_module()->source_positions()->get(
static_cast<int>(code->index())))),
decoder(nullptr, nullptr) {
uint32_t func_index = code->index();
WasmCompiledModule* comp_mod = instance->compiled_module();
WasmCompiledModule* comp_mod = native_module->compiled_module();
func_bytes =
comp_mod->shared()->module_bytes()->GetChars() +
comp_mod->shared()->module()->functions[func_index].code.offset();
}
PatchDirectCallsHelper(WasmInstanceObject* instance, Code* code)
PatchDirectCallsHelper(NativeModule* native_module, Code* code)
: source_pos_it(code->SourcePositionTable()), decoder(nullptr, nullptr) {
FixedArray* deopt_data = code->deoptimization_data();
DCHECK_EQ(2, deopt_data->length());
WasmSharedModuleData* shared = instance->compiled_module()->shared();
WasmSharedModuleData* shared = native_module->compiled_module()->shared();
int func_index = Smi::ToInt(deopt_data->get(1));
func_bytes = shared->module_bytes()->GetChars() +
shared->module()->functions[func_index].code.offset();
@ -82,11 +82,10 @@ void CodeSpecialization::RelocateWasmContextReferences(Address new_context) {
new_wasm_context_address_ = new_context;
}
void CodeSpecialization::RelocateDirectCalls(
Handle<WasmInstanceObject> instance) {
DCHECK(relocate_direct_calls_instance_.is_null());
DCHECK(!instance.is_null());
relocate_direct_calls_instance_ = instance;
void CodeSpecialization::RelocateDirectCalls(NativeModule* native_module) {
DCHECK_NULL(relocate_direct_calls_module_);
DCHECK_NOT_NULL(native_module);
relocate_direct_calls_module_ = native_module;
}
void CodeSpecialization::RelocatePointer(Address old_ptr, Address new_ptr) {
@ -95,11 +94,10 @@ void CodeSpecialization::RelocatePointer(Address old_ptr, Address new_ptr) {
pointers_to_relocate_.insert(std::make_pair(old_ptr, new_ptr));
}
bool CodeSpecialization::ApplyToWholeInstance(
WasmInstanceObject* instance, ICacheFlushMode icache_flush_mode) {
bool CodeSpecialization::ApplyToWholeModule(NativeModule* native_module,
ICacheFlushMode icache_flush_mode) {
DisallowHeapAllocation no_gc;
WasmCompiledModule* compiled_module = instance->compiled_module();
NativeModule* native_module = compiled_module->GetNativeModule();
WasmCompiledModule* compiled_module = native_module->compiled_module();
WasmSharedModuleData* shared = compiled_module->shared();
WasmModule* module = shared->module();
std::vector<WasmFunction>* wasm_functions = &shared->module()->functions;
@ -113,7 +111,9 @@ bool CodeSpecialization::ApplyToWholeInstance(
for (int num_wasm_functions = static_cast<int>(wasm_functions->size());
func_index < num_wasm_functions; ++func_index) {
WasmCode* wasm_function = native_module->GetCode(func_index);
if (wasm_function->kind() != WasmCode::kFunction) {
// TODO(clemensh): Get rid of this nullptr check
if (wasm_function == nullptr ||
wasm_function->kind() != WasmCode::kFunction) {
continue;
}
changed |= ApplyToWasmCode(wasm_function, icache_flush_mode);
@ -126,10 +126,10 @@ bool CodeSpecialization::ApplyToWholeInstance(
reloc_mode |= RelocInfo::ModeMask(RelocInfo::WASM_CONTEXT_REFERENCE);
}
// Patch CODE_TARGET if we shall relocate direct calls. If we patch direct
// calls, the instance registered for that (relocate_direct_calls_instance_)
// calls, the instance registered for that (relocate_direct_calls_module_)
// should match the instance we currently patch (instance).
if (!relocate_direct_calls_instance_.is_null()) {
DCHECK_EQ(instance, *relocate_direct_calls_instance_);
if (relocate_direct_calls_module_ != nullptr) {
DCHECK_EQ(native_module, relocate_direct_calls_module_);
reloc_mode |= RelocInfo::ModeMask(RelocInfo::JS_TO_WASM_CALL);
}
if (!reloc_mode) return changed;
@ -137,8 +137,8 @@ bool CodeSpecialization::ApplyToWholeInstance(
for (auto exp : module->export_table) {
if (exp.kind != kExternalFunction) continue;
Code* export_wrapper =
Code::cast(compiled_module->export_wrappers()->get(wrapper_index));
DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
Code::cast(compiled_module->export_wrappers()->get(wrapper_index++));
if (export_wrapper->kind() != Code::JS_TO_WASM_FUNCTION) continue;
for (RelocIterator it(export_wrapper, reloc_mode); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
switch (mode) {
@ -156,7 +156,6 @@ bool CodeSpecialization::ApplyToWholeInstance(
}
}
changed = true;
++wrapper_index;
}
DCHECK_EQ(module->functions.size(), func_index);
DCHECK_EQ(compiled_module->export_wrappers()->length(), wrapper_index);
@ -168,7 +167,7 @@ bool CodeSpecialization::ApplyToWasmCode(wasm::WasmCode* code,
DisallowHeapAllocation no_gc;
DCHECK_EQ(wasm::WasmCode::kFunction, code->kind());
bool reloc_direct_calls = !relocate_direct_calls_instance_.is_null();
bool reloc_direct_calls = relocate_direct_calls_module_ != nullptr;
bool reloc_pointers = pointers_to_relocate_.size() > 0;
int reloc_mode = 0;
@ -197,7 +196,7 @@ bool CodeSpecialization::ApplyToWasmCode(wasm::WasmCode* code,
// bytes to find the new compiled function.
size_t offset = it.rinfo()->pc() - code->instructions().start();
if (!patch_direct_calls_helper) {
patch_direct_calls_helper.emplace(*relocate_direct_calls_instance_,
patch_direct_calls_helper.emplace(relocate_direct_calls_module_,
code);
}
int byte_pos = AdvanceSourcePositionTableIterator(

View File

@ -31,14 +31,14 @@ class CodeSpecialization {
// Update WasmContext references.
void RelocateWasmContextReferences(Address new_context);
// Update all direct call sites based on the code table in the given instance.
void RelocateDirectCalls(Handle<WasmInstanceObject> instance);
void RelocateDirectCalls(NativeModule* module);
// Relocate an arbitrary object (e.g. function table).
void RelocatePointer(Address old_obj, Address new_obj);
// Apply all relocations and patching to all code in the instance (wasm code
// and exported functions).
bool ApplyToWholeInstance(WasmInstanceObject*,
ICacheFlushMode = FLUSH_ICACHE_IF_NEEDED);
bool ApplyToWholeModule(NativeModule*,
ICacheFlushMode = FLUSH_ICACHE_IF_NEEDED);
// Apply all relocations and patching to one wasm code object.
bool ApplyToWasmCode(wasm::WasmCode*,
ICacheFlushMode = FLUSH_ICACHE_IF_NEEDED);
@ -46,7 +46,7 @@ class CodeSpecialization {
private:
Address new_wasm_context_address_ = 0;
Handle<WasmInstanceObject> relocate_direct_calls_instance_;
NativeModule* relocate_direct_calls_module_ = nullptr;
std::unordered_map<Address, Address> pointers_to_relocate_;
};

View File

@ -492,7 +492,6 @@ bool NativeModuleDeserializer::Read(Vector<const byte> data) {
for (; index_ < native_module_->FunctionCount(); ++index_) {
if (!ReadCode()) return false;
}
native_module_->LinkAll();
return data.size() - unread_.size();
}