[wasm] Fix jump table for long jumps on arm
Direct jumps only work for offset up to 64 MB on arm. For longer jumps, use indirect branches (load target from constant pool into the pc register). R=mstarzinger@chromium.org CC=pierre.langlois@arm.com Bug: v8:7758 Change-Id: I1cf66b7d1bfb62cfcd6b1619c02816909a1f651e Reviewed-on: https://chromium-review.googlesource.com/1105996 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#53847}
This commit is contained in:
parent
928e28cddd
commit
d5177a02c9
@ -85,22 +85,30 @@ void JumpTableAssembler::NopBytes(int bytes) {
|
||||
void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
|
||||
Address lazy_compile_target) {
|
||||
// Load function index to r4.
|
||||
// This generates <= 3 instructions: ldr, const pool start, constant
|
||||
// This generates [movw, movt] on ARMv7 and later, [ldr, constant pool marker,
|
||||
// constant] on ARMv6.
|
||||
Move32BitImmediate(r4, Operand(func_index));
|
||||
// Jump to {lazy_compile_target}.
|
||||
int offset =
|
||||
lazy_compile_target - reinterpret_cast<Address>(pc_) - kPcLoadDelta;
|
||||
DCHECK_EQ(0, offset % kInstrSize);
|
||||
DCHECK(is_int26(offset)); // 26 bit imm
|
||||
b(offset); // 1 instr
|
||||
CheckConstPool(true, false); // force emit of const pool
|
||||
// EmitJumpSlot emits either [b], [movw, movt, mov] (ARMv7+), or [ldr,
|
||||
// constant].
|
||||
// In total, this is <=5 instructions on all architectures.
|
||||
// TODO(arm): Optimize this for code size; lazy compile is not performance
|
||||
// critical, as it's only executed once per function.
|
||||
EmitJumpSlot(lazy_compile_target);
|
||||
}
|
||||
|
||||
void JumpTableAssembler::EmitJumpSlot(Address target) {
|
||||
int offset = target - reinterpret_cast<Address>(pc_) - kPcLoadDelta;
|
||||
DCHECK_EQ(0, offset % kInstrSize);
|
||||
DCHECK(is_int26(offset)); // 26 bit imm
|
||||
b(offset);
|
||||
// If the offset is within 64 MB, emit a direct jump. Otherwise jump
|
||||
// indirectly.
|
||||
if (is_int26(offset)) {
|
||||
b(offset); // 1 instr
|
||||
} else {
|
||||
// {Move32BitImmediate} emits either [movw, movt, mov] or [ldr, constant].
|
||||
Move32BitImmediate(pc, Operand(target));
|
||||
}
|
||||
|
||||
CheckConstPool(true, false); // force emit of const pool
|
||||
}
|
||||
|
||||
void JumpTableAssembler::NopBytes(int bytes) {
|
||||
|
@ -40,7 +40,7 @@ class JumpTableAssembler : public TurboAssembler {
|
||||
#elif V8_TARGET_ARCH_IA32
|
||||
static constexpr int kJumpTableSlotSize = 10;
|
||||
#elif V8_TARGET_ARCH_ARM
|
||||
static constexpr int kJumpTableSlotSize = 4 * kInstrSize;
|
||||
static constexpr int kJumpTableSlotSize = 5 * kInstrSize;
|
||||
#elif V8_TARGET_ARCH_ARM64
|
||||
static constexpr int kJumpTableSlotSize = 3 * kInstructionSize;
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user