< prev index next >

src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java

Print this page




 940                         default:
 941                             throw new StringConcatException("Unhandled tag: " + el.getTag());
 942                     }
 943                     mv.visitMethodInsn(
 944                             INVOKEVIRTUAL,
 945                             "java/lang/StringBuilder",
 946                             "append",
 947                             desc,
 948                             false
 949                     );
 950                 }
 951             }
 952 
 953             if (DEBUG && mode.isExact()) {
 954                 /*
 955                     Exactness checks compare the final StringBuilder.capacity() with a resulting
 956                     String.length(). If these values disagree, that means StringBuilder had to perform
 957                     storage trimming, which defeats the purpose of exact strategies.
 958                  */
 959 
















 960                 mv.visitInsn(DUP);
 961 
 962                 mv.visitMethodInsn(
 963                         INVOKEVIRTUAL,
 964                         "java/lang/StringBuilder",
 965                         "capacity",
 966                         "()I",
 967                         false
 968                 );
 969 
 970                 mv.visitIntInsn(ISTORE, 0);
 971 
 972                 mv.visitMethodInsn(
 973                         INVOKEVIRTUAL,
 974                         "java/lang/StringBuilder",
 975                         "toString",
 976                         "()Ljava/lang/String;",
 977                         false
 978                 );
 979 
 980                 mv.visitInsn(DUP);
 981 
 982                 mv.visitMethodInsn(
 983                         INVOKEVIRTUAL,
 984                         "java/lang/String",
 985                         "length",
 986                         "()I",
 987                         false
 988                 );
 989 
 990                 mv.visitIntInsn(ILOAD, 0);
 991 
 992                 Label l0 = new Label();
 993                 mv.visitJumpInsn(IF_ICMPEQ, l0);
 994 
 995                 mv.visitTypeInsn(NEW, "java/lang/AssertionError");
 996                 mv.visitInsn(DUP);
 997                 mv.visitLdcInsn("Failed exactness check");
 998                 mv.visitMethodInsn(INVOKESPECIAL,
 999                         "java/lang/AssertionError",
1000                         "<init>",
1001                         "(Ljava/lang/Object;)V",
1002                         false);
1003                 mv.visitInsn(ATHROW);
1004 
1005                 mv.visitLabel(l0);
1006             } else {

1007                 mv.visitMethodInsn(
1008                         INVOKEVIRTUAL,
1009                         "java/lang/StringBuilder",
1010                         "toString",
1011                         "()Ljava/lang/String;",
1012                         false
1013                 );
1014             }
1015 
1016             mv.visitInsn(ARETURN);
1017 
1018             mv.visitMaxs(-1, -1);
1019             mv.visitEnd();
1020             cw.visitEnd();
1021 
1022             Class<?> targetClass = lookup.lookupClass();
1023             final byte[] classBytes = cw.toByteArray();
1024             final Class<?> innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
1025 
1026             try {
1027                 UNSAFE.ensureClassInitialized(innerClass);
1028                 return lookup.findStatic(innerClass, NAME_FACTORY, args);
1029             } catch (ReflectiveOperationException e) {
1030                 throw new StringConcatException("Exception finding constructor", e);
1031             }
1032         }
1033 
1034         private static String getSBAppendDesc(Class<?> cl) {




 940                         default:
 941                             throw new StringConcatException("Unhandled tag: " + el.getTag());
 942                     }
 943                     mv.visitMethodInsn(
 944                             INVOKEVIRTUAL,
 945                             "java/lang/StringBuilder",
 946                             "append",
 947                             desc,
 948                             false
 949                     );
 950                 }
 951             }
 952 
 953             if (DEBUG && mode.isExact()) {
 954                 /*
 955                     Exactness checks compare the final StringBuilder.capacity() with a resulting
 956                     String.length(). If these values disagree, that means StringBuilder had to perform
 957                     storage trimming, which defeats the purpose of exact strategies.
 958                  */
 959 
 960                 /*
 961                    The logic for this check is as follows:
 962 
 963                      Stack before:     Op:
 964                       (SB)              dup, dup
 965                       (SB, SB, SB)      capacity()
 966                       (int, SB, SB)     swap
 967                       (SB, int, SB)     toString()
 968                       (S, int, SB)      length()
 969                       (int, int, SB)    if_icmpeq
 970                       (SB)              <end>
 971 
 972                    Note that it leaves the same StringBuilder on exit, like the one on enter.
 973                  */
 974 
 975                 mv.visitInsn(DUP);
 976                 mv.visitInsn(DUP);
 977 
 978                 mv.visitMethodInsn(
 979                         INVOKEVIRTUAL,
 980                         "java/lang/StringBuilder",
 981                         "capacity",
 982                         "()I",
 983                         false
 984                 );
 985 
 986                 mv.visitInsn(SWAP);
 987 
 988                 mv.visitMethodInsn(
 989                         INVOKEVIRTUAL,
 990                         "java/lang/StringBuilder",
 991                         "toString",
 992                         "()Ljava/lang/String;",
 993                         false
 994                 );
 995 


 996                 mv.visitMethodInsn(
 997                         INVOKEVIRTUAL,
 998                         "java/lang/String",
 999                         "length",
1000                         "()I",
1001                         false
1002                 );
1003 


1004                 Label l0 = new Label();
1005                 mv.visitJumpInsn(IF_ICMPEQ, l0);
1006 
1007                 mv.visitTypeInsn(NEW, "java/lang/AssertionError");
1008                 mv.visitInsn(DUP);
1009                 mv.visitLdcInsn("Failed exactness check");
1010                 mv.visitMethodInsn(INVOKESPECIAL,
1011                         "java/lang/AssertionError",
1012                         "<init>",
1013                         "(Ljava/lang/Object;)V",
1014                         false);
1015                 mv.visitInsn(ATHROW);
1016 
1017                 mv.visitLabel(l0);
1018             }
1019 
1020             mv.visitMethodInsn(
1021                     INVOKEVIRTUAL,
1022                     "java/lang/StringBuilder",
1023                     "toString",
1024                     "()Ljava/lang/String;",
1025                     false
1026             );

1027 
1028             mv.visitInsn(ARETURN);
1029 
1030             mv.visitMaxs(-1, -1);
1031             mv.visitEnd();
1032             cw.visitEnd();
1033 
1034             Class<?> targetClass = lookup.lookupClass();
1035             final byte[] classBytes = cw.toByteArray();
1036             final Class<?> innerClass = UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
1037 
1038             try {
1039                 UNSAFE.ensureClassInitialized(innerClass);
1040                 return lookup.findStatic(innerClass, NAME_FACTORY, args);
1041             } catch (ReflectiveOperationException e) {
1042                 throw new StringConcatException("Exception finding constructor", e);
1043             }
1044         }
1045 
1046         private static String getSBAppendDesc(Class<?> cl) {


< prev index next >