openj9
openj9 copied to clipboard
WIP: Adjust arguments to transformed UnsafeAPI calls when offheap is enabled
During recognizedCallTransformer and unsafeFastPath, Unsafe.getAndAdd() or Unsafe.getAndSet() can be transformed into an atomicFetchAndAdd/atomicSwap helper call. For the UnsafeAPI methods, the destination address is passed in as two separate values: a base object address and an offset. When they are transformed into atomic helper calls, these values are added together and passed in as a single destination address value. However, this does not account for the differing shape of array objects under offheap/balanced GC policy (as opposed to the default, gencon).
Thus, this contribution includes the following changes
- For both recognizedCallTransformer and unsafeFastPath, if the object is an array, the
dataAddrpointer is loaded and used as the base address. - For recognizedCallTransformer, an array check is added to the series of runtime tests performed before calling the atomic helper, to ensure that
dataAddris only used if the object is indeed an array.
@zl-wang here is the Unsafe.getAndAdd()/getAndSet() fix! Marked as a WIP since I am still finalizing the unsafeFastPath changes (the last two commits)
During recognizedCallTransformer and unsafeFastPath,
Unsafe.getAndAdd()orUnsafe.getAndSet()can be transformed into anatomicFetchAndAdd/atomicSwaphelper call. For the UnsafeAPI methods, the destination address is passed in as two separate values: a base object address and an offset. When they are transformed into atomic helper calls, these values are added together and passed in as a single destination address value. However, this does not account for the differing shape of array objects under offheap/balanced GC policy (as opposed to the default, gencon).Thus, this contribution includes the following changes
- For both recognizedCallTransformer and unsafeFastPath, if the object is an array, the
dataAddrpointer is loaded and used as the base address.- For recognizedCallTransformer, an array check is added to the series of runtime tests performed before calling the atomic helper, to ensure that
dataAddris only used if the object is indeed an array.
During the running period of our application, from the thread stack, it has been "staying" at AtomicReferenceArray#getAndSet. A phenomenon similar to livelock has occurred. As a result, the thread is blocked and the application is seriously unrecoverable. I am not sure if it is related to your problem? @midronij @zl-wang
thread stack: "pool-EventCacheMessageHandler-thread-1" Id=21859 RUNNABLE at sun.misc.Unsafe.getAndSetObject(Unsafe.java:1165) at java.util.concurrent.atomic.AtomicReferenceArray.getAndSet(AtomicReferenceArray.java:164) at com.fasterxml.jackson.core.util.BufferRecycler.allocCharBuffer(BufferRecycler.java:159) at com.fasterxml.jackson.core.io.IOContext.allocTokenBuffer(IOContext.java:270) at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1164) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3629) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3597)
java version: openjdk version "1.8.0_422" IBM Semeru Runtime Open Edition (build 1.8.0_422-b05) Eclipse OpenJ9 VM (build openj9-0.46.0, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20240802_1004 (JIT enabled, AOT enabled) OpenJ9 - 1a6f6128aa OMR - 840a9adba JCL - a75ff73ce5 based on jdk8u422-b05)
Jenkins test sanity.functional all jdk8,jdk23
@midronij there was one xlinux test failure: JIT server doesn't exist. it might not be related to your change, but please make sure of it.
@zl-wang just confirmed, as far as I can tell the JITServer failure on x isn't related to my changes
pp64-aix testing failure was due to infra issue ... all tests passed; xlinux testing failure at jit-server not existing is not related to this PR; x86-windows aborted due to infra issue;
merging ...