openj9 icon indicating copy to clipboard operation
openj9 copied to clipboard

Recognize StringUTF16.indexOfUnsafe([BI[BII)I

Open knn-k opened this issue 6 months ago • 6 comments

This commit changes the JIT compiler to recognize the method StringUTF16.indexOfUnsafe([BI[BII)I instead of StringUTF16.indexOf([BI[BII)I.

It improves the performance of String.indexOf(String) on Z with Java 17+.

knn-k avatar Jun 06 '25 08:06 knn-k

Jenkins test sanity zlinux jdk11,jdk17

knn-k avatar Jun 06 '25 08:06 knn-k

Jenkins compile amac jdk17

knn-k avatar Jun 06 '25 10:06 knn-k

There are methods (1) String.indexOf(String) and (2) String.indexOf(String, int). When the Strings are in UTF-16, these methods call StringUTF16 methods in Java 17+ as shown below:

(1)
↓
StringUTF16.indexOf([B[B)I
↓
StringUTF16.indexOfUnsafe([BI[BII)I

(2)
↓
String.indexOf([BBIString;I)I
↓
StringUTF16.indexOf([BI[BII)I
↓
StringUTF16.indexOfUnsafe([BI[BII)I

Existing Z codegen recognizes and inlines StringUTF16.indexOf([BI[BII)I, but it appears in the call path of (2) only. It does not accelerate the single parameter String.indexOf(String). By recognizing the StringUTF16 method indexOfUnsafe([BI[BII)I instead of indexOf([BI[BII)I, both (1) and (2) are accelerated. This is the background of this PR.

For Java 11, both (1) and (2) are accelerated because (1) calls (2).

(1)
↓
(2)
↓
String.indexOf([BBIString;I)I
↓
StringUTF16.indexOf([BI[BII)I
↓
StringUTF16.indexOfUnsafe([BI[BII)I

knn-k avatar Jun 06 '25 23:06 knn-k

@r30shah Can I ask you to look at this? It changes Z codegen. Thanks.

knn-k avatar Jun 09 '25 00:06 knn-k

@knn-k Were you able to get some runs with your change for the case String.indexOf(String, int) as well ? With this change - We would have to inline other calls from the indexOf([BI[BII)I as well - that may increase pathlength - I wanted to understand the impact on that case.

[1]. https://github.com/ibmruntimes/openj9-openjdk-jdk21/blob/cd11ae446eeb94d5c03cad006f291c22f85ebbf7/src/java.base/share/classes/java/lang/StringUTF16.java#L449-L453

r30shah avatar Jun 09 '25 13:06 r30shah

Jenkins test sanity zlinux jdk11,jdk17

knn-k avatar Jun 11 '25 06:06 knn-k

Jenkins test sanity xlinux,zlinux jdk11,jdk17

knn-k avatar Aug 01 '25 08:08 knn-k

@r30shah Sorry for my late response to your question. You don't need to worry about checkBoundsBeginEnd() and checkBoundsBeginEnd() called by StringUTF16.indexOf([BI[BII)I, because this PR just adds recognition of StringUTF16.indexOfUnsafe([BI[BII)I, not replacing StringUTF16.indexOf([BI[BII)I by that. In the case of String.indexOf(String, int) with Java 17+, StringUTF16.indexOf([BI[BII)I in inlined in String.indexOf([BBILjava/lang/String;I)I as an intrinsic, with or without this PR. I made sure with JIT trace files.

(1)
↓
StringUTF16.indexOf([B[B)I
↓
StringUTF16.indexOfUnsafe([BI[BII)I // recognized and inlined as an intrinsic with this PR

(2)
↓
String.indexOf([BBIString;I)I
↓
StringUTF16.indexOf([BI[BII)I // recognized and inlined as an intrinsic with or without this PR

knn-k avatar Aug 01 '25 10:08 knn-k

I rebased to add the recognition of indexOfUnsafe([BI[BII)I to the x86 platform, and updated the commit message.

knn-k avatar Aug 01 '25 10:08 knn-k