Execution problems with Atomic Operations on OpenJDK10 for ARM5 Soft Float

Bob Vandette bob.vandette at oracle.com
Wed Apr 4 16:15:38 UTC 2018


I believe the problem is that the VM is now using more atomic load/store of java longs
and we don’t support these operations on multi-processing ARMv5 systems due to the
lack of low level atomic instructions.  On non MP ARMv5 systems, we use load/store multiple
instructions.

If you can determine that your ARMv5 processor’s implementation of ldmia/stmia are
indeed atomic, you could try to use these instructions by altering the code below.

Otherwise, you might want to investigate gcc atomic intrinsics and see if 8 byte atomics
are supported on your platform.  There’s a set of kernel helper routines that we use
for atomic exchange of 8 bytes, maybe they now have atomic 8 byte loads/stores.

https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt


In open/src/hotspot/cpu/arm/stubGenerator_arm.cpp, these two functions would need to be
fixed to provide these low level operations.

  address generate_atomic_load_long() {
    address start;

    StubCodeMark mark(this, "StubRoutines", "atomic_load_long");
    start = __ pc();
    Register result_lo = R0;
    Register result_hi = R1;
    Register src       = R0;

    if (!os::is_MP()) {
      __ ldmia(src, RegisterSet(result_lo, result_hi));
      __ bx(LR);
    } else if (VM_Version::supports_ldrexd()) {
      __ ldrexd(result_lo, Address(src));
      __ clrex(); // FIXME: safe to remove?
      __ bx(LR);
    } else {
      __ stop("Atomic load(jlong) unsupported on this platform");
      __ bx(LR);
    }

    return start;
  }

  address generate_atomic_store_long() {
    address start;

    StubCodeMark mark(this, "StubRoutines", "atomic_store_long");
    start = __ pc();
    Register newval_lo = R0;
    Register newval_hi = R1;
    Register dest      = R2;
    Register scratch_lo    = R2;
    Register scratch_hi    = R3;  /* After load from stack */
    Register result    = R3;

    if (!os::is_MP()) {
      __ stmia(dest, RegisterSet(newval_lo, newval_hi));
      __ bx(LR);
    } else if (VM_Version::supports_ldrexd()) {
      __ mov(Rtemp, dest);  // get dest to Rtemp
      Label retry;
      __ bind(retry);
      __ ldrexd(scratch_lo, Address(Rtemp));
      __ strexd(result, R0, Address(Rtemp));
      __ rsbs(result, result, 1);
      __ b(retry, eq);
      __ bx(LR);
    } else {
      __ stop("Atomic store(jlong) unsupported on this platform");
      __ bx(LR);
    }

    return start;
  }

Bob.

> On Apr 4, 2018, at 11:06 AM, John Paul Adrian Glaubitz <glaubitz at physik.fu-berlin.de> wrote:
> 
> CC'ing hotspot-dev
> 
> On 04/04/2018 12:29 PM, bren at juanantonio.info wrote:
>> I think that in OpenJDK10 changed something in compare to OpenJDK9 in relation to ARM5 support.
> 
> It was OpenJDK9 which dropped support for ARM CPUs prior ARMv7. If you are
> using ARMv5, you have to resort to OpenJDK Zero, i.e. the unoptimized, generic
> implementation of the JVM.
> 
> As for the atomic operation, I'm not sure whether Zero supports this particular
> atomic operation. I will have to dig into the code myself.
> 
> Would it be possible that you provide sample code that helps reproduce the problem?
> 
> Adrian
> 
> -- 
> .''`.  John Paul Adrian Glaubitz
> : :' :  Debian Developer - glaubitz at debian.org
> `. `'   Freie Universitaet Berlin - glaubitz at physik.fu-berlin.de
>  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913



More information about the build-dev mailing list