Commit 9fd418b9 authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Exit loop once wasm code in JS_TO_WASM is found

This is a minor performance optimization. Instead of iterating the
relocation information till the end, we exit the loop once we found the
call to wasm code.

R=titzer@chromium.org, ahaas@chromium.org

Review-Url: https://codereview.chromium.org/2717973003
Cr-Commit-Position: refs/heads/master@{#43534}
parent c5c570f0
......@@ -56,6 +56,14 @@ class PatchDirectCallsHelper {
const byte* func_bytes;
};
bool IsAtWasmDirectCallTarget(RelocIterator& it) {
DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode()));
Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
return code->kind() == Code::WASM_FUNCTION ||
code->kind() == Code::WASM_TO_JS_FUNCTION ||
code->builtin_index() == Builtins::kIllegal;
}
} // namespace
CodeSpecialization::CodeSpecialization(Isolate* isolate, Zone* zone)
......@@ -131,26 +139,20 @@ bool CodeSpecialization::ApplyToWholeInstance(
Code* export_wrapper = Code::cast(code_table->get(func_index));
DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind());
// There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION.
int num_wasm_calls = 0;
for (RelocIterator it(export_wrapper,
RelocInfo::ModeMask(RelocInfo::CODE_TARGET));
!it.done(); it.next()) {
DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode()));
Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
; it.next()) {
DCHECK(!it.done());
// Ignore calls to other builtins like ToNumber.
if (code->kind() != Code::WASM_FUNCTION &&
code->kind() != Code::WASM_TO_JS_FUNCTION &&
code->builtin_index() != Builtins::kIllegal)
continue;
++num_wasm_calls;
if (!IsAtWasmDirectCallTarget(it)) continue;
Code* new_code = Code::cast(code_table->get(exp.index));
DCHECK(new_code->kind() == Code::WASM_FUNCTION ||
new_code->kind() == Code::WASM_TO_JS_FUNCTION);
it.rinfo()->set_target_address(new_code->instruction_start(),
UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
changed = true;
break;
}
DCHECK_EQ(1, num_wasm_calls);
changed = true;
func_index++;
}
DCHECK_EQ(code_table->length(), func_index);
......@@ -201,13 +203,8 @@ bool CodeSpecialization::ApplyToWasmCode(Code* code,
break;
case RelocInfo::CODE_TARGET: {
DCHECK(reloc_direct_calls);
Code* old_code =
Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
// Skip everything which is not a wasm call (stack checks, traps, ...).
if (old_code->kind() != Code::WASM_FUNCTION &&
old_code->kind() != Code::WASM_TO_JS_FUNCTION &&
old_code->builtin_index() != Builtins::kIllegal)
continue;
if (!IsAtWasmDirectCallTarget(it)) continue;
// Iterate simultaneously over the relocation information and the source
// position table. For each call in the reloc info, move the source
// position iterator forward to that position to find the byte offset of
......
......@@ -860,24 +860,28 @@ static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate,
return nullptr;
}
static Handle<Code> UnwrapImportWrapper(Handle<Object> target) {
Handle<JSFunction> func = Handle<JSFunction>::cast(target);
static Handle<Code> UnwrapImportWrapper(Handle<Object> import_wrapper) {
Handle<JSFunction> func = Handle<JSFunction>::cast(import_wrapper);
Handle<Code> export_wrapper_code = handle(func->code());
int found = 0;
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
Handle<Code> code;
for (RelocIterator it(*export_wrapper_code, mask); !it.done(); it.next()) {
RelocInfo* rinfo = it.rinfo();
Address target_address = rinfo->target_address();
Code* target = Code::GetCodeFromTargetAddress(target_address);
if (target->kind() == Code::WASM_FUNCTION ||
target->kind() == Code::WASM_TO_JS_FUNCTION) {
++found;
code = handle(target);
}
}
DCHECK_EQ(1, found);
return code;
for (RelocIterator it(*export_wrapper_code, mask);; it.next()) {
DCHECK(!it.done());
Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
if (target->kind() != Code::WASM_FUNCTION &&
target->kind() != Code::WASM_TO_JS_FUNCTION)
continue;
// There should only be this one call to wasm code.
#ifdef DEBUG
for (it.next(); !it.done(); it.next()) {
Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
DCHECK(code->kind() != Code::WASM_FUNCTION &&
code->kind() != Code::WASM_TO_JS_FUNCTION);
}
#endif
return handle(target);
}
UNREACHABLE();
return Handle<Code>::null();
}
static Handle<Code> CompileImportWrapper(Isolate* isolate, int index,
......
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