JDK-8164103 : C2: Broken cmpxchgb encoding on x86
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: x86_64
  • Submitted: 2016-08-16
  • Updated: 2016-09-08
  • Resolved: 2016-08-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b135Fixed
Related Reports
Blocks :  
Relates :  
Description
The attached test VarHandleTestAccessBoolean.java fails only on windows_x64_6.3-product.

To test apply the following patch to jdk9/dev/jdk:

  http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8161444-vhs-bitwise-atomics/webrev/

compile with:

 javac --add-exports java.base/jdk.internal.misc=ALL-UNNAMED VarHandleTestAccessBoolean.java

and run with the attached run.sh script.

So far it has not been possible to reproduce on any other platform other than windows_x64_6.3-product.
Comments
Just a peculiarity of register allocation: new value should be put in RDI to trigger the bug.
17-08-2016

@Vladimir, thanks, i will verify today. Do you have an idea why this was only occurring on the windows platform?
17-08-2016

Suggested fix: diff --git a/src/cpu/x86/vm/x86_64.ad b/src/cpu/x86/vm/x86_64.ad --- a/src/cpu/x86/vm/x86_64.ad +++ b/src/cpu/x86/vm/x86_64.ad @@ -7355,7 +7355,7 @@ "movzbl $res, $res" %} opcode(0x0F, 0xB0); ins_encode(lock_prefix, - REX_reg_mem(newval, mem_ptr), + REX_breg_mem(newval, mem_ptr), OpcP, OpcS, reg_mem(newval, mem_ptr), REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete @@ -7424,7 +7424,7 @@ "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} opcode(0x0F, 0xB0); ins_encode(lock_prefix, - REX_reg_mem(newval, mem_ptr), + REX_breg_mem(newval, mem_ptr), OpcP, OpcS, reg_mem(newval, mem_ptr) // lock cmpxchg );
17-08-2016

compareAndSwapB was added by JDK-8157726.
17-08-2016

The problem is that cmpxchgb instruction encoding is wrong: jdk/internal/misc/Unsafe.getAndBitwiseAndBoolean(Ljava/lang/Object;JZ)Z ... 0x000000000ad8bd03: mov edi,r10d 0x000000000ad8bd06: and edi,r11d 0x000000000ad8bd09: movsx edi,dil 0x000000000ad8bd0d: mov eax,r11d 0x000000000ad8bd10: lock cmpxchg byte ptr [rcx],bh 043 movl RDI, R10 # spill 046 andl RDI, R11 # int 049 movsbl RDI, RDI # i2b 04d movl RAX, R11 # spill 050 cmpxchgb [RCX],RDI # If rax == [RCX] then store RDI into [RCX] The value is put in DIL, but the instruction refers to BH.
17-08-2016