mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 17:14:41 +02:00
8255606: Enable concurrent stack processing on x86_32 platforms
Reviewed-by: shade, rkennke, eosterlund
This commit is contained in:
parent
ca216bae1a
commit
134e22a00f
7 changed files with 49 additions and 29 deletions
|
@ -80,19 +80,29 @@ void ConversionStub::emit_code(LIR_Assembler* ce) {
|
||||||
#endif // !_LP64
|
#endif // !_LP64
|
||||||
|
|
||||||
void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
|
void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
|
||||||
#ifdef _LP64
|
|
||||||
__ bind(_entry);
|
__ bind(_entry);
|
||||||
InternalAddress safepoint_pc(ce->masm()->pc() - ce->masm()->offset() + safepoint_offset());
|
InternalAddress safepoint_pc(ce->masm()->pc() - ce->masm()->offset() + safepoint_offset());
|
||||||
|
#ifdef _LP64
|
||||||
__ lea(rscratch1, safepoint_pc);
|
__ lea(rscratch1, safepoint_pc);
|
||||||
__ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
|
__ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
|
||||||
|
#else
|
||||||
|
const Register tmp1 = rcx;
|
||||||
|
const Register tmp2 = rdx;
|
||||||
|
__ push(tmp1);
|
||||||
|
__ push(tmp2);
|
||||||
|
|
||||||
|
__ lea(tmp1, safepoint_pc);
|
||||||
|
__ get_thread(tmp2);
|
||||||
|
__ movptr(Address(tmp2, JavaThread::saved_exception_pc_offset()), tmp1);
|
||||||
|
|
||||||
|
__ pop(tmp2);
|
||||||
|
__ pop(tmp1);
|
||||||
|
#endif /* _LP64 */
|
||||||
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
||||||
"polling page return stub not created yet");
|
"polling page return stub not created yet");
|
||||||
|
|
||||||
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
|
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
|
||||||
__ jump(RuntimeAddress(stub));
|
__ jump(RuntimeAddress(stub));
|
||||||
#else
|
|
||||||
ShouldNotReachHere();
|
|
||||||
#endif /* _LP64 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
|
void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
|
||||||
|
|
|
@ -535,17 +535,14 @@ void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) {
|
||||||
// the poll sets the condition code, but no data registers
|
// the poll sets the condition code, but no data registers
|
||||||
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
|
const Register thread = r15_thread;
|
||||||
|
#else
|
||||||
|
const Register thread = rbx;
|
||||||
|
__ get_thread(thread);
|
||||||
|
#endif
|
||||||
code_stub->set_safepoint_offset(__ offset());
|
code_stub->set_safepoint_offset(__ offset());
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ relocate(relocInfo::poll_return_type);
|
||||||
__ safepoint_poll(*code_stub->entry(), r15_thread, true /* at_return */, true /* in_nmethod */);
|
__ safepoint_poll(*code_stub->entry(), thread, true /* at_return */, true /* in_nmethod */);
|
||||||
#else
|
|
||||||
const Register poll_addr = rbx;
|
|
||||||
assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
|
|
||||||
__ get_thread(poll_addr);
|
|
||||||
__ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
|
|
||||||
__ relocate(relocInfo::poll_return_type);
|
|
||||||
__ testl(rax, Address(poll_addr, 0));
|
|
||||||
#endif
|
|
||||||
__ ret(0);
|
__ ret(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
#define __ masm.
|
#define __ masm.
|
||||||
void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointPollStub* entry) const {
|
void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointPollStub* entry) const {
|
||||||
#ifdef _LP64
|
|
||||||
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
|
||||||
"polling page return stub not created yet");
|
"polling page return stub not created yet");
|
||||||
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
|
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
|
||||||
|
@ -40,11 +39,22 @@ void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointP
|
||||||
|
|
||||||
__ bind(entry->_stub_label);
|
__ bind(entry->_stub_label);
|
||||||
InternalAddress safepoint_pc(masm.pc() - masm.offset() + entry->_safepoint_offset);
|
InternalAddress safepoint_pc(masm.pc() - masm.offset() + entry->_safepoint_offset);
|
||||||
|
#ifdef _LP64
|
||||||
__ lea(rscratch1, safepoint_pc);
|
__ lea(rscratch1, safepoint_pc);
|
||||||
__ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
|
__ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1);
|
||||||
__ jump(callback_addr);
|
|
||||||
#else
|
#else
|
||||||
ShouldNotReachHere();
|
const Register tmp1 = rcx;
|
||||||
|
const Register tmp2 = rdx;
|
||||||
|
__ push(tmp1);
|
||||||
|
__ push(tmp2);
|
||||||
|
|
||||||
|
__ lea(tmp1, safepoint_pc);
|
||||||
|
__ get_thread(tmp2);
|
||||||
|
__ movptr(Address(tmp2, JavaThread::saved_exception_pc_offset()), tmp1);
|
||||||
|
|
||||||
|
__ pop(tmp2);
|
||||||
|
__ pop(tmp1);
|
||||||
#endif
|
#endif
|
||||||
|
__ jump(callback_addr);
|
||||||
}
|
}
|
||||||
#undef __
|
#undef __
|
||||||
|
|
|
@ -2761,15 +2761,13 @@ void MacroAssembler::save_rax(Register tmp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, bool at_return, bool in_nmethod) {
|
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, bool at_return, bool in_nmethod) {
|
||||||
#ifdef _LP64
|
|
||||||
if (at_return) {
|
if (at_return) {
|
||||||
// Note that when in_nmethod is set, the stack pointer is incremented before the poll. Therefore,
|
// Note that when in_nmethod is set, the stack pointer is incremented before the poll. Therefore,
|
||||||
// we may safely use rsp instead to perform the stack watermark check.
|
// we may safely use rsp instead to perform the stack watermark check.
|
||||||
cmpq(in_nmethod ? rsp : rbp, Address(thread_reg, Thread::polling_word_offset()));
|
cmpptr(in_nmethod ? rsp : rbp, Address(thread_reg, Thread::polling_word_offset()));
|
||||||
jcc(Assembler::above, slow_path);
|
jcc(Assembler::above, slow_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
testb(Address(thread_reg, Thread::polling_word_offset()), SafepointMechanism::poll_bit());
|
testb(Address(thread_reg, Thread::polling_word_offset()), SafepointMechanism::poll_bit());
|
||||||
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
|
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
|
||||||
}
|
}
|
||||||
|
|
|
@ -1023,7 +1023,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr static bool supports_stack_watermark_barrier() {
|
constexpr static bool supports_stack_watermark_barrier() {
|
||||||
return LP64_ONLY(true) NOT_LP64(false);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// there are several insns to force cache line sync to memory which
|
// there are several insns to force cache line sync to memory which
|
||||||
|
|
|
@ -653,8 +653,9 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
|
||||||
}
|
}
|
||||||
st->print_cr("POPL EBP"); st->print("\t");
|
st->print_cr("POPL EBP"); st->print("\t");
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
st->print("TEST PollPage,EAX\t! Poll Safepoint");
|
st->print("CMPL rsp, poll_offset[thread] \n\t"
|
||||||
st->cr(); st->print("\t");
|
"JA #safepoint_stub\t"
|
||||||
|
"# Safepoint: poll for GC");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -697,12 +698,16 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
Register pollReg = as_Register(EBX_enc);
|
Register thread = as_Register(EBX_enc);
|
||||||
MacroAssembler masm(&cbuf);
|
MacroAssembler masm(&cbuf);
|
||||||
masm.get_thread(pollReg);
|
__ get_thread(thread);
|
||||||
masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
|
Label dummy_label;
|
||||||
masm.relocate(relocInfo::poll_return_type);
|
Label* code_stub = &dummy_label;
|
||||||
masm.testl(rax, Address(pollReg, 0));
|
if (!C->output()->in_scratch_emit_size()) {
|
||||||
|
code_stub = &C->output()->safepoint_poll_table()->add_safepoint(__ offset());
|
||||||
|
}
|
||||||
|
__ relocate(relocInfo::poll_return_type);
|
||||||
|
__ safepoint_poll(*code_stub, thread, true /* at_return */, true /* in_nmethod */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -930,8 +930,8 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||||
st->print_cr("popq rbp");
|
st->print_cr("popq rbp");
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
st->print("\t");
|
st->print("\t");
|
||||||
st->print_cr("cmpq poll_offset[r15_thread], rsp\n\t"
|
st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t"
|
||||||
"ja #safepoint_stub\t"
|
"ja #safepoint_stub\t"
|
||||||
"# Safepoint: poll for GC");
|
"# Safepoint: poll for GC");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue