8298075: RISC-V: Implement post-call NOPs
Reviewed-by: fyang, luhenry
This commit is contained in:
parent
3aa4070d4c
commit
74f346b33f
@ -43,7 +43,9 @@ void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
|
||||
__ bind(_entry);
|
||||
InternalAddress safepoint_pc(__ pc() - __ offset() + safepoint_offset());
|
||||
__ relocate(safepoint_pc.rspec(), [&] {
|
||||
__ la(t0, safepoint_pc.target());
|
||||
int32_t offset;
|
||||
__ la_patchable(t0, safepoint_pc.target(), offset);
|
||||
__ addi(t0, t0, offset);
|
||||
});
|
||||
__ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset()));
|
||||
|
||||
|
@ -40,7 +40,9 @@ void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointP
|
||||
__ bind(entry->_stub_label);
|
||||
InternalAddress safepoint_pc(__ pc() - __ offset() + entry->_safepoint_offset);
|
||||
__ relocate(safepoint_pc.rspec(), [&] {
|
||||
__ la(t0, safepoint_pc.target());
|
||||
int32_t offset;
|
||||
__ la_patchable(t0, safepoint_pc.target(), offset);
|
||||
__ addi(t0, t0, offset);
|
||||
});
|
||||
__ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset()));
|
||||
__ far_jump(callback_addr);
|
||||
|
@ -210,6 +210,7 @@ void MacroAssembler::post_call_nop() {
|
||||
}
|
||||
relocate(post_call_nop_Relocation::spec(), [&] {
|
||||
nop();
|
||||
li32(zr, 0);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1383,7 +1384,7 @@ static int patch_imm_in_li64(address branch, address target) {
|
||||
return LI64_INSTRUCTIONS_NUM * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
static int patch_imm_in_li32(address branch, int32_t target) {
|
||||
int MacroAssembler::patch_imm_in_li32(address branch, int32_t target) {
|
||||
const int LI32_INSTRUCTIONS_NUM = 2; // lui + addiw
|
||||
int64_t upper = (intptr_t)target;
|
||||
int32_t lower = (((int32_t)target) << 20) >> 20;
|
||||
@ -1447,7 +1448,7 @@ static address get_target_of_li64(address insn_addr) {
|
||||
return (address)target_address;
|
||||
}
|
||||
|
||||
static address get_target_of_li32(address insn_addr) {
|
||||
address MacroAssembler::get_target_of_li32(address insn_addr) {
|
||||
assert_cond(insn_addr != NULL);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 12; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addiw.
|
||||
|
@ -387,6 +387,9 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
static int patch_oop(address insn_addr, address o);
|
||||
|
||||
static address get_target_of_li32(address insn_addr);
|
||||
static int patch_imm_in_li32(address branch, int32_t target);
|
||||
|
||||
// Return whether code is emitted to a scratch blob.
|
||||
virtual bool in_scratch_emit_size() {
|
||||
return false;
|
||||
|
@ -444,8 +444,16 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
int NativePostCallNop::displacement() const {
|
||||
// Discard the high 32 bits
|
||||
return (int)(intptr_t)MacroAssembler::get_target_of_li32(addr_at(4));
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
// unsupported for now
|
||||
assert(diff != 0, "must be");
|
||||
assert(is_lui_to_zr_at(addr_at(4)) && is_addiw_to_zr_at(addr_at(8)), "must be");
|
||||
|
||||
MacroAssembler::patch_imm_in_li32(addr_at(4), diff);
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
|
@ -78,7 +78,9 @@ class NativeInstruction {
|
||||
static bool is_jump_at(address instr) { assert_cond(instr != NULL); return is_branch_at(instr) || is_jal_at(instr) || is_jalr_at(instr); }
|
||||
static bool is_addi_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0010011 && extract_funct3(instr) == 0b000; }
|
||||
static bool is_addiw_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0011011 && extract_funct3(instr) == 0b000; }
|
||||
static bool is_addiw_to_zr_at(address instr) { assert_cond(instr != NULL); return is_addiw_at(instr) && extract_rd(instr) == zr; }
|
||||
static bool is_lui_at(address instr) { assert_cond(instr != NULL); return extract_opcode(instr) == 0b0110111; }
|
||||
static bool is_lui_to_zr_at(address instr) { assert_cond(instr != NULL); return is_lui_at(instr) && extract_rd(instr) == zr; }
|
||||
static bool is_slli_shift_at(address instr, uint32_t shift) {
|
||||
assert_cond(instr != NULL);
|
||||
return (extract_opcode(instr) == 0b0010011 && // opcode field
|
||||
@ -554,10 +556,22 @@ inline NativeMembar *NativeMembar_at(address addr) {
|
||||
return (NativeMembar*)addr;
|
||||
}
|
||||
|
||||
// A NativePostCallNop takes the form of three instructions:
|
||||
// nop; lui zr, hi20; addiw zr, lo12
|
||||
//
|
||||
// The nop is patchable for a deoptimization trap. The lui and addiw
|
||||
// instructions execute as nops but have a 20/12-bit payload in which we
|
||||
// can store an offset from the initial nop to the nmethod.
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
bool check() const {
|
||||
// Check for two instructions: nop; lui zr, hi20
|
||||
// These instructions only ever appear together in a post-call
|
||||
// NOP, so it's unnecessary to check that the third instruction is
|
||||
// an addiw as well.
|
||||
return is_nop() && is_lui_to_zr_at(addr_at(4));
|
||||
}
|
||||
int displacement() const;
|
||||
void patch(jint diff);
|
||||
void make_deopt();
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user