< prev index next >
src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp
Print this page
rev 48494 : 8195112: x86 (32 bit): implementation for Thread-local handshakes
Reviewed-by:
*** 2109,2128 ****
}
Label after_transition;
// check for safepoint operation in progress and/or pending suspend requests
! { Label Continue;
! __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()),
! SafepointSynchronize::_not_synchronized);
- Label L;
- __ jcc(Assembler::notEqual, L);
__ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
__ jcc(Assembler::equal, Continue);
! __ bind(L);
// Don't use call_VM as it will see a possible pending exception and forward it
// and never return here preventing us from clearing _last_native_pc down below.
// Also can't use call_VM_leaf either as it will check to see if rsi & rdi are
// preserved and correspond to the bcp/locals pointers. So we do a runtime call
--- 2109,2125 ----
}
Label after_transition;
// check for safepoint operation in progress and/or pending suspend requests
! { Label Continue, slow_path;
! __ safepoint_poll(slow_path, thread, noreg);
__ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
__ jcc(Assembler::equal, Continue);
! __ bind(slow_path);
// Don't use call_VM as it will see a possible pending exception and forward it
// and never return here preventing us from clearing _last_native_pc down below.
// Also can't use call_VM_leaf either as it will check to see if rsi & rdi are
// preserved and correspond to the bcp/locals pointers. So we do a runtime call
*** 2994,3005 ****
__ push(java_thread);
__ set_last_Java_frame(java_thread, noreg, noreg, NULL);
// if this was not a poll_return then we need to correct the return address now.
if (!cause_return) {
! __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
! __ movptr(Address(rbp, wordSize), rax);
}
// do the call
__ call(RuntimeAddress(call_ptr));
--- 2991,3005 ----
__ push(java_thread);
__ set_last_Java_frame(java_thread, noreg, noreg, NULL);
// if this was not a poll_return then we need to correct the return address now.
if (!cause_return) {
! // Get the return pc saved by the signal handler and stash it in its appropriate place on the stack.
! // Additionally, rbx is a callee saved register and we can look at it later to determine
! // if someone changed the return address for us!
! __ movptr(rbx, Address(java_thread, JavaThread::saved_exception_pc_offset()));
! __ movptr(Address(rbp, wordSize), rbx);
}
// do the call
__ call(RuntimeAddress(call_ptr));
*** 3027,3041 ****
--- 3027,3093 ----
__ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
__ bind(noException);
+ Label no_adjust, bail, not_special;
+ if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+ // If our stashed return pc was modified by the runtime we avoid touching it
+ __ cmpptr(rbx, Address(rbp, wordSize));
+ __ jccb(Assembler::notEqual, no_adjust);
+
+ // Skip over the poll instruction.
+ // See NativeInstruction::is_safepoint_poll()
+ // Possible encodings:
+ // 85 00 test %eax,(%rax)
+ // 85 01 test %eax,(%rcx)
+ // 85 02 test %eax,(%rdx)
+ // 85 03 test %eax,(%rbx)
+ // 85 06 test %eax,(%rsi)
+ // 85 07 test %eax,(%rdi)
+ //
+ // 85 04 24 test %eax,(%rsp)
+ // 85 05 00 test %eax,0x0(%rbp)
+
+ #ifdef ASSERT
+ __ movptr(rax, rbx); // remember where 0x85 should be, for verification below
+ #endif
+ // rsp/rbp base encoding takes 3 bytes with the following register values:
+ // rsp 0x04
+ // rbp 0x05
+ __ movzbl(rcx, Address(rbx, 1));
+ __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05
+ __ subptr(rcx, 4); // looking for 0x00 .. 0x01
+ __ cmpptr(rcx, 1);
+ __ jcc(Assembler::above, not_special);
+ __ addptr(rbx, 1);
+ __ bind(not_special);
+ #ifdef ASSERT
+ // Verify the correct encoding of the poll we're about to skip.
+ __ cmpb(Address(rax, 0), NativeTstRegMem::instruction_code_memXregl);
+ __ jcc(Assembler::notEqual, bail);
+ // Mask out the modrm bits
+ __ testb(Address(rax, 1), NativeTstRegMem::modrm_mask);
+ // rax encodes to 0, so if the bits are nonzero it's incorrect
+ __ jcc(Assembler::notZero, bail);
+ #endif
+ // Adjust return pc forward to step over the safepoint poll instruction
+ __ addptr(rbx, 2);
+ __ movptr(Address(rbp, wordSize), rbx);
+ }
+
+ __ bind(no_adjust);
// Normal exit, register restoring and exit
RegisterSaver::restore_live_registers(masm, save_vectors);
__ ret(0);
+ #ifdef ASSERT
+ __ bind(bail);
+ __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+ #endif
+
// make sure all code is generated
masm->flush();
// Fill-out other meta info
return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words);
< prev index next >