JDK-8216549 : Mismatched unsafe access to non escaping object fails
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,11,12,13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-01-11
  • Updated: 2019-10-04
  • Resolved: 2019-01-14
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 11 JDK 12 JDK 13
11.0.5Fixed 12 b28Fixed 13Fixed
Description
public class MismatchedUnsafeLoadFromNewObject {
    public volatile int f_int = -1;

    public static Unsafe unsafe = Unsafe.getUnsafe();
    public static final long f_int_off;

    static {
        Field f_int_field = null;
        try {
            f_int_field = CASandCAEwithNegExpected.class.getField("f_int");
        } catch (Exception e) {
            System.out.println("reflection failed " + e);
            e.printStackTrace();
        }
        f_int_off = unsafe.objectFieldOffset(f_int_field);
    }

    static public void main(String[] args) {
        for (int i = 0; i < 20_000; i++) {
            byte res = test1();
            if (res != -1) {
                throw new RuntimeException("Incorrect result: " + res);
            }
            res = test2();
            if (res != -1) {
                throw new RuntimeException("Incorrect result: " + res);
            }
        }
    }

    static byte test1() {
        MismatchedUnsafeLoadFromNewObject t = new MismatchedUnsafeLoadFromNewObject();
        return unsafe.getByte(t, f_int_off);
    }

    static byte test2() {
        MismatchedUnsafeLoadFromNewObject t = new MismatchedUnsafeLoadFromNewObject();
        return unsafe.getByte(t, f_int_off+1);
    }
}

test1() causes the compiler to crash, test2() returns incorrect result

#  Internal Error (/home/roland/hs/src/hotspot/share/opto/lcm.cpp:1162), pid=17302, tid=17315
#  assert(false) failed: graph should be schedulable

Stack: [0x00007fe7af3fc000,0x00007fe7af4fd000],  sp=0x00007fe7af4f7ce0,  free space=1007k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x119dc39]  PhaseCFG::schedule_local(Block*, GrowableArray<int>&, VectorSet&, long*)+0x739
V  [libjvm.so+0xd5b00d]  PhaseCFG::global_code_motion()+0xc1d
V  [libjvm.so+0xd5cfa1]  PhaseCFG::do_global_code_motion()+0x51
V  [libjvm.so+0xa17d9c]  Compile::Code_Gen()+0x28c
V  [libjvm.so+0xa1bffb]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x123b
V  [libjvm.so+0x81e401]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0xd1
V  [libjvm.so+0xa28c42]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x452
V  [libjvm.so+0xa29b90]  CompileBroker::compiler_thread_loop()+0x370
V  [libjvm.so+0x186e68f]  JavaThread::thread_main_inner()+0x2cf
V  [libjvm.so+0x1878981]  JavaThread::run()+0x1c1
V  [libjvm.so+0x1875820]  Thread::call_run()+0x100
V  [libjvm.so+0x147352d]  thread_native_entry(Thread*)+0x10d
Comments
Working on 8u backport. Review thread: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-August/010155.html
23-08-2019

ILW = Incorrect result of compiled code or assert during C2 compilation because of unschedulable graph, rare with unsafe accesses but easy to reproduce, disable escape analysis or compilation of affected method = HLM = P3
20-06-2019

Okay, thanks. I've updated the ILW.
20-06-2019

Fix Request (11u) This fixes C2 miscompilation. The patch applies cleanly to 11u. New testcase fails without product fix, and passes with it. Additionally, patched build passes tier1 and tier2 tests.
19-06-2019

I think ILW is slightly incorrect: in release bits, C2 would not bail and would instead "happily" miscompile. Applied the test to 11u-dev, ran the test on Linux x86_64 release, and test2() failed: STDERR: java.lang.RuntimeException: Incorrect result: 0 at MismatchedUnsafeLoadFromNewObject.main(MismatchedUnsafeLoadFromNewObject.java:66) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) TEST RESULT: Failed. Execution failed: `main' threw exception: java.lang.RuntimeException: Incorrect result: 0".
19-06-2019