JDK-8329260 : C2 fails to inline memory access API due to "unloaded signature classes"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 14,17,21,23
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2024-03-28
  • Updated: 2024-07-03
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.
Other
tbdUnresolved
Related Reports
Relates :  
Description
Running attached Test2.java shows some inlining failures due to "unloaded signature classes" since JDK-8234049 in JDK 14 b28:

java -XX:CompileCommand=compileonly,"Test2::test" -XX:CompileCommand=quiet -Xbatch -XX:+PrintCompilation -XX:+PrintInlining Test2.java

1723  107    b  3       Test2::test (12 bytes)
                              @ 2   java.nio.ByteBuffer::allocate (20 bytes)   failed to inline: callee uses too much stack
                              @ 8   java.nio.ByteBuffer::getShort (0 bytes)   failed to inline: no static binding
1732  108    b  4       Test2::test (12 bytes)
1735  107       3       Test2::test (12 bytes)   made not entrant
                              @ 2   java.nio.ByteBuffer::allocate (20 bytes)   inline (hot)
                                @ 16   java.nio.HeapByteBuffer::<init> (21 bytes)   failed to inline: unloaded signature classes
                              @ 8   java.nio.HeapByteBuffer::getShort (30 bytes)   inline (hot)
                                @ 4   java.nio.Buffer::session (20 bytes)   failed to inline: unloaded signature classes
                                @ 15   java.nio.Buffer::checkIndex (16 bytes)   force inline by annotation
                                  @ 12   jdk.internal.util.Preconditions::checkIndex (18 bytes)   (intrinsic)
                                @ 19   java.nio.HeapByteBuffer::byteOffset (7 bytes)   inline (hot)
               !                @ 26   jdk.internal.misc.ScopedMemoryAccess::getShortUnaligned (18 bytes)   failed to inline: unloaded signature classes

Running with JDK 13 looks like this:

   1561   88    b  3       Test2::test (12 bytes)
                              @ 2   java.nio.ByteBuffer::allocate (19 bytes)   not compilable (disabled)
                              @ 8   java.nio.ByteBuffer::getShort (0 bytes)   no static binding
   1570   89    b  4       Test2::test (12 bytes)
   1573   88       3       Test2::test (12 bytes)   made not entrant
                              @ 2   java.nio.ByteBuffer::allocate (19 bytes)   inline (hot)
                                @ 15   java.nio.HeapByteBuffer::<init> (20 bytes)   inline (hot)
                                  @ 9   java.nio.ByteBuffer::<init> (45 bytes)   inline (hot)
                                    @ 6   java.nio.Buffer::<init> (99 bytes)   inline (hot)
                                      @ 1   java.lang.Object::<init> (1 bytes)   inline (hot)
                                      @ 33   java.nio.ByteBuffer::limit (6 bytes)   inline (hot)
                                        @ 2   java.nio.ByteBuffer::limit (8 bytes)   inline (hot)
                                          @ 2   java.nio.Buffer::limit (74 bytes)   inline (hot)
                                      @ 39   java.nio.ByteBuffer::position (6 bytes)   inline (hot)
                                        @ 2   java.nio.ByteBuffer::position (8 bytes)   inline (hot)
                                          @ 2   java.nio.Buffer::position (55 bytes)   inline (hot)
                                    @ 15   java.nio.ByteOrder::nativeOrder (4 bytes)   inline (hot)
                              @ 8   java.nio.HeapByteBuffer::getShort (26 bytes)   inline (hot)
                                @ 11   java.nio.Buffer::checkIndex (24 bytes)   inline (hot)
                                @ 15   java.nio.HeapByteBuffer::byteOffset (7 bytes)   inline (hot)
                                @ 22   jdk.internal.misc.Unsafe::getShortUnaligned (12 bytes)   inline (hot)
                                  @ 5   jdk.internal.misc.Unsafe::getShortUnaligned (33 bytes)   (intrinsic)
                                  @ 8   jdk.internal.misc.Unsafe::convEndian (16 bytes)   inline (hot)
                                    @ 12   java.lang.Short::reverseBytes (14 bytes)   (intrinsic)

I also attached a version of the test (Test3.java) that fails:

java Test3.java
52    1     n       jdk.internal.vm.Continuation::enterSpecial (native)   (static)
52    2     n       jdk.internal.vm.Continuation::doYield (native)   (static)
66    3    b        Test3::test (12 bytes)
                            @ 2   java.nio.ByteBuffer::allocate (20 bytes)   inline (hot)
                              @ 16   java.nio.HeapByteBuffer::<init> (21 bytes)   failed to inline: unloaded signature classes
                            @ 8   java.nio.HeapByteBuffer::getShort (30 bytes)   inline (hot)
                              @ 4   java.nio.Buffer::session (20 bytes)   failed to inline: unloaded signature classes
                              @ 15   java.nio.Buffer::checkIndex (16 bytes)   force inline by annotation
                                @ 12   jdk.internal.util.Preconditions::checkIndex (18 bytes)   (intrinsic)
                              @ 19   java.nio.HeapByteBuffer::byteOffset (7 bytes)   inline (hot)
               !              @ 26   jdk.internal.misc.ScopedMemoryAccess::getShortUnaligned (18 bytes)   failed to inline: unloaded signature classes

Exception in thread "main" java.lang.RuntimeException: Test failed
	at Test3.runInSeparateVM(Test3.java:36)
	at Test3.main(Test3.java:52)

Comments
[~vlivanov] had a quick look at this: java.nio.ByteBuffer::allocate calls java.nio.HeapByteBuffer::<init> but MemorySegment is not loaded and therefore the call is not inlined: https://github.com/openjdk/jdk/blob/4d932d615c78f45516a4f136398e7610546065a6/src/java.base/share/classes/java/nio/X-Buffer.java.template#L394 https://github.com/openjdk/jdk/blob/4d932d615c78f45516a4f136398e7610546065a6/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template#L70 Instead, C2 could simply assert that the argument is null (which holds in this case). Vladimir said: "inlining failure manifests as a considerable loss of performance in this particular case. The bug itself may be used as a justification to improve inlining support when it comes to unloaded signature classes."
03-04-2024

ILW = Inlining fails, memory access API methods when C2 compiled, no workaround = MLH = P4
28-03-2024