Skip to content

Commit 289a133

Browse files
authored
Merge pull request #19370 from ehsankianifar/SkipZeroTLHWhenStringBuilderToStringCopyArray
Skip zero init when copied array is the result of StringBuilder.toString
2 parents 9cbb1d5 + 03850dd commit 289a133

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@
173173
java_lang_String_init_String,
174174
java_lang_String_init_int_String_int_String_String,
175175
java_lang_String_init_int_int_char_boolean,
176+
java_lang_String_init_StringBuilder,
177+
java_lang_String_init_AbstractStringBuilder_Void,
176178

177179
java_lang_String_trim,
178180
java_lang_String_charAt,
@@ -1236,6 +1238,8 @@
12361238
java_util_Arrays_copyOfRange_Object1,
12371239
java_util_Arrays_copyOfRange_Object2,
12381240

1241+
java_util_Arrays_copyOfRangeByte,
1242+
12391243
sun_nio_ch_NativeThread_current,
12401244

12411245
// Multi-Tenancy Tenant Context switch methods

runtime/compiler/env/j9method.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2734,6 +2734,8 @@ void TR_ResolvedJ9Method::construct()
27342734
{x(TR::java_util_Arrays_copyOfRange_double, "copyOfRange", "([DII)[D")},
27352735
{x(TR::java_util_Arrays_copyOfRange_Object1,"copyOfRange", "([Ljava/lang/Object;II)[Ljava/lang/Object;")},
27362736
{x(TR::java_util_Arrays_copyOfRange_Object2,"copyOfRange", "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;")},
2737+
2738+
{x(TR::java_util_Arrays_copyOfRangeByte, "copyOfRangeByte", "([BII)[B")},
27372739
{ TR::unknownMethod}
27382740
};
27392741

@@ -2743,7 +2745,9 @@ void TR_ResolvedJ9Method::construct()
27432745
{x(TR::java_lang_String_init_String, "<init>", "(Ljava/lang/String;)V")},
27442746
{x(TR::java_lang_String_init_String_char, "<init>", "(Ljava/lang/String;C)V")},
27452747
{x(TR::java_lang_String_init_int_String_int_String_String, "<init>","(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;)V")},
2746-
{x(TR::java_lang_String_init_int_int_char_boolean, "<init>", "(II[CZ)V")},
2748+
{x(TR::java_lang_String_init_int_int_char_boolean, "<init>", "(II[CZ)V")},
2749+
{x(TR::java_lang_String_init_StringBuilder, "<init>", "(Ljava/lang/StringBuilder;)V")},
2750+
{x(TR::java_lang_String_init_AbstractStringBuilder_Void, "<init>", "(Ljava/lang/AbstractStringBuilder;Ljava/lang/Void;)V")},
27472751
{ TR::java_lang_String_init, 6, "<init>", (int16_t)-1, "*"},
27482752
{x(TR::java_lang_String_charAt, "charAt", "(I)C")},
27492753
{x(TR::java_lang_String_charAtInternal_I, "charAtInternal", "(I)C")},

runtime/compiler/ilgen/Walker.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6802,6 +6802,38 @@ TR_J9ByteCodeIlGenerator::genAconst_init(TR_OpaqueClassBlock *valueTypeClass, in
68026802
genFlush(0);
68036803
}
68046804

6805+
/**
6806+
* Check the call chain for the following pattern: StringBuilder.toString() -> String<init>(StringBuilder)
6807+
* -> String<init>(AbstractStringBuilder, Void) -> Arrays.copyOfRange([BII)
6808+
*
6809+
* @param comp the compilation class.
6810+
* @return true if the call chain matches the expected stack or false otherwise.
6811+
*/
6812+
static bool isCallChainFromStringBuilderToStringToArraysCopyOfRange(TR::Compilation *comp)
6813+
{
6814+
if(comp->getInlineDepth() < 4)
6815+
return false;
6816+
6817+
int32_t callerIndex = comp->getCurrentInlinedCallSite()->_byteCodeInfo.getCallerIndex();
6818+
if(comp->getInlinedResolvedMethodSymbol(callerIndex)->getRecognizedMethod() != TR::java_util_Arrays_copyOfRange_byte)
6819+
return false;
6820+
6821+
callerIndex = comp->getInlinedCallSite(callerIndex)._byteCodeInfo.getCallerIndex();
6822+
if(comp->getInlinedResolvedMethodSymbol(callerIndex)->getRecognizedMethod() != TR::java_lang_String_init_AbstractStringBuilder_Void)
6823+
return false;
6824+
6825+
callerIndex = comp->getInlinedCallSite(callerIndex)._byteCodeInfo.getCallerIndex();
6826+
if(comp->getInlinedResolvedMethodSymbol(callerIndex)->getRecognizedMethod() != TR::java_lang_String_init_StringBuilder)
6827+
return false;
6828+
6829+
callerIndex = comp->getInlinedCallSite(callerIndex)._byteCodeInfo.getCallerIndex();
6830+
TR::ResolvedMethodSymbol *caller = callerIndex > -1 ? comp->getInlinedResolvedMethodSymbol(callerIndex) : comp->getOptimizer()->getMethodSymbol();
6831+
if(caller->getRecognizedMethod() != TR::java_lang_StringBuilder_toString)
6832+
return false;
6833+
6834+
return true;
6835+
}
6836+
68056837
void
68066838
TR_J9ByteCodeIlGenerator::genNewArray(int32_t typeIndex)
68076839
{
@@ -6837,6 +6869,16 @@ TR_J9ByteCodeIlGenerator::genNewArray(int32_t typeIndex)
68376869
}
68386870
}
68396871

6872+
// Special case for handling Arrays.copyOfRangeByte when called from StringBuilder.toString method
6873+
// The call chain is: StringBuilder.toString() -> String<init>(StringBuilder) -> String<init>(AbstractStringBuilder, Void)
6874+
// -> Arrays.copyOfRange([BII) -> Arrays.copyOfRangeByte([BII)
6875+
if (!comp()->isPeekingMethod() && !generateArraylets
6876+
&& _methodSymbol->getRecognizedMethod() == TR::java_util_Arrays_copyOfRangeByte
6877+
&& isCallChainFromStringBuilderToStringToArraysCopyOfRange(comp()))
6878+
{
6879+
node->setCanSkipZeroInitialization(true);
6880+
}
6881+
68406882
bool separateInitializationFromAllocation;
68416883
switch (_methodSymbol->getRecognizedMethod())
68426884
{

0 commit comments

Comments
 (0)