Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8285699: riscv: Provide information when hitting a HaltNode #21

Merged
merged 1 commit into from
Mar 22, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp
Original file line number Diff line number Diff line change
@@ -387,8 +387,51 @@ class Assembler : public AbstractAssembler {
emit_int32((jint)insn);
}

void _halt() {
emit_int32(0);
enum csr {
cycle = 0xc00,
time,
instret,
hpmcounter3,
hpmcounter4,
hpmcounter5,
hpmcounter6,
hpmcounter7,
hpmcounter8,
hpmcounter9,
hpmcounter10,
hpmcounter11,
hpmcounter12,
hpmcounter13,
hpmcounter14,
hpmcounter15,
hpmcounter16,
hpmcounter17,
hpmcounter18,
hpmcounter19,
hpmcounter20,
hpmcounter21,
hpmcounter22,
hpmcounter23,
hpmcounter24,
hpmcounter25,
hpmcounter26,
hpmcounter27,
hpmcounter28,
hpmcounter29,
hpmcounter30,
hpmcounter31 = 0xc1f
};

// Emit an illegal instruction that's known to trap, with 32 read-only CSR
// to choose as the input operand.
// According to the RISC-V Assembly Programmer's Manual, a de facto implementation
// of this instruction is the UNIMP pseduo-instruction, 'CSRRW x0, cycle, x0',
// attempting to write zero to a read-only CSR 'cycle' (0xC00).
// RISC-V ISAs provide a set of up to 32 read-only CSR registers 0xC00-0xC1F,
// and an attempt to write into any read-only CSR (whether it exists or not)
// will generate an illegal instruction exception.
void illegal_instruction(csr csr_reg) {
csrrw(x0, (unsigned)csr_reg, x0);
}

// Register Instruction
@@ -2852,20 +2895,6 @@ enum Nf {

#undef INSN

#define INSN(NAME) \
void NAME() { \
/* The illegal instruction in RVC is presented by a 16-bit 0. */ \
if (do_compress()) { \
emit_int16(0); \
return; \
} \
_halt(); \
}

INSN(halt);

#undef INSN

// --------------------------
// Immediate Instructions
// --------------------------
2 changes: 2 additions & 0 deletions src/hotspot/cpu/riscv/frame_riscv.hpp
Original file line number Diff line number Diff line change
@@ -106,10 +106,12 @@
public:
enum {
pc_return_offset = 0,

// All frames
link_offset = -2,
return_addr_offset = -1,
sender_sp_offset = 0,

// Interpreter frames
interpreter_frame_oop_temp_offset = 1, // for native calls only

34 changes: 6 additions & 28 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
Original file line number Diff line number Diff line change
@@ -381,7 +381,7 @@ void MacroAssembler::verify_oop(Register reg, const char* s) {

mv(c_rarg0, reg); // c_rarg0 : x10
// The length of the instruction sequence emitted should be independent
// of the values of the local char buffer address so that the size of mach
// of the value of the local char buffer address so that the size of mach
// nodes for scratch emit and normal emit matches.
mv(t0, (address)b);

@@ -420,7 +420,7 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
}

// The length of the instruction sequence emitted should be independent
// of the values of the local char buffer address so that the size of mach
// of the value of the local char buffer address so that the size of mach
// nodes for scratch emit and normal emit matches.
mv(t0, (address)b);

@@ -537,17 +537,9 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
}

void MacroAssembler::stop(const char* msg) {
address ip = pc();
pusha();
// The length of the instruction sequence emitted should be independent
// of the values of msg and ip so that the size of mach nodes for scratch
// emit and normal emit matches.
mv(c_rarg0, (address)msg);
mv(c_rarg1, (address)ip);
mv(c_rarg2, sp);
mv(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
jalr(c_rarg3);
ebreak();
BLOCK_COMMENT(msg);
illegal_instruction(Assembler::csr::time);
emit_int64((uintptr_t)msg);
}

void MacroAssembler::unimplemented(const char* what) {
@@ -1120,18 +1112,6 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
pop_reg(RegSet::of(x7) + RegSet::range(x10, x17) + RegSet::range(x28, x31) - exclude, sp);
}

// Push all the integer registers, except zr(x0) & sp(x2) & gp(x3) & tp(x4).
void MacroAssembler::pusha() {
CompressibleRegion cr(this);
push_reg(0xffffffe2, sp);
}

// Pop all the integer registers, except zr(x0) & sp(x2) & gp(x3) & tp(x4).
void MacroAssembler::popa() {
CompressibleRegion cr(this);
pop_reg(0xffffffe2, sp);
}

void MacroAssembler::push_CPU_state(bool save_vectors, int vector_size_in_bytes) {
CompressibleRegion cr(this);
// integer registers, except zr(x0) & ra(x1) & sp(x2) & gp(x3) & tp(x4)
@@ -3157,9 +3137,7 @@ address MacroAssembler::emit_trampoline_stub(int insts_call_instruction_offset,
// with the call instruction at insts_call_instruction_offset in the
// instructions code-section.

// make sure 4 byte aligned here, so that the destination address would be
// 8 byte aligned after 3 intructions
// when we reach here we may get a 2-byte alignment so need to align it
// Make sure the address of destination 8-byte aligned after 3 instructions.
align(wordSize, NativeCallTrampolineStub::data_offset);

relocate(trampoline_stub_Relocation::spec(code()->insts()->start() +
2 changes: 0 additions & 2 deletions src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
Original file line number Diff line number Diff line change
@@ -499,8 +499,6 @@ class MacroAssembler: public Assembler {
pop_call_clobbered_registers_except(RegSet());
}

void pusha();
void popa();
void push_CPU_state(bool save_vectors = false, int vector_size_in_bytes = 0);
void pop_CPU_state(bool restore_vectors = false, int vector_size_in_bytes = 0);

2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/nativeInst_riscv.cpp
Original file line number Diff line number Diff line change
@@ -347,7 +347,7 @@ void NativeIllegalInstruction::insert(address code_pos) {
}

bool NativeInstruction::is_stop() {
return uint_at(0) == 0xffffffff; // an illegal instruction
return uint_at(0) == 0xc0101073; // an illegal instruction, 'csrrw x0, time, x0'
}

//-------------------------------------------------------------------
3 changes: 1 addition & 2 deletions src/hotspot/cpu/riscv/riscv.ad
Original file line number Diff line number Diff line change
@@ -10537,9 +10537,8 @@ instruct ShouldNotReachHere() %{
format %{ "#@ShouldNotReachHere" %}

ins_encode %{
Assembler::CompressibleRegion cr(&_masm);
if (is_reachable()) {
__ halt();
__ stop(_halt_reason);
}
%}

2 changes: 1 addition & 1 deletion src/hotspot/cpu/riscv/stubGenerator_riscv.cpp
Original file line number Diff line number Diff line change
@@ -642,7 +642,7 @@ class StubGenerator: public StubCodeGenerator {
__ bind(error);
__ pop_reg(0x3000, sp); // pop c_rarg2 and c_rarg3

__ pusha();
__ push_reg(RegSet::range(x0, x31), sp);
// debug(char* msg, int64_t pc, int64_t regs[])
__ mv(c_rarg0, t0); // pass address of error message
__ mv(c_rarg1, ra); // pass return address
4 changes: 2 additions & 2 deletions src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp
Original file line number Diff line number Diff line change
@@ -1203,11 +1203,11 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ addi(t1, zr, (u1)StackOverflow::stack_guard_yellow_reserved_disabled);
__ bne(t0, t1, no_reguard);

__ pusha(); // only save smashed registers
__ push_call_clobbered_registers();
__ mv(c_rarg0, xthread);
__ mv(t1, CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
__ jalr(t1);
__ popa(); // only restore smashed registers
__ pop_call_clobbered_registers();
__ bind(no_reguard);
}

2 changes: 1 addition & 1 deletion src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
Original file line number Diff line number Diff line change
@@ -354,7 +354,7 @@ void os::print_context(outputStream *st, const void *context) {
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Posix::ucontext_get_pc(uc);
print_instructions(st, pc, sizeof(char));
print_instructions(st, pc, UseRVC ? sizeof(char) : 4/*non-compressed native instruction size*/);
st->cr();
}