Code review revealed an error in MacroAssembler::get_thread() for windows x64:
66// call (Thread*)TlsGetValue(thread_index());
67void MacroAssembler::get_thread(Register thread) {
68 if (thread != rax) {
69 push(rax);
70 }
71 push(rdi);
72 push(rsi);
73 push(rdx);
74 push(rcx);
75 push(r8);
76 push(r9);
77 push(r10);
78 // XXX
79 mov(r10, rsp);
80 andq(rsp, -16);
81 push(r10);
82 push(r11);
83
84 movl(c_rarg0, ThreadLocalStorage::thread_index());
85 call(RuntimeAddress((address)TlsGetValue));
86
87 pop(r11);
88 pop(rsp);
89 pop(r10);
90 pop(r9);
91 pop(r8);
92 pop(rcx);
93 pop(rdx);
94 pop(rsi);
95 pop(rdi);
96 if (thread != rax) {
97 mov(thread, rax);
98 pop(rax);
99 }
100}
when preparing the call to TlsGetValue(), it uses the space above the return address to save registers and restores them after the function call. This violates the x64 windows abi, which states this about the parameter register stack area:
"Even if the called function has fewer than 4 parameters, these 4 stack locations are effectively owned by the called function, and may be used by the called function for other purposes besides saving parameter register values. Thus the caller may not save information in this region of stack across a function call."
https://msdn.microsoft.com/en-us/library/ew5tede7(v=VS.90).aspx
See also discussion under
http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-November/020765.html
66// call (Thread*)TlsGetValue(thread_index());
67void MacroAssembler::get_thread(Register thread) {
68 if (thread != rax) {
69 push(rax);
70 }
71 push(rdi);
72 push(rsi);
73 push(rdx);
74 push(rcx);
75 push(r8);
76 push(r9);
77 push(r10);
78 // XXX
79 mov(r10, rsp);
80 andq(rsp, -16);
81 push(r10);
82 push(r11);
83
84 movl(c_rarg0, ThreadLocalStorage::thread_index());
85 call(RuntimeAddress((address)TlsGetValue));
86
87 pop(r11);
88 pop(rsp);
89 pop(r10);
90 pop(r9);
91 pop(r8);
92 pop(rcx);
93 pop(rdx);
94 pop(rsi);
95 pop(rdi);
96 if (thread != rax) {
97 mov(thread, rax);
98 pop(rax);
99 }
100}
when preparing the call to TlsGetValue(), it uses the space above the return address to save registers and restores them after the function call. This violates the x64 windows abi, which states this about the parameter register stack area:
"Even if the called function has fewer than 4 parameters, these 4 stack locations are effectively owned by the called function, and may be used by the called function for other purposes besides saving parameter register values. Thus the caller may not save information in this region of stack across a function call."
https://msdn.microsoft.com/en-us/library/ew5tede7(v=VS.90).aspx
See also discussion under
http://mail.openjdk.java.net/pipermail/hotspot-dev/2015-November/020765.html