On 6/16/22 10:38, dean.l...@oracle.com wrote:
On 6/15/22 9:54 AM, Aleksey Shipilev wrote:
(I *suspect* that somewhere we stash the "current" thread onto stack,
and then remount to another thread, which makes "current" thread
obsolete. Assuming current thread does not change is quite pervasive,
and saving "current thread" on architectures without dedicated thread
register is rather common.)
That does sound like a problem. I noticed that
SharedRuntime::generate_native_wrapper() does this:
1554 // We use rdi as a thread pointer because it is callee save and
1555 // if we load it once it is usable thru the entire wrapper
1556 const Register thread = rdi;
This comment seems wrong for loom.
Yes, good spot!
In fact, most of the uses for thread registers on x86_32 seem to assume that thread register would
be clobbered by calls already, *except* when it is in callee-saved register. Luckily, many of those
paths are explicitly asserted, see for example MacroAssembler::call_VM_base:
// restore the thread (cannot use the pushed argument since arguments
// may be overwritten by C code generated by an optimizing compiler);
// however can use the register value directly if it is callee saved.
if (LP64_ONLY(true ||) java_thread == rdi || java_thread == rsi) {
// rdi & rsi (also r15) are callee saved -> nothing to do
#ifdef ASSERT
guarantee(java_thread != rax, "change this code");
push(rax);
{ Label L;
get_thread(rax);
cmpptr(java_thread, rax);
jcc(Assembler::equal, L);
STOP("MacroAssembler::call_VM_base: rdi not callee saved?");
bind(L);
}
pop(rax);
#endif
} else {
get_thread(java_thread);
}
I am going to sprinkle more thread verification everywhere...
--
Thanks,
-Aleksey