Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created June 26, 2012 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rednaxelafx/2994300 to your computer and use it in GitHub Desktop.
Save rednaxelafx/2994300 to your computer and use it in GitHub Desktop.
OptimizeStringConcat in HS24 won't optimize a StringBuilder with extra uses
$ java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b43)
OpenJDK 64-Bit Server VM (build 24.0-b14-internal-fastdebug, mixed mode)
$ java -XX:-TieredCompilation -XX:+PrintCompilation -XX:+PrintOptimizeStringConcat -XX:CompileCommand='exclude,ExtraUse,main' ExtraUse
CompilerOracle: exclude ExtraUse.main
281 1 n java.lang.System::arraycopy (0 bytes) (static)
286 2 java.lang.Object::<init> (1 bytes)
289 3 java.lang.String::length (6 bytes)
297 4 java.lang.AbstractStringBuilder::ensureCapacityInternal (16 bytes)
297 5 java.lang.AbstractStringBuilder::append (48 bytes)
299 6 java.lang.String::getChars (62 bytes)
302 7 java.lang.StringBuilder::append (8 bytes)
311 8 java.lang.Math::min (11 bytes)
312 9 java.lang.String::<init> (67 bytes)
316 10 java.util.Arrays::copyOfRange (63 bytes)
321 11 java.lang.AbstractStringBuilder::<init> (12 bytes)
324 12 java.lang.StringBuilder::<init> (7 bytes)
### Excluding compile: static ExtraUse::main
326 13 java.lang.StringBuilder::toString (17 bytes)
334 14 ExtraUse::foo (33 bytes)
considering toString call in ExtraUse::foo @ bci:26
extra uses for result:
68 Proj === 63 [[ 125 102 94 113 ]] #5 Oop:java/lang/StringBuilder:exact * !jvms: ExtraUse::foo @ bci:11
102 EncodeP === _ 68 [[ 103 ]] #narrowoop: java/lang/StringBuilder:exact * !jvms: ExtraUse::foo @ bci:17
$
public class ExtraUse {
public static void foo(Pair p) {
String s = "testing";
StringBuilder sb = new StringBuilder().append(s);
p.first = sb;
p.second = sb.append(s).toString();
}
public static void main(String[] args) throws Exception {
Pair p = new Pair();
for (int i = 0; i < 20000; i++) {
foo(p);
}
System.in.read();
}
}
class Pair {
Object first;
Object second;
}
$ javap -verbose -private ExtraUse
Compiled from "ExtraUse.java"
public class ExtraUse extends java.lang.Object
SourceFile: "ExtraUse.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #15.#43; // java/lang/Object."<init>":()V
const #2 = String #44; // testing
const #3 = class #45; // java/lang/StringBuilder
const #4 = Method #3.#43; // java/lang/StringBuilder."<init>":()V
const #5 = Method #3.#46; // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
const #6 = Field #9.#47; // Pair.first:Ljava/lang/Object;
const #7 = Method #3.#48; // java/lang/StringBuilder.toString:()Ljava/lang/String;
const #8 = Field #9.#49; // Pair.second:Ljava/lang/Object;
const #9 = class #50; // Pair
const #10 = Method #9.#43; // Pair."<init>":()V
const #11 = Method #14.#51; // ExtraUse.foo:(LPair;)V
const #12 = Field #52.#53; // java/lang/System.in:Ljava/io/InputStream;
const #13 = Method #54.#55; // java/io/InputStream.read:()I
const #14 = class #56; // ExtraUse
const #15 = class #57; // java/lang/Object
const #16 = Asciz <init>;
const #17 = Asciz ()V;
const #18 = Asciz Code;
const #19 = Asciz LineNumberTable;
const #20 = Asciz LocalVariableTable;
const #21 = Asciz this;
const #22 = Asciz LExtraUse;;
const #23 = Asciz foo;
const #24 = Asciz (LPair;)V;
const #25 = Asciz p;
const #26 = Asciz LPair;;
const #27 = Asciz s;
const #28 = Asciz Ljava/lang/String;;
const #29 = Asciz sb;
const #30 = Asciz Ljava/lang/StringBuilder;;
const #31 = Asciz main;
const #32 = Asciz ([Ljava/lang/String;)V;
const #33 = Asciz i;
const #34 = Asciz I;
const #35 = Asciz args;
const #36 = Asciz [Ljava/lang/String;;
const #37 = Asciz StackMapTable;
const #38 = class #50; // Pair
const #39 = Asciz Exceptions;
const #40 = class #58; // java/lang/Exception
const #41 = Asciz SourceFile;
const #42 = Asciz ExtraUse.java;
const #43 = NameAndType #16:#17;// "<init>":()V
const #44 = Asciz testing;
const #45 = Asciz java/lang/StringBuilder;
const #46 = NameAndType #59:#60;// append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
const #47 = NameAndType #61:#62;// first:Ljava/lang/Object;
const #48 = NameAndType #63:#64;// toString:()Ljava/lang/String;
const #49 = NameAndType #65:#62;// second:Ljava/lang/Object;
const #50 = Asciz Pair;
const #51 = NameAndType #23:#24;// foo:(LPair;)V
const #52 = class #66; // java/lang/System
const #53 = NameAndType #67:#68;// in:Ljava/io/InputStream;
const #54 = class #69; // java/io/InputStream
const #55 = NameAndType #70:#71;// read:()I
const #56 = Asciz ExtraUse;
const #57 = Asciz java/lang/Object;
const #58 = Asciz java/lang/Exception;
const #59 = Asciz append;
const #60 = Asciz (Ljava/lang/String;)Ljava/lang/StringBuilder;;
const #61 = Asciz first;
const #62 = Asciz Ljava/lang/Object;;
const #63 = Asciz toString;
const #64 = Asciz ()Ljava/lang/String;;
const #65 = Asciz second;
const #66 = Asciz java/lang/System;
const #67 = Asciz in;
const #68 = Asciz Ljava/io/InputStream;;
const #69 = Asciz java/io/InputStream;
const #70 = Asciz read;
const #71 = Asciz ()I;
{
public ExtraUse();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LExtraUse;
public static void foo(Pair);
Code:
Stack=3, Locals=3, Args_size=1
0: ldc #2; //String testing
2: astore_1
3: new #3; //class java/lang/StringBuilder
6: dup
7: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: astore_2
15: aload_0
16: aload_2
17: putfield #6; //Field Pair.first:Ljava/lang/Object;
20: aload_0
21: aload_2
22: aload_1
23: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: putfield #8; //Field Pair.second:Ljava/lang/Object;
32: return
LineNumberTable:
line 3: 0
line 4: 3
line 5: 15
line 6: 20
line 7: 32
LocalVariableTable:
Start Length Slot Name Signature
0 33 0 p LPair;
3 30 1 s Ljava/lang/String;
15 18 2 sb Ljava/lang/StringBuilder;
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
Stack=2, Locals=3, Args_size=1
0: new #9; //class Pair
3: dup
4: invokespecial #10; //Method Pair."<init>":()V
7: astore_1
8: iconst_0
9: istore_2
10: iload_2
11: sipush 20000
14: if_icmpge 27
17: aload_1
18: invokestatic #11; //Method foo:(LPair;)V
21: iinc 2, 1
24: goto 10
27: getstatic #12; //Field java/lang/System.in:Ljava/io/InputStream;
30: invokevirtual #13; //Method java/io/InputStream.read:()I
33: pop
34: return
LineNumberTable:
line 10: 0
line 11: 8
line 12: 17
line 11: 21
line 14: 27
line 15: 34
LocalVariableTable:
Start Length Slot Name Signature
10 17 2 i I
0 35 0 args [Ljava/lang/String;
8 27 1 p LPair;
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 10
locals = [ class Pair, int ]
frame_type = 250 /* chop */
offset_delta = 16
Exceptions:
throws java.lang.Exception
}
$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment