Commit d5177a02 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[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: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53847}
parent 928e28cd
......@@ -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
......
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