Skip to content

Instantly share code, notes, and snippets.

@rednaxelafx
Created June 25, 2012 09:55
Show Gist options
  • Save rednaxelafx/2987732 to your computer and use it in GitHub Desktop.
Save rednaxelafx/2987732 to your computer and use it in GitHub Desktop.
+PrintCompilation
-BackgroundCompilation
PrintIdealGraphLevel=4
PrintIdealGraphFile=ideal.xml
CICompilerCount=1
-TieredCompilation
CompileCommand=exclude,Main,logError
$ java -version
CompilerOracle: exclude Main.logError
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-jvmg, mixed mode)
$ java Main
CompilerOracle: exclude Main.logError
Java Version: 24.0-b14-internal-jvmg
try OSR compilation
1060 1 % b Main::foo @ 11 (98 bytes)
Failed at iteration: 241
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
try standard compilation
2449 1 b Main::foo (98 bytes)
Failed at iteration: 17
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
Failed at iteration: 0
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
$
public class Main {
private static void logError(int i, String actual) {
final String expected = "test" + "test" + "test" + "test";
System.out.print("Failed at iteration: ");
System.out.println(i);
System.out.print("Length mismatch: ");
System.out.print(actual.length());
System.out.print(" <> ");
System.out.println(expected.length());
System.out.println("Expected: \n\"" + expected + "\"");
System.out.print("Actual: \"");
System.out.print(actual);
System.out.println("\"");
}
private static void foo() {
for (int i = 0; i < 30000; i++) {
// this empty for-loop is required to reproduce this bug
for (int j = 0; j < 60; j++) {
// do nothing
}
{
String s = "test";
int len = s.length();
s = new StringBuilder(String.valueOf(s)).append(s).toString();
len = len + len;
s = new StringBuilder(String.valueOf(s)).append(s).toString();
len = len + len;
if (s.length() != len) {
logError(i, s);
return;
}
}
}
}
public static void main(String[] args) throws Exception {
System.out.println("Java Version: " + System.getProperty("java.vm.version"));
System.out.println("try OSR compilation");
foo();
System.out.println("try standard compilation");
foo();
foo();
}
}

During bytecode parsing,

  • line 29: len = len + len;, we can see String.length() constant-folded

  • bytecode 52 iadd: 271 AddI(141 ConI(#4), 141 ConI(#4))

  • line 32: len = len + len;

  • bytecode 75 iadd: 403 AddI(272 ConI(#8), 272 ConI(#8))

  • line 34: if (s.length() != len) {, variable len is still constant-folded into 16

  • bytecode 82 if_icmpeq: 448 If(447 Bool(446 CmpI(445 LoadRange(444 AddP(443 CastPP(430 DecodeN(429 LoadN(428 AddP(424 CastPP(390 Proj(372 CallStaticJava(java.lang.StringBuilder::toString)).result)).value)))).length), 404 ConI(#16)))[ne]))


During Iterative GVN 1,

< int:>=0	< 445	LoadRange	=== _ _ _  [[]]   [24200445]
> int:0..max-2	 767	ConI	===  0  [[ 551  446 ]]  #int:12

With this replacement, the predicate at line 34 is folded into if (12 != 16) {, which is then also folded out.


After optimize finished,

  • 454 CallStaticJava(Main::logError) is the place to start tracking things down
CompilerOracle: exclude Main.logError
Java Version: 24.0-b14-internal-jvmg
try OSR compilation
1046 1 % b Main::foo @ 11 (98 bytes)
considering toString call in Main::foo @ bci:69
fusion would succeed (1 0) for Main::foo @ bci:54
303 Phi === 289 285 288 [[ 307 452 ]] #java/lang/String:NotNull:exact * Oop:java/lang/String:NotNull:exact * !jvms: String::valueOf @ bci:13 Main::foo @ bci:59
228 Proj === 209 [[ 324 244 307 279 285 452 ]] #5 Oop:java/lang/String:exact * !jvms: Main::foo @ bci:46
0--> 324 CallStaticJava === 314 319 320 8 1 ( 261 228 76 1 242 ) [[ 325 326 327 329 338 337 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:66 !jvms: Main::foo @ bci:66
1--> 342 CallStaticJava === 348 337 338 8 1 ( 355 76 1 242 ) [[ 356 357 358 360 369 368 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:69 !jvms: Main::foo @ bci:69
2--> 307 CallStaticJava === 289 255 274 8 1 ( 261 303 76 228 242 261 ) [[ 308 309 310 320 319 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:62 !jvms: Main::foo @ bci:62
3--> 244 Allocate === 231 236 237 8 1 ( 113 112 20 1 76 228 242 ) [[ 245 246 247 254 255 256 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:54 !jvms: Main::foo @ bci:54
4--> 348 IfTrue === 347 [[ 342 355 ]] #1 !jvms: Main::foo @ bci:69
considering toString call in Main::foo @ bci:46
fusion would succeed (1 0) for Main::foo @ bci:31
91 ConP === 0 [[ 187 170 170 115 453 453 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
91 ConP === 0 [[ 187 170 170 115 453 453 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
0--> 187 CallStaticJava === 177 182 183 8 1 ( 132 91 76 1 110 ) [[ 188 189 190 192 201 200 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:43 !jvms: Main::foo @ bci:43
1--> 209 CallStaticJava === 215 200 201 8 1 ( 223 76 1 110 ) [[ 224 225 226 228 237 236 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:46 !jvms: Main::foo @ bci:46
2--> 170 CallStaticJava === 129 126 140 8 1 ( 132 91 76 91 110 132 ) [[ 171 172 173 183 182 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:39 !jvms: Main::foo @ bci:39
3--> 115 Allocate === 85 73 97 8 1 ( 113 112 20 1 76 91 110 ) [[ 116 117 118 125 126 127 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:31 !jvms: Main::foo @ bci:31
4--> 215 IfTrue === 214 [[ 209 223 ]] #1 !jvms: Main::foo @ bci:46
considering stacked concats
fusion would succeed (2 0) for Main::foo @ bci:31
303 Phi === 289 285 288 [[ 307 452 454 ]] #java/lang/String:NotNull:exact * Oop:java/lang/String:NotNull:exact * !jvms: String::valueOf @ bci:13 Main::foo @ bci:59
91 ConP === 0 [[ 187 170 170 115 453 453 454 454 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
91 ConP === 0 [[ 187 170 170 115 453 453 454 454 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
0--> 324 CallStaticJava === 314 319 320 8 1 ( 261 228 76 1 242 ) [[ 325 326 327 329 338 337 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:66 !jvms: Main::foo @ bci:66
1--> 342 CallStaticJava === 348 337 338 8 1 ( 355 76 1 242 ) [[ 356 357 358 360 369 368 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:69 !jvms: Main::foo @ bci:69
2--> 307 CallStaticJava === 289 255 274 8 1 ( 261 303 76 228 242 261 ) [[ 308 309 310 320 319 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:62 !jvms: Main::foo @ bci:62
3--> 244 Allocate === 231 236 237 8 1 ( 113 112 20 1 76 228 242 ) [[ 245 246 247 254 255 256 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:54 !jvms: Main::foo @ bci:54
4--> 187 CallStaticJava === 177 182 183 8 1 ( 132 91 76 1 110 ) [[ 188 189 190 192 201 200 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:43 !jvms: Main::foo @ bci:43
5--> 209 CallStaticJava === 215 200 201 8 1 ( 223 76 1 110 ) [[ 224 225 226 228 237 236 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:46 !jvms: Main::foo @ bci:46
6--> 170 CallStaticJava === 129 126 140 8 1 ( 132 91 76 91 110 132 ) [[ 171 172 173 183 182 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:39 !jvms: Main::foo @ bci:39
7--> 115 Allocate === 85 73 97 8 1 ( 113 112 20 1 76 91 110 ) [[ 116 117 118 125 126 127 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:31 !jvms: Main::foo @ bci:31
8--> 348 IfTrue === 347 [[ 342 355 ]] #1 !jvms: Main::foo @ bci:69
9--> 215 IfTrue === 214 [[ 209 223 ]] #1 !jvms: Main::foo @ bci:46
stacking would succeed
Failed at iteration: 241
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
try standard compilation
2455 1 b Main::foo (98 bytes)
considering toString call in Main::foo @ bci:69
fusion would succeed (1 0) for Main::foo @ bci:54
333 Phi === 319 315 318 [[ 337 482 ]] #java/lang/String:NotNull:exact * Oop:java/lang/String:NotNull:exact * !jvms: String::valueOf @ bci:13 Main::foo @ bci:59
258 Proj === 239 [[ 354 274 337 309 315 482 ]] #5 Oop:java/lang/String:exact * !jvms: Main::foo @ bci:46
0--> 354 CallStaticJava === 344 349 350 8 1 ( 291 258 64 1 272 ) [[ 355 356 357 359 368 367 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:66 !jvms: Main::foo @ bci:66
1--> 372 CallStaticJava === 378 367 368 8 1 ( 385 64 1 272 ) [[ 386 387 388 390 399 398 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:69 !jvms: Main::foo @ bci:69
2--> 337 CallStaticJava === 319 285 304 8 1 ( 291 333 64 258 272 291 ) [[ 338 339 340 350 349 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:62 !jvms: Main::foo @ bci:62
3--> 274 Allocate === 261 266 267 8 1 ( 143 142 20 1 64 258 272 ) [[ 275 276 277 284 285 286 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:54 !jvms: Main::foo @ bci:54
4--> 378 IfTrue === 377 [[ 372 385 ]] #1 !jvms: Main::foo @ bci:69
considering toString call in Main::foo @ bci:46
fusion would succeed (1 0) for Main::foo @ bci:31
121 ConP === 0 [[ 217 200 200 145 483 483 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
121 ConP === 0 [[ 217 200 200 145 483 483 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
0--> 217 CallStaticJava === 207 212 213 8 1 ( 162 121 64 1 141 ) [[ 218 219 220 222 231 230 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:43 !jvms: Main::foo @ bci:43
1--> 239 CallStaticJava === 245 230 231 8 1 ( 253 64 1 141 ) [[ 254 255 256 258 267 266 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:46 !jvms: Main::foo @ bci:46
2--> 200 CallStaticJava === 159 156 170 8 1 ( 162 121 64 121 141 162 ) [[ 201 202 203 213 212 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:39 !jvms: Main::foo @ bci:39
3--> 145 Allocate === 117 105 106 8 1 ( 143 142 20 1 64 121 141 ) [[ 146 147 148 155 156 157 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:31 !jvms: Main::foo @ bci:31
4--> 245 IfTrue === 244 [[ 239 253 ]] #1 !jvms: Main::foo @ bci:46
considering stacked concats
fusion would succeed (2 0) for Main::foo @ bci:31
333 Phi === 319 315 318 [[ 337 482 484 ]] #java/lang/String:NotNull:exact * Oop:java/lang/String:NotNull:exact * !jvms: String::valueOf @ bci:13 Main::foo @ bci:59
121 ConP === 0 [[ 217 200 200 145 483 483 484 484 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
121 ConP === 0 [[ 217 200 200 145 483 483 484 484 ]] #java/lang/String:exact * Oop:java/lang/String:exact *
0--> 354 CallStaticJava === 344 349 350 8 1 ( 291 258 64 1 272 ) [[ 355 356 357 359 368 367 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:66 !jvms: Main::foo @ bci:66
1--> 372 CallStaticJava === 378 367 368 8 1 ( 385 64 1 272 ) [[ 386 387 388 390 399 398 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:69 !jvms: Main::foo @ bci:69
2--> 337 CallStaticJava === 319 285 304 8 1 ( 291 333 64 258 272 291 ) [[ 338 339 340 350 349 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:62 !jvms: Main::foo @ bci:62
3--> 274 Allocate === 261 266 267 8 1 ( 143 142 20 1 64 258 272 ) [[ 275 276 277 284 285 286 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:54 !jvms: Main::foo @ bci:54
4--> 217 CallStaticJava === 207 212 213 8 1 ( 162 121 64 1 141 ) [[ 218 219 220 222 231 230 ]] # Static java.lang.StringBuilder::append java/lang/StringBuilder:exact * ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:43 !jvms: Main::foo @ bci:43
5--> 239 CallStaticJava === 245 230 231 8 1 ( 253 64 1 141 ) [[ 254 255 256 258 267 266 ]] # Static java.lang.StringBuilder::toString java/lang/String:exact * ( java/lang/StringBuilder:NotNull:exact * ) Main::foo @ bci:46 !jvms: Main::foo @ bci:46
6--> 200 CallStaticJava === 159 156 170 8 1 ( 162 121 64 121 141 162 ) [[ 201 202 203 213 212 ]] # Static java.lang.StringBuilder::<init> void ( java/lang/StringBuilder:NotNull:exact *, java/lang/String:exact * ) Main::foo @ bci:39 !jvms: Main::foo @ bci:39
7--> 145 Allocate === 117 105 106 8 1 ( 143 142 20 1 64 121 141 ) [[ 146 147 148 155 156 157 ]] rawptr:NotNull ( int:>=0, java/lang/Object:NotNull *, bool, int ) Main::foo @ bci:31 !jvms: Main::foo @ bci:31
8--> 378 IfTrue === 377 [[ 372 385 ]] #1 !jvms: Main::foo @ bci:69
9--> 245 IfTrue === 244 [[ 239 253 ]] #1 !jvms: Main::foo @ bci:46
stacking would succeed
Failed at iteration: 17
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
Failed at iteration: 0
Length mismatch: 12 <> 16
Expected:
"testtesttesttest"
Actual: "nulltesttest"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment