publicclass Main { publicstaticvoid main(String[] args) throws Exception { Class<?> c = Class.forName("Test");
// Case 1: Release Pattern (StringBuilder(String)) // This is the classic string concatenation pattern that should be optimized. // A new StringBuilder is created with a string literal and immediately appended to.
Method mRelease = c.getMethod("testRelease", String.class);
String resultRelease = (String) mRelease.invoke(null, "World"); if (!"Hello World".equals(resultRelease)) { thrownew Error("testRelease failed: " + resultRelease);
}
// Case 2: Debug Pattern (StringBuilder() -> append(String)) // Similar to the `d8 --release` pattern, but starting with an empty StringBuilder. // This should also be optimized.
Method mDebug = c.getMethod("testDebug", String.class);
String resultDebug = (String) mDebug.invoke(null, "World"); if (!"Hello World".equals(resultDebug)) { thrownew Error("testDebug failed: " + resultDebug);
}
// Case 3: Escape/Safety Check // Ensures that if the StringBuilder is passed to an unknown method (`$noinline$consume`) // before the final `toString()` call, the optimization is aborted. This is because // the compiler cannot prove that the `consume` method doesn't modify the StringBuilder // in an unexpected way.
Method mEscape = c.getMethod("testEscape", String.class);
String resultEscape = (String) mEscape.invoke(null, "World"); if (!"StartMiddleWorldEnd".equals(resultEscape)) { thrownew Error("testEscape failed: " + resultEscape);
}
// Case 4: String argument // Tests the case where the constructor is called with a String argument that is not // a `const-string` (HLoadString). The optimization should not apply because the // argument could be null, and the `StringBuilder` constructor would throw an NPE.
Method mStringArg = c.getMethod("testStringArgument", String.class, String.class);
String resultStringArg = (String) mStringArg.invoke(null, "Hello ", "World"); if (!"Hello World".equals(resultStringArg)) { thrownew Error("testStringArgument failed: " + resultStringArg);
} try {
mStringArg.invoke(null, null, "World"); thrownew Error("testStringArgument should have thrown NPE");
} catch (java.lang.reflect.InvocationTargetException e) { if (!(e.getCause() instanceof NullPointerException)) { thrownew Error("testStringArgument threw wrong exception: " + e.getCause());
}
}
// Case 5: Null-checked String argument // Similar to Case 4, but the String argument is null-checked by calling `.length()` // before the StringBuilder is constructed. This allows the compiler to prove that // the argument is not null, and the optimization should be applied.
Method mStringArgNC =
c.getMethod("testStringArgumentNullChecked", String.class, String.class);
String resultStringArgNC = (String) mStringArgNC.invoke(null, "Hello ", "World"); if (!"Hello World".equals(resultStringArgNC)) { thrownew Error("testStringArgumentNullChecked failed: " + resultStringArgNC);
} try {
mStringArgNC.invoke(null, null, "World"); thrownew Error("testStringArgumentNullChecked should have thrown NPE");
} catch (java.lang.reflect.InvocationTargetException e) { if (!(e.getCause() instanceof NullPointerException)) { thrownew Error( "testStringArgumentNullChecked threw wrong exception: " + e.getCause());
}
}
// Case 6: const-string as CharSequence // Tests that the optimization works when a `const-string` is passed to an `append` // method that takes a `CharSequence`. The compiler should be able to identify that // the CharSequence is a String and apply the optimization.
Method mConstStringAsCharSequence =
c.getMethod("testConstStringAsCharSequence", String.class);
String resultConstStringAsCharSequence =
(String) mConstStringAsCharSequence.invoke(null, "World"); if (!"Hello World".equals(resultConstStringAsCharSequence)) { thrownew Error( "testConstStringAsCharSequence failed: " + resultConstStringAsCharSequence);
}
// Case 7: CharSequence that is not known to be a String // Tests that the optimization is NOT applied when `append(CharSequence)` is called // with a CharSequence that is not known to be a String at compile time. In this // case, `getCharSequence()` is `$noinline$` and returns a string literal but it's // seen as an opaque `CharSequence` that the compiler does not see as an actual `String`. // The call to `getCharSequence` is placed before the StringBuilder constructor // so that it's not in the `ChaseSequence`'s environment.
Method mUnknownCharSequence = c.getMethod("testUnknownCharSequence", String.class);
String resultUnknownCharSequence = (String) mUnknownCharSequence.invoke(null, "World"); if (!"Hello World".equals(resultUnknownCharSequence)) { thrownew Error("testUnknownCharSequence failed: " + resultUnknownCharSequence);
}
// Case 8: CharSequence that is not known to be a String passed to constructor
Method mUnknownCharSequenceConstructor =
c.getMethod("testUnknownCharSequenceConstructor", String.class);
String resultUnknownCharSequenceConstructor =
(String) mUnknownCharSequenceConstructor.invoke(null, "World"); if (!"Hello World".equals(resultUnknownCharSequenceConstructor)) { thrownew Error("testUnknownCharSequenceConstructor failed: " +
resultUnknownCharSequenceConstructor);
}
// Case 10: StringBuilder(int) constructor // Tests that the optimization works when the StringBuilder is created with a capacity // specified as an int literal.
Method mCapacity = c.getMethod("testCapacity", String.class);
String resultCapacity = (String) mCapacity.invoke(null, "World"); if (!"World".equals(resultCapacity)) { thrownew Error("testCapacity failed: " + resultCapacity);
}
System.out.println("passed");
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.