8286476: x86_32: Fix crashes with non-preview mode after JDK-8284161 (Virtual Threads)
Reviewed-by: coleenp, stuefe
This commit is contained in:
parent
87f3d2b870
commit
ae695d6cb7
@ -3866,6 +3866,104 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::x86::_fpu_subnormal_bias2[2]= 0x7bff;
|
||||
}
|
||||
|
||||
RuntimeStub* generate_cont_doYield() {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
address generate_cont_thaw(bool return_barrier, bool exception) {
|
||||
if (!Continuations::enabled()) return nullptr;
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if INCLUDE_JFR
|
||||
|
||||
static void jfr_prologue(address the_pc, MacroAssembler* masm) {
|
||||
Register java_thread = rdi;
|
||||
__ get_thread(java_thread);
|
||||
__ set_last_Java_frame(java_thread, rsp, rbp, the_pc);
|
||||
__ movptr(Address(rsp, 0), java_thread);
|
||||
}
|
||||
|
||||
// The handle is dereferenced through a load barrier.
|
||||
static void jfr_epilogue(MacroAssembler* masm) {
|
||||
Register java_thread = rdi;
|
||||
__ get_thread(java_thread);
|
||||
__ reset_last_Java_frame(java_thread, true);
|
||||
Label null_jobject;
|
||||
__ testptr(rax, rax);
|
||||
__ jcc(Assembler::zero, null_jobject);
|
||||
DecoratorSet decorators = ACCESS_READ | IN_NATIVE;
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->load_at(masm, decorators, T_OBJECT, rax, Address(rax, 0), noreg, java_thread);
|
||||
__ bind(null_jobject);
|
||||
}
|
||||
|
||||
// For c2: c_rarg0 is junk, call to runtime to write a checkpoint.
|
||||
// It returns a jobject handle to the event writer.
|
||||
// The handle is dereferenced and the return value is the event writer oop.
|
||||
static RuntimeStub* generate_jfr_write_checkpoint() {
|
||||
enum layout {
|
||||
FPUState_off = 0,
|
||||
rbp_off = FPUStateSizeInWords,
|
||||
rdi_off,
|
||||
rsi_off,
|
||||
rcx_off,
|
||||
rbx_off,
|
||||
saved_argument_off,
|
||||
saved_argument_off2, // 2nd half of double
|
||||
framesize
|
||||
};
|
||||
|
||||
int insts_size = 512;
|
||||
int locs_size = 64;
|
||||
CodeBuffer code("jfr_write_checkpoint", 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);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, JfrIntrinsicSupport::write_checkpoint), 1);
|
||||
jfr_epilogue(_masm);
|
||||
__ leave();
|
||||
__ ret(0);
|
||||
|
||||
OopMap* map = new OopMap(framesize, 1); // rbp
|
||||
oop_maps->add_gc_map(the_pc - start, map);
|
||||
|
||||
RuntimeStub* stub = // codeBlob framesize is in words (not VMRegImpl::slot_size)
|
||||
RuntimeStub::new_runtime_stub("jfr_write_checkpoint", &code, frame_complete,
|
||||
(framesize >> (LogBytesPerWord - LogBytesPerInt)),
|
||||
oop_maps, false);
|
||||
return stub;
|
||||
}
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Initialization
|
||||
|
||||
@ -3953,6 +4051,19 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
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->entry_point();)
|
||||
}
|
||||
|
||||
void generate_all() {
|
||||
// Generates all stubs and initializes the entry points
|
||||
|
||||
@ -4044,11 +4155,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();
|
||||
}
|
||||
}
|
||||
}; // end class declaration
|
||||
|
@ -116,7 +116,7 @@ ReferenceArgumentCount::ReferenceArgumentCount(Symbol* signature)
|
||||
do_parameters_on(this); // non-virtual template execution
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
#if !defined(_LP64) || defined(ZERO) || defined(ASSERT)
|
||||
static int compute_num_stack_arg_slots(Symbol* signature, int sizeargs, bool is_static) {
|
||||
ResourceMark rm;
|
||||
BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs);
|
||||
@ -138,7 +138,7 @@ static int compute_num_stack_arg_slots(Symbol* signature, int sizeargs, bool is_
|
||||
|
||||
return SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs);
|
||||
}
|
||||
#endif // ASSERT
|
||||
#endif
|
||||
|
||||
void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) {
|
||||
// See if we fingerprinted this method already
|
||||
@ -177,13 +177,15 @@ void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) {
|
||||
_param_size += 1; // this is the convention for Method::compute_size_of_parameters
|
||||
}
|
||||
|
||||
#if defined(_LP64) && !defined(ZERO)
|
||||
_stack_arg_slots = align_up(_stack_arg_slots, 2);
|
||||
|
||||
#ifdef ASSERT
|
||||
int dbg_stack_arg_slots = compute_num_stack_arg_slots(_signature, _param_size, static_flag);
|
||||
#if defined(_LP64) && !defined(ZERO)
|
||||
assert(_stack_arg_slots == dbg_stack_arg_slots, "fingerprinter: %d full: %d", _stack_arg_slots, dbg_stack_arg_slots);
|
||||
#endif
|
||||
#else
|
||||
// Fallback: computed _stack_arg_slots is unreliable, compute directly.
|
||||
_stack_arg_slots = compute_num_stack_arg_slots(_signature, _param_size, static_flag);
|
||||
#endif
|
||||
|
||||
// Detect overflow. (We counted _param_size correctly.)
|
||||
@ -220,7 +222,10 @@ void Fingerprinter::initialize_calling_convention(bool static_flag) {
|
||||
|
||||
void Fingerprinter::do_type_calling_convention(BasicType type) {
|
||||
// We compute the number of slots for stack-passed arguments in compiled calls.
|
||||
// The value computed for 32-bit ports and for zero is bogus, and will need to be fixed.
|
||||
// TODO: SharedRuntime::java_calling_convention is the shared code that knows all details
|
||||
// about the platform-specific calling conventions. This method tries to compute the stack
|
||||
// args number... poorly, at least for 32-bit ports and for zero. Current code has the fallback
|
||||
// that recomputes the stack args number from SharedRuntime::java_calling_convention.
|
||||
#if defined(_LP64) && !defined(ZERO)
|
||||
switch (type) {
|
||||
case T_VOID:
|
||||
|
Loading…
Reference in New Issue
Block a user