JDK-8253464 : ARM32 Zero: atomic_copy64 is incorrect, breaking volatile stores
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 7,8,11,15,16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-09-22
  • Updated: 2020-10-05
  • Resolved: 2020-09-23
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 16
16 b18Fixed
Related Reports
Relates :  
Description
Running current arm32-zero binaries with jcstress yields this exception:

$ java -jar jcstress-tests-all-20200917.jar --jvmArgs "-Xint" -m quick
Java Concurrency Stress Tests
---------------------------------------------------------------------------------
Rev: ad66703e2ed0, built by buildbot with 11.0.5-testing at 2020-09-17T13:24:16Z

Exception in thread "main" java.util.ServiceConfigurationError: Locale provider adapter "CLDR"cannot be instantiated.
	at java.base/sun.util.locale.provider.LocaleProviderAdapter.forType(LocaleProviderAdapter.java:199)
	at java.base/sun.util.locale.provider.LocaleProviderAdapter.findAdapter(LocaleProviderAdapter.java:287)
	at java.base/sun.util.locale.provider.LocaleProviderAdapter.getAdapter(LocaleProviderAdapter.java:258)
	at java.base/java.util.Calendar.createCalendar(Calendar.java:1693)
	at java.base/java.util.Calendar.getInstance(Calendar.java:1661)
	at java.base/java.text.SimpleDateFormat.initializeCalendar(SimpleDateFormat.java:677)
	at java.base/java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:621)
	at org.openjdk.jcstress.Options.parse(Options.java:176)
	at org.openjdk.jcstress.Main.main(Main.java:48)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
	at java.base/sun.util.locale.provider.LocaleProviderAdapter.forType(LocaleProviderAdapter.java:188)
	... 8 more
Caused by: java.lang.OutOfMemoryError: Cannot reserve 8192 bytes of direct buffer memory (allocated: 0, limit: -5290888278393214624)
	at java.base/java.nio.Bits.reserveMemory(Bits.java:178)
	at java.base/java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:120)
	at java.base/java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:330)
	at java.base/jdk.internal.jimage.ImageBufferCache.allocateBuffer(ImageBufferCache.java:52)
	at java.base/jdk.internal.jimage.ImageBufferCache.getBuffer(ImageBufferCache.java:85)
	at java.base/jdk.internal.jimage.BasicImageReader.readBuffer(BasicImageReader.java:364)
	at java.base/jdk.internal.jimage.BasicImageReader.getResourceBuffer(BasicImageReader.java:421)
	at java.base/jdk.internal.jimage.ImageReader.getResourceBuffer(ImageReader.java:194)
	at java.base/jdk.internal.module.SystemModuleFinders$SystemModuleReader.read(SystemModuleFinders.java:466)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:735)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClass(BuiltinClassLoader.java:616)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:634)
	at java.base/java.lang.Class.forName(Class.java:546)
	at java.base/java.util.ServiceLoader.loadProvider(ServiceLoader.java:854)
	at java.base/java.util.ServiceLoader$ModuleServicesLookupIterator.hasNext(ServiceLoader.java:1078)
	at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1301)
	at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1386)
	at java.base/sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:89)
	at java.base/sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:86)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)
	at java.base/sun.util.cldr.CLDRLocaleProviderAdapter.<init>(CLDRLocaleProviderAdapter.java:86)
	... 14 more

This seems to only happen with release builds. fastdebug builds seem to pass fine.

Bisection points to JDK-8218565, and its reversal makes the release builds work. But that makes little sense! It must be just triggering the other bug, not being the root cause itself.
Comments
Changeset: c21690b5 Author: Aleksey Shipilev <shade@openjdk.org> Date: 2020-09-23 16:53:10 +0000 URL: https://git.openjdk.java.net/jdk/commit/c21690b5
23-09-2020

The actual cause seems to be JDK-8211387. Reverting JDK-8211387 from head JDK makes ARM32 start and run jcstress.
22-09-2020

Same thing in hex, low words are zero! Caused by: java.lang.IllegalStateException: VM.maxDirectMemory() is: f780000, MAX_MEMORY updated from b69635f000000000 to b69635f000000000
22-09-2020

Following up on "limit: -5290888278393214624" yields more mysteries. That value is the printout of MAX_MEMORY. Add this to track updates: diff --git a/src/java.base/share/classes/java/nio/Bits.java b/src/java.base/share/classes/java/nio/Bits.java index 7e8b833dbea..3e0843be952 100644 --- a/src/java.base/share/classes/java/nio/Bits.java +++ b/src/java.base/share/classes/java/nio/Bits.java @@ -109,7 +109,12 @@ class Bits { // package-private static void reserveMemory(long size, int cap) { if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) { + long oldM = MAX_MEMORY; MAX_MEMORY = VM.maxDirectMemory(); + long newM = MAX_MEMORY; + if (newM < 0) { + throw new IllegalStateException("VM.maxDirectMemory() is: " + VM.maxDirectMemory() + ", MAX_MEMORY updated from " + oldM + " to " + newM); + } MEMORY_LIMIT_SET = true; } It yields: "Caused by: java.lang.IllegalStateException: VM.maxDirectMemory() is: 259522560, MAX_MEMORY updated from -5292936894647107584 to -5292936894647107584" It seems MAX_MEMORY was not initialized before, and then *it was not initialized even after the immediate store*. Looks like volatile long stores are broken.
22-09-2020

This seems to fix it: https://github.com/openjdk/jdk/compare/master...shipilev:JDK-8253464-zero-atomic-copy64
22-09-2020