Created
June 26, 2012 07:41
-
-
Save rednaxelafx/2994161 to your computer and use it in GitHub Desktop.
OptimizeStringConcat in HS24 won't optimize a StringBuilder with append() calls after toString()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AppendAfterToString { | |
public static void foo(Pair p) { | |
String s = "testing"; | |
StringBuilder sb = new StringBuilder(); | |
sb.append(s).append(s); | |
p.first = sb.toString(); | |
sb.append(s); | |
p.second = sb.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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ javap -verbose -private AppendAfterToString | |
Compiled from "AppendAfterToString.java" | |
public class AppendAfterToString extends java.lang.Object | |
SourceFile: "AppendAfterToString.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 = Method #3.#47; // java/lang/StringBuilder.toString:()Ljava/lang/String; | |
const #7 = Field #9.#48; // Pair.first:Ljava/lang/Object; | |
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; // AppendAfterToString.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; // AppendAfterToString | |
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 LAppendAfterToString;; | |
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 AppendAfterToString.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;// toString:()Ljava/lang/String; | |
const #48 = NameAndType #63:#64;// first:Ljava/lang/Object; | |
const #49 = NameAndType #65:#64;// 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 AppendAfterToString; | |
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 toString; | |
const #62 = Asciz ()Ljava/lang/String;; | |
const #63 = Asciz first; | |
const #64 = Asciz Ljava/lang/Object;; | |
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 AppendAfterToString(); | |
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 LAppendAfterToString; | |
public static void foo(Pair); | |
Code: | |
Stack=2, 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: astore_2 | |
11: aload_2 | |
12: aload_1 | |
13: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; | |
16: aload_1 | |
17: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; | |
20: pop | |
21: aload_0 | |
22: aload_2 | |
23: invokevirtual #6; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; | |
26: putfield #7; //Field Pair.first:Ljava/lang/Object; | |
29: aload_2 | |
30: aload_1 | |
31: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; | |
34: pop | |
35: aload_0 | |
36: aload_2 | |
37: invokevirtual #6; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; | |
40: putfield #8; //Field Pair.second:Ljava/lang/Object; | |
43: return | |
LineNumberTable: | |
line 3: 0 | |
line 4: 3 | |
line 5: 11 | |
line 6: 21 | |
line 7: 29 | |
line 8: 35 | |
line 9: 43 | |
LocalVariableTable: | |
Start Length Slot Name Signature | |
0 44 0 p LPair; | |
3 41 1 s Ljava/lang/String; | |
11 33 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 12: 0 | |
line 13: 8 | |
line 14: 17 | |
line 13: 21 | |
line 16: 27 | |
line 17: 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 | |
} | |
$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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,AppendAfterToString,main' AppendAfterToString | |
CompilerOracle: exclude AppendAfterToString.main | |
285 1 n java.lang.System::arraycopy (0 bytes) (static) | |
298 2 java.lang.Object::<init> (1 bytes) | |
313 3 java.lang.Math::min (11 bytes) | |
314 4 java.lang.String::length (6 bytes) | |
314 5 java.lang.AbstractStringBuilder::ensureCapacityInternal (16 bytes) | |
314 6 java.lang.AbstractStringBuilder::append (48 bytes) | |
324 7 java.lang.String::getChars (62 bytes) | |
328 8 java.lang.StringBuilder::append (8 bytes) | |
333 9 java.lang.String::<init> (67 bytes) | |
342 10 java.util.Arrays::copyOfRange (63 bytes) | |
343 11 java.lang.StringBuilder::toString (17 bytes) | |
358 12 java.lang.AbstractStringBuilder::<init> (12 bytes) | |
358 13 java.lang.StringBuilder::<init> (7 bytes) | |
360 14 AppendAfterToString::foo (44 bytes) | |
considering toString call in AppendAfterToString::foo @ bci:23 | |
fusion would fail for | |
26 Allocate === 5 6 7 8 1 ( 24 22 23 1 10 21 1 ) [[ 27 28 29 36 37 38 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) AppendAfterToString::foo @ bci:3 !jvms: AppendAfterToString::foo @ bci:3 | |
108 CatchProj === 107 [[ 118 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:17 | |
107 Catch === 101 102 [[ 108 109 ]] !jvms: AppendAfterToString::foo @ bci:17 | |
101 Proj === 85 [[ 107 ]] #0 !jvms: AppendAfterToString::foo @ bci:17 | |
85 CallStaticJava === 92 76 77 8 1 ( 100 21 10 21 43 ) [[ 101 102 103 114 113 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) AppendAfterToString::foo @ bci:17 !jvms: AppendAfterToString::foo @ bci:17 | |
71 CatchProj === 70 [[ 91 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:13 | |
70 Catch === 64 65 [[ 71 72 ]] !jvms: AppendAfterToString::foo @ bci:13 | |
64 Proj === 63 [[ 70 ]] #0 !jvms: AppendAfterToString::foo @ bci:13 | |
63 CallStaticJava === 53 58 59 8 1 ( 43 21 10 21 43 ) [[ 64 65 66 68 77 76 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) AppendAfterToString::foo @ bci:13 !jvms: AppendAfterToString::foo @ bci:13 | |
considering toString call in AppendAfterToString::foo @ bci:37 | |
fusion would fail for | |
26 Allocate === 5 6 7 8 1 ( 24 22 23 1 10 21 1 ) [[ 27 28 29 36 37 38 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) AppendAfterToString::foo @ bci:3 !jvms: AppendAfterToString::foo @ bci:3 | |
169 CatchProj === 168 [[ 179 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:31 | |
168 Catch === 162 163 [[ 169 170 ]] !jvms: AppendAfterToString::foo @ bci:31 | |
162 Proj === 161 [[ 168 ]] #0 !jvms: AppendAfterToString::foo @ bci:31 | |
161 CallStaticJava === 141 131 160 8 1 ( 43 21 148 1 43 ) [[ 162 163 164 175 174 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) AppendAfterToString::foo @ bci:31 !jvms: AppendAfterToString::foo @ bci:31 | |
126 CatchProj === 125 [[ 140 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:23 | |
125 Catch === 119 120 [[ 126 127 ]] !jvms: AppendAfterToString::foo @ bci:23 | |
119 Proj === 118 [[ 125 ]] #0 !jvms: AppendAfterToString::foo @ bci:23 | |
118 CallStaticJava === 108 113 114 8 1 ( 43 10 21 43 10 ) [[ 119 120 121 123 132 131 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) AppendAfterToString::foo @ bci:23 !jvms: AppendAfterToString::foo @ bci:23 | |
108 CatchProj === 107 [[ 118 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:17 | |
107 Catch === 101 102 [[ 108 109 ]] !jvms: AppendAfterToString::foo @ bci:17 | |
101 Proj === 85 [[ 107 ]] #0 !jvms: AppendAfterToString::foo @ bci:17 | |
85 CallStaticJava === 92 76 77 8 1 ( 100 21 10 21 43 ) [[ 101 102 103 114 113 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) AppendAfterToString::foo @ bci:17 !jvms: AppendAfterToString::foo @ bci:17 | |
71 CatchProj === 70 [[ 91 ]] #0@bci -1 !jvms: AppendAfterToString::foo @ bci:13 | |
70 Catch === 64 65 [[ 71 72 ]] !jvms: AppendAfterToString::foo @ bci:13 | |
64 Proj === 63 [[ 70 ]] #0 !jvms: AppendAfterToString::foo @ bci:13 | |
63 CallStaticJava === 53 58 59 8 1 ( 43 21 10 21 43 ) [[ 64 65 66 68 77 76 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) AppendAfterToString::foo @ bci:13 !jvms: AppendAfterToString::foo @ bci:13 | |
### Excluding compile: static AppendAfterToString::main | |
$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment