Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255401

Shenandoah: Allow oldval and newval registers to overlap in cmpxchg_oop()

XMLWordPrintable

    • b23
    • generic
    • generic

        We encountered a failure in testing:

        # Internal Error (/home/jenkins/workspace/nightly/jdk-jdk/src/hotspot/share/asm/register.hpp:141), pid=15470, tid=15611
        # assert(a != b && a != c && a != d && b != c && b != d && c != d) failed: registers must be different: a=0x0000000000000000, b=0x0000000000000000, c=0x000000000000000b, d=0x000000000000000a

        in:

        Stack: [0x00007fb8fa2e3000,0x00007fb8fa3e4000], sp=0x00007fb8fa3deca0, 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+0x156890e] ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler*, RegisterImpl*, Address, RegisterImpl*, RegisterImpl*, bool, RegisterImpl*, RegisterImpl*)+0xde
        V [libjvm.so+0x3ec1d1] compareAndSwapN_shenandoahNode::emit(CodeBuffer&, PhaseRegAlloc*) const+0x571
        V [libjvm.so+0x13d1f57] PhaseOutput::scratch_emit_size(Node const*)+0x477
        V [libjvm.so+0x13ca1e5] PhaseOutput::shorten_branches(unsigned int*)+0x2e5
        V [libjvm.so+0x13d9bfa] PhaseOutput::Output()+0x87a
        V [libjvm.so+0x91b61e] Compile::Code_Gen()+0x4ae
        V [libjvm.so+0x920b8d] Compile::Compile(ciEnv*, ciMethod*, int, bool, bool, bool, bool, DirectiveSet*)+0xfbd
        V [libjvm.so+0x7903f6] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x106
        V [libjvm.so+0x92e412] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x9b2
        V [libjvm.so+0x92edf8] CompileBroker::compiler_thread_loop()+0x438
        V [libjvm.so+0x17a8f37] JavaThread::thread_main_inner()+0x247
        V [libjvm.so+0x17ae2e8] Thread::call_run()+0xf8
        V [libjvm.so+0x13b159e] thread_native_entry(Thread*)+0x10e

        See also attached hs_err.
        It seems to appear very rarely. The failure is that both newval and oldval are the same register (rax). I believe this could be problematic and lead to misbehavior because the retry-loop would reuse newval, but that has (potentially) been clobbered by the preceding failed CAS.

        I couldn't reproduce it locally, yet.

        I suspect a fix might be to declare newval as TEMP in shenandoah_x86_64.ad, this should preserve it across the instruction.

              rkennke Roman Kennke
              rkennke Roman Kennke
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: