From fed7025b350004b7e48f5879d942485297ddd590 Mon Sep 17 00:00:00 2001 From: Henry Zongaro Date: Fri, 23 Aug 2024 10:35:26 -0700 Subject: [PATCH] Adjust bound for out-of-line call to StringUTF16.toBytes Recognized Call Transformer generates IL that implements an inline version of StringUTF16.toBytes for values in the range [0,0x3fffffff], and that falls back to calling the Java implementation otherwise. In JDK levels up to 22, the Java implementation throws an OutOfMemoryException if the length is greater than 0x3fffffff. JDK Level 23, however, was changed to throw an OutOfMemoryException if the length is greater than or equal to 0x3fffffff. This change alters the IL that Recognized Call Transformer generates to fall back to the Java implementation if the length is greater than or equal to 0x3fffffff, so that it will work with all JDK levels. Signed-off-by: Henry Zongaro --- .../optimizer/J9RecognizedCallTransformer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/runtime/compiler/optimizer/J9RecognizedCallTransformer.cpp b/runtime/compiler/optimizer/J9RecognizedCallTransformer.cpp index a028e5c53ab..ca4274de589 100644 --- a/runtime/compiler/optimizer/J9RecognizedCallTransformer.cpp +++ b/runtime/compiler/optimizer/J9RecognizedCallTransformer.cpp @@ -287,10 +287,11 @@ void J9::RecognizedCallTransformer::process_java_lang_StringUTF16_toBytes(TR::Tr // The implementation of java.lang.StringUTF16.toBytes(char[],int,int) will // throw a NegativeArraySizeException or OutOfMemoryError if the specified - // length is outside the range [0,0x3fffffff]. In order to avoid deciding - // which to throw in the IL, fall back to the out-of-line call if the length - // is negative or too great. Otherwise, create the byte array and copy the - // input char array to it with java.lang.String.decompressedArrayCopy + // length is outside the range [0,0x3fffffff] or [0,0x3ffffffe], depending on + // the JDK level. In order to avoid deciding which to throw in the IL, fall + // back to the out-of-line call if the length is negative or greater than or + // equal to 0x3fffffff. Otherwise, create the byte array and copy the input + // char array to it with java.lang.String.decompressedArrayCopy // // Before: // @@ -312,7 +313,7 @@ void J9::RecognizedCallTransformer::process_java_lang_StringUTF16_toBytes(TR::Tr // | iload off | // | istore lenTemp | // | iload len | - // | ifiucmpgt --> fallbackPathBlock -----------------+ + // | ifiucmpge --> fallbackPathBlock -----------------+ // | iload lenTemp | | // | iconst 0x3fffffff | | // +--------------------+-------------------+ | @@ -355,7 +356,7 @@ void J9::RecognizedCallTransformer::process_java_lang_StringUTF16_toBytes(TR::Tr // +----------------------------------------+ // TR::Node *upperBoundConstNode = TR::Node::iconst(node, TR::getMaxSigned() >> 1); - TR::Node *ifCmpNode = TR::Node::createif(TR::ifiucmpgt, lenNode, upperBoundConstNode); + TR::Node *ifCmpNode = TR::Node::createif(TR::ifiucmpge, lenNode, upperBoundConstNode); TR::TreeTop *ifCmpTreeTop = TR::TreeTop::create(comp(), treetop->getPrevTreeTop(), ifCmpNode); // Create temporary variable that will be used to hold result @@ -410,7 +411,7 @@ void J9::RecognizedCallTransformer::process_java_lang_StringUTF16_toBytes(TR::Tr TR::Node::recreate(node, comp()->il.opCodeForDirectLoad(resultDataType)); node->setSymbolReference(resultSymRef); - // Split the current block right after the ifuicmpgt + // Split the current block right after the ifiucmpge TR::Block *ifCmpBlock = ifCmpTreeTop->getEnclosingBlock(); // Then split the inline version of the code into its own block @@ -429,7 +430,7 @@ void J9::RecognizedCallTransformer::process_java_lang_StringUTF16_toBytes(TR::Tr fallThroughPathBlock->getExit()->insertBefore(gotoTree); // Now we have fall-through block, fallback block and tail/merge block. - // Set the ifuicmp's destination to the fallback block and update the CFG as well. + // Set the ifiucmp's destination to the fallback block and update the CFG as well. ifCmpNode->setBranchDestination(fallbackPathBlock->getEntry()); cfg->addEdge(ifCmpBlock, fallbackPathBlock); cfg->addEdge(fallThroughPathBlock, tailBlock);