--- old/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java 2016-02-01 22:45:47.205131318 +0300 +++ new/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java 2016-02-01 22:45:47.117131689 +0300 @@ -957,6 +957,22 @@ storage trimming, which defeats the purpose of exact strategies. */ + /* + The logic for this check is as follows: + + Stack before: Op: + (SB) dup, dup + (SB, SB, SB) capacity() + (int, SB, SB) swap + (SB, int, SB) toString() + (S, int, SB) length() + (int, int, SB) if_icmpeq + (SB) + + Note that it leaves the same StringBuilder on exit, like the one on enter. + */ + + mv.visitInsn(DUP); mv.visitInsn(DUP); mv.visitMethodInsn( @@ -967,7 +983,7 @@ false ); - mv.visitIntInsn(ISTORE, 0); + mv.visitInsn(SWAP); mv.visitMethodInsn( INVOKEVIRTUAL, @@ -977,8 +993,6 @@ false ); - mv.visitInsn(DUP); - mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/String", @@ -987,8 +1001,6 @@ false ); - mv.visitIntInsn(ILOAD, 0); - Label l0 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l0); @@ -1003,16 +1015,16 @@ mv.visitInsn(ATHROW); mv.visitLabel(l0); - } else { - mv.visitMethodInsn( - INVOKEVIRTUAL, - "java/lang/StringBuilder", - "toString", - "()Ljava/lang/String;", - false - ); } + mv.visitMethodInsn( + INVOKEVIRTUAL, + "java/lang/StringBuilder", + "toString", + "()Ljava/lang/String;", + false + ); + mv.visitInsn(ARETURN); mv.visitMaxs(-1, -1);