mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8286367: riscv: riscv port is broken after JDK-8284161
Co-authored-by: Fei Yang <fyang@openjdk.org> Reviewed-by: coleenp, fyang
This commit is contained in:
parent
4fd79a6ad2
commit
bf0dc4f844
@ -93,8 +93,7 @@ inline void ContinuationHelper::InterpretedFrame::patch_sender_sp(frame& f, intp
|
||||
}
|
||||
|
||||
inline address* ContinuationHelper::Frame::return_pc_address(const frame& f) {
|
||||
Unimplemented();
|
||||
return NULL;
|
||||
return (address*)(f.real_fp() - 1);
|
||||
}
|
||||
|
||||
inline address ContinuationHelper::Frame::real_pc(const frame& f) {
|
||||
|
||||
@ -259,22 +259,25 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
void frame::patch_pc(Thread* thread, address pc) {
|
||||
assert(_cb == CodeCache::find_blob(pc), "unexpected pc");
|
||||
address* pc_addr = &(((address*) sp())[-1]);
|
||||
|
||||
if (TracePcPatching) {
|
||||
tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]",
|
||||
p2i(pc_addr), p2i(*pc_addr), p2i(pc));
|
||||
}
|
||||
|
||||
// Either the return address is the original one or we are going to
|
||||
// patch in the same address that's already there.
|
||||
assert(_pc == *pc_addr || pc == *pc_addr, "must be");
|
||||
assert(_pc == *pc_addr || pc == *pc_addr || *pc_addr == 0, "must be");
|
||||
DEBUG_ONLY(address old_pc = _pc;)
|
||||
*pc_addr = pc;
|
||||
_pc = pc; // must be set before call to get_deopt_original_pc
|
||||
address original_pc = CompiledMethod::get_deopt_original_pc(this);
|
||||
if (original_pc != NULL) {
|
||||
assert(original_pc == _pc, "expected original PC to be stored before patching");
|
||||
assert(original_pc == old_pc, "expected original PC to be stored before patching");
|
||||
_deopt_state = is_deoptimized;
|
||||
// leave _pc as is
|
||||
_pc = original_pc;
|
||||
} else {
|
||||
_deopt_state = not_deoptimized;
|
||||
_pc = pc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,6 +381,7 @@ void frame::verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::adjust_unextended_sp
|
||||
#ifdef ASSERT
|
||||
void frame::adjust_unextended_sp() {
|
||||
// On riscv, sites calling method handle intrinsics and lambda forms are treated
|
||||
// as any other call site. Therefore, no special action is needed when we are
|
||||
@ -394,6 +398,8 @@ void frame::adjust_unextended_sp() {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender_for_interpreter_frame
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
// original sp we use that convention.
|
||||
|
||||
intptr_t* _unextended_sp;
|
||||
void adjust_unextended_sp();
|
||||
void adjust_unextended_sp() NOT_DEBUG_RETURN;
|
||||
|
||||
intptr_t* ptr_at_addr(int offset) const {
|
||||
return (intptr_t*) addr_at(offset);
|
||||
@ -189,6 +189,7 @@
|
||||
frame(intptr_t* ptr_sp, intptr_t* ptr_fp);
|
||||
|
||||
void init(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc);
|
||||
void setup(address pc);
|
||||
|
||||
// accessors for the instance variables
|
||||
// Note: not necessarily the real 'frame pointer' (see real_fp)
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vmreg.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
|
||||
// Inline functions for RISCV frames:
|
||||
|
||||
@ -54,20 +55,31 @@ inline void frame::init(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc) {
|
||||
_unextended_sp = ptr_sp;
|
||||
_fp = ptr_fp;
|
||||
_pc = pc;
|
||||
_oop_map = NULL;
|
||||
_on_heap = false;
|
||||
DEBUG_ONLY(_frame_index = -1;)
|
||||
|
||||
assert(pc != NULL, "no pc?");
|
||||
_cb = CodeCache::find_blob(pc);
|
||||
setup(pc);
|
||||
}
|
||||
|
||||
inline void frame::setup(address pc) {
|
||||
adjust_unextended_sp();
|
||||
|
||||
address original_pc = CompiledMethod::get_deopt_original_pc(this);
|
||||
if (original_pc != NULL) {
|
||||
_pc = original_pc;
|
||||
_deopt_state = is_deoptimized;
|
||||
assert(_cb == NULL || _cb->as_compiled_method()->insts_contains_inclusive(_pc),
|
||||
"original PC must be in the main code section of the compiled method (or must be immediately following it)");
|
||||
} else {
|
||||
_deopt_state = not_deoptimized;
|
||||
if (_cb == SharedRuntime::deopt_blob()) {
|
||||
_deopt_state = is_deoptimized;
|
||||
} else {
|
||||
_deopt_state = not_deoptimized;
|
||||
}
|
||||
}
|
||||
|
||||
_on_heap = false;
|
||||
DEBUG_ONLY(_frame_index = -1;)
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* ptr_sp, intptr_t* ptr_fp, address pc) {
|
||||
@ -83,20 +95,11 @@ inline frame::frame(intptr_t* ptr_sp, intptr_t* unextended_sp, intptr_t* ptr_fp,
|
||||
_pc = pc;
|
||||
assert(pc != NULL, "no pc?");
|
||||
_cb = CodeCache::find_blob(pc);
|
||||
adjust_unextended_sp();
|
||||
|
||||
address original_pc = CompiledMethod::get_deopt_original_pc(this);
|
||||
if (original_pc != NULL) {
|
||||
_pc = original_pc;
|
||||
assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
|
||||
"original PC must be in the main code section of the the compiled method (or must be immediately following it)");
|
||||
_deopt_state = is_deoptimized;
|
||||
} else {
|
||||
_deopt_state = not_deoptimized;
|
||||
}
|
||||
|
||||
_oop_map = NULL;
|
||||
_on_heap = false;
|
||||
DEBUG_ONLY(_frame_index = -1;)
|
||||
|
||||
setup(pc);
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* ptr_sp) {
|
||||
@ -293,7 +296,11 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
|
||||
PRAGMA_DIAG_POP
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
Unimplemented();
|
||||
if (_cb == NULL) return NULL;
|
||||
if (_cb->oop_maps() != NULL) {
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#define CPU_RISCV_NATIVEINST_RISCV_HPP
|
||||
|
||||
#include "asm/assembler.hpp"
|
||||
#include "runtime/continuation.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
@ -195,7 +196,7 @@ class NativeInstruction {
|
||||
}
|
||||
static bool is_lwu_to_zr(address instr);
|
||||
|
||||
inline bool is_nop();
|
||||
inline bool is_nop() const;
|
||||
inline bool is_jump_or_nop();
|
||||
bool is_safepoint_poll();
|
||||
bool is_sigill_zombie_not_entrant();
|
||||
@ -494,7 +495,7 @@ class NativeIllegalInstruction: public NativeInstruction {
|
||||
static void insert(address code_pos);
|
||||
};
|
||||
|
||||
inline bool NativeInstruction::is_nop() {
|
||||
inline bool NativeInstruction::is_nop() const {
|
||||
uint32_t insn = *(uint32_t*)addr_at(0);
|
||||
return insn == 0x13;
|
||||
}
|
||||
@ -571,14 +572,17 @@ public:
|
||||
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { Unimplemented(); return false; }
|
||||
int displacement() const { Unimplemented(); return 0; }
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff) { Unimplemented(); }
|
||||
void make_deopt() { Unimplemented(); }
|
||||
};
|
||||
|
||||
inline NativePostCallNop* nativePostCallNop_at(address address) {
|
||||
Unimplemented();
|
||||
NativePostCallNop* nop = (NativePostCallNop*) address;
|
||||
if (nop->check()) {
|
||||
return nop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -590,6 +594,7 @@ public:
|
||||
void verify() { Unimplemented(); }
|
||||
|
||||
static bool is_deopt_at(address instr) {
|
||||
if (!Continuations::enabled()) return false;
|
||||
Unimplemented();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3700,6 +3700,100 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return stub->entry_point();
|
||||
}
|
||||
|
||||
address generate_cont_thaw() {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
address generate_cont_returnBarrier() {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
address generate_cont_returnBarrier_exception() {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RuntimeStub* generate_cont_doYield() {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if INCLUDE_JFR
|
||||
|
||||
#undef __
|
||||
#define __ _masm->
|
||||
|
||||
static void jfr_prologue(address the_pc, MacroAssembler* _masm, Register thread) {
|
||||
__ set_last_Java_frame(sp, fp, the_pc, t0);
|
||||
__ mv(c_rarg0, thread);
|
||||
}
|
||||
|
||||
static void jfr_epilogue(MacroAssembler* _masm, Register thread) {
|
||||
__ reset_last_Java_frame(true);
|
||||
Label null_jobject;
|
||||
__ beqz(x10, null_jobject);
|
||||
DecoratorSet decorators = ACCESS_READ | IN_NATIVE;
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->load_at(_masm, decorators, T_OBJECT, x10, Address(x10, 0), c_rarg0, thread);
|
||||
__ bind(null_jobject);
|
||||
}
|
||||
|
||||
static RuntimeStub* generate_jfr_stub(const char* name, address entrypoint) {
|
||||
enum layout {
|
||||
fp_off,
|
||||
fp_off2,
|
||||
return_off,
|
||||
return_off2,
|
||||
framesize // inclusive of return address
|
||||
};
|
||||
|
||||
int insts_size = 512;
|
||||
int locs_size = 64;
|
||||
CodeBuffer code(name, insts_size, locs_size);
|
||||
OopMapSet* oop_maps = new OopMapSet();
|
||||
MacroAssembler* masm = new MacroAssembler(&code);
|
||||
MacroAssembler* _masm = masm;
|
||||
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
int frame_complete = __ pc() - start;
|
||||
address the_pc = __ pc();
|
||||
jfr_prologue(the_pc, _masm, xthread);
|
||||
__ call_VM_leaf(entrypoint, 1);
|
||||
jfr_epilogue(_masm, xthread);
|
||||
__ leave();
|
||||
__ ret();
|
||||
|
||||
OopMap* map = new OopMap(framesize, 1);
|
||||
oop_maps->add_gc_map(the_pc - start, map);
|
||||
|
||||
RuntimeStub* stub = // codeBlob framesize is in words (not VMRegImpl::slot_size)
|
||||
RuntimeStub::new_runtime_stub(name, &code, frame_complete,
|
||||
(framesize >> (LogBytesPerWord - LogBytesPerInt)),
|
||||
oop_maps, false);
|
||||
return stub;
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
RuntimeStub* generate_jfr_write_checkpoint() {
|
||||
return generate_jfr_stub("jfr_write_checkpoint",
|
||||
CAST_FROM_FN_PTR(address, JfrIntrinsicSupport::write_checkpoint));
|
||||
}
|
||||
|
||||
RuntimeStub* generate_jfr_get_event_writer() {
|
||||
return generate_jfr_stub("jfr_get_event_writer",
|
||||
CAST_FROM_FN_PTR(address, JfrIntrinsicSupport::event_writer));
|
||||
}
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
// Initialization
|
||||
void generate_initial() {
|
||||
// Generate initial stubs and initializes the entry points
|
||||
@ -3729,6 +3823,23 @@ class StubGenerator: public StubCodeGenerator {
|
||||
SharedRuntime::throw_delayed_StackOverflowError));
|
||||
}
|
||||
|
||||
void generate_phase1() {
|
||||
// Continuation stubs:
|
||||
StubRoutines::_cont_thaw = generate_cont_thaw();
|
||||
StubRoutines::_cont_returnBarrier = generate_cont_returnBarrier();
|
||||
StubRoutines::_cont_returnBarrierExc = generate_cont_returnBarrier_exception();
|
||||
StubRoutines::_cont_doYield_stub = generate_cont_doYield();
|
||||
StubRoutines::_cont_doYield = StubRoutines::_cont_doYield_stub == nullptr ? nullptr
|
||||
: StubRoutines::_cont_doYield_stub->entry_point();
|
||||
|
||||
JFR_ONLY(StubRoutines::_jfr_write_checkpoint_stub = generate_jfr_write_checkpoint();)
|
||||
JFR_ONLY(StubRoutines::_jfr_write_checkpoint = StubRoutines::_jfr_write_checkpoint_stub == nullptr ? nullptr
|
||||
: StubRoutines::_jfr_write_checkpoint_stub->entry_point();)
|
||||
JFR_ONLY(StubRoutines::_jfr_get_event_writer_stub = generate_jfr_get_event_writer();)
|
||||
JFR_ONLY(StubRoutines::_jfr_get_event_writer = StubRoutines::_jfr_get_event_writer_stub == nullptr ? nullptr
|
||||
: StubRoutines::_jfr_get_event_writer_stub->entry_point();)
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
// support for verify_oop (must happen after universe_init)
|
||||
if (VerifyOops) {
|
||||
@ -3798,11 +3909,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
public:
|
||||
StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
|
||||
if (all) {
|
||||
generate_all();
|
||||
} else {
|
||||
StubGenerator(CodeBuffer* code, int phase) : StubCodeGenerator(code) {
|
||||
if (phase == 0) {
|
||||
generate_initial();
|
||||
} else if (phase == 1) {
|
||||
generate_phase1(); // stubs that must be available for the interpreter
|
||||
} else {
|
||||
generate_all();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -798,6 +798,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
// End of helpers
|
||||
|
||||
address TemplateInterpreterGenerator::generate_Continuation_doYield_entry(void) {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user