Skip to content

Commit 49e24f0

Browse files
author
Andrew Haley
committed
8287567: AArch64: Implement post-call NOPs
Reviewed-by: adinn, rbackman, dlong
1 parent 1fcbaa4 commit 49e24f0

File tree

5 files changed

+46
-4
lines changed

5 files changed

+46
-4
lines changed

src/hotspot/cpu/aarch64/assembler_aarch64.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ class Assembler : public AbstractAssembler {
794794
starti; \
795795
f(opcode, 31, 29), f(0b100101, 28, 23), f(shift/16, 22, 21), \
796796
f(imm, 20, 5); \
797-
rf(Rd, 0); \
797+
zrf(Rd, 0); \
798798
}
799799

800800
INSN(movnw, 0b000);

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@ void MacroAssembler::post_call_nop() {
844844
InstructionMark im(this);
845845
relocate(post_call_nop_Relocation::spec());
846846
nop();
847+
movk(zr, 0);
848+
movk(zr, 0);
847849
}
848850

849851
// these are no-ops overridden by InterpreterMacroAssembler

src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,24 @@ void NativePostCallNop::make_deopt() {
549549
NativeDeoptInstruction::insert(addr_at(0));
550550
}
551551

552+
#ifndef PRODUCT
553+
static bool is_movk_to_zr(uint32_t insn) {
554+
return ((insn & 0xffe0001f) == 0xf280001f);
555+
}
556+
#endif
557+
552558
void NativePostCallNop::patch(jint diff) {
553-
// unsupported for now
559+
#ifndef PRODUCT
560+
assert(diff != 0, "must be");
561+
uint32_t insn1 = uint_at(4);
562+
uint32_t insn2 = uint_at(8);
563+
assert (is_movk_to_zr(insn1) && is_movk_to_zr(insn2), "must be");
564+
#endif
565+
566+
uint32_t lo = diff & 0xffff;
567+
uint32_t hi = (uint32_t)diff >> 16;
568+
Instruction_aarch64::patch(addr_at(4), 20, 5, lo);
569+
Instruction_aarch64::patch(addr_at(8), 20, 5, hi);
554570
}
555571

556572
void NativeDeoptInstruction::verify() {

src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,10 +666,33 @@ inline NativeLdSt* NativeLdSt_at(address addr) {
666666
return (NativeLdSt*)addr;
667667
}
668668

669+
// A NativePostCallNop takes the form of three instructions:
670+
// nop; movk zr, lo; movk zr, hi
671+
//
672+
// The nop is patchable for a deoptimization trap. The two movk
673+
// instructions execute as nops but have a 16-bit payload in which we
674+
// can store an offset from the initial nop to the nmethod.
675+
669676
class NativePostCallNop: public NativeInstruction {
670677
public:
671-
bool check() const { return is_nop(); }
672-
int displacement() const { return 0; }
678+
bool check() const {
679+
uint64_t insns = *(uint64_t*)addr_at(0);
680+
// Check for two instructions: nop; movk zr, xx
681+
// These instructions only ever appear together in a post-call
682+
// NOP, so it's unnecessary to check that the third instruction is
683+
// a MOVK as well.
684+
return (insns & 0xffe0001fffffffff) == 0xf280001fd503201f;
685+
}
686+
687+
jint displacement() const {
688+
uint64_t movk_insns = *(uint64_t*)addr_at(4);
689+
uint32_t lo = (movk_insns >> 5) & 0xffff;
690+
uint32_t hi = (movk_insns >> (5 + 32)) & 0xffff;
691+
uint32_t result = (hi << 16) | lo;
692+
693+
return (jint)result;
694+
}
695+
673696
void patch(jint diff);
674697
void make_deopt();
675698
};

src/hotspot/share/code/codeCache.inline.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ inline CodeBlob* CodeCache::find_blob_and_oopmap(void* pc, int& slot) {
4141
int offset = (nop->displacement() & 0xffffff);
4242
cb = (CodeBlob*) ((address) pc - offset);
4343
slot = ((nop->displacement() >> 24) & 0xff);
44+
assert(cb == CodeCache::find_blob(pc), "must be");
4445
} else {
4546
cb = CodeCache::find_blob(pc);
4647
slot = -1;

0 commit comments

Comments
 (0)