< prev index next >

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

Print this page




  28 import jdk.internal.access.JavaLangAccess;
  29 import jdk.internal.access.SharedSecrets;
  30 import jdk.internal.misc.VM;
  31 import jdk.internal.org.objectweb.asm.ClassWriter;
  32 import jdk.internal.org.objectweb.asm.Label;
  33 import jdk.internal.org.objectweb.asm.MethodVisitor;
  34 import jdk.internal.org.objectweb.asm.Opcodes;
  35 import sun.invoke.util.Wrapper;
  36 
  37 import java.lang.invoke.MethodHandles.Lookup;
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.List;
  41 import java.util.Objects;
  42 import java.util.concurrent.ConcurrentHashMap;
  43 import java.util.concurrent.ConcurrentMap;
  44 import java.util.function.Function;
  45 
  46 import static java.lang.invoke.MethodHandles.lookup;
  47 import static java.lang.invoke.MethodType.methodType;
  48 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  49 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  50 
  51 /**
  52  * <p>Methods to facilitate the creation of String concatenation methods, that
  53  * can be used to efficiently concatenate a known number of arguments of known
  54  * types, possibly after type adaptation and partial evaluation of arguments.
  55  * These methods are typically used as <em>bootstrap methods</em> for {@code
  56  * invokedynamic} call sites, to support the <em>string concatenation</em>
  57  * feature of the Java Programming Language.
  58  *
  59  * <p>Indirect access to the behavior specified by the provided {@code
  60  * MethodHandle} proceeds in order through two phases:
  61  *
  62  * <ol>
  63  *     <li><em>Linkage</em> occurs when the methods in this class are invoked.
  64  * They take as arguments a method type describing the concatenated arguments
  65  * count and types, and optionally the String <em>recipe</em>, plus the
  66  * constants that participate in the String concatenation. The details on
  67  * accepted recipe shapes are described further below. Linkage may involve
  68  * dynamically loading a new class that implements the expected concatenation


1125 
1126                 mv.visitLabel(l0);
1127             }
1128 
1129             mv.visitMethodInsn(
1130                     INVOKEVIRTUAL,
1131                     "java/lang/StringBuilder",
1132                     "toString",
1133                     "()Ljava/lang/String;",
1134                     false
1135             );
1136 
1137             mv.visitInsn(ARETURN);
1138 
1139             mv.visitMaxs(-1, -1);
1140             mv.visitEnd();
1141             cw.visitEnd();
1142 
1143             byte[] classBytes = cw.toByteArray();
1144             try {
1145                 Class<?> innerClass = lookup.defineHiddenClass(classBytes,true).lookupClass();
1146                 dumpIfEnabled(className, classBytes);
1147                 return lookup.findStatic(innerClass, METHOD_NAME, args);
1148             } catch (Exception e) {
1149                 dumpIfEnabled(className + "$$FAILED", classBytes);
1150                 throw new StringConcatException("Exception while spinning the class", e);
1151             }
1152         }
1153 
1154         private static void dumpIfEnabled(String name, byte[] bytes) {
1155             if (DUMPER != null) {
1156                 DUMPER.dumpClass(name, bytes);
1157             }
1158         }
1159 
1160         private static String getSBAppendDesc(Class<?> cl) {
1161             if (cl.isPrimitive()) {
1162                 if (cl == Integer.TYPE || cl == Byte.TYPE || cl == Short.TYPE) {
1163                     return "(I)Ljava/lang/StringBuilder;";
1164                 } else if (cl == Boolean.TYPE) {
1165                     return "(Z)Ljava/lang/StringBuilder;";




  28 import jdk.internal.access.JavaLangAccess;
  29 import jdk.internal.access.SharedSecrets;
  30 import jdk.internal.misc.VM;
  31 import jdk.internal.org.objectweb.asm.ClassWriter;
  32 import jdk.internal.org.objectweb.asm.Label;
  33 import jdk.internal.org.objectweb.asm.MethodVisitor;
  34 import jdk.internal.org.objectweb.asm.Opcodes;
  35 import sun.invoke.util.Wrapper;
  36 
  37 import java.lang.invoke.MethodHandles.Lookup;
  38 import java.util.ArrayList;
  39 import java.util.Arrays;
  40 import java.util.List;
  41 import java.util.Objects;
  42 import java.util.concurrent.ConcurrentHashMap;
  43 import java.util.concurrent.ConcurrentMap;
  44 import java.util.function.Function;
  45 
  46 import static java.lang.invoke.MethodHandles.lookup;
  47 import static java.lang.invoke.MethodType.methodType;
  48 import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*;
  49 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  50 
  51 /**
  52  * <p>Methods to facilitate the creation of String concatenation methods, that
  53  * can be used to efficiently concatenate a known number of arguments of known
  54  * types, possibly after type adaptation and partial evaluation of arguments.
  55  * These methods are typically used as <em>bootstrap methods</em> for {@code
  56  * invokedynamic} call sites, to support the <em>string concatenation</em>
  57  * feature of the Java Programming Language.
  58  *
  59  * <p>Indirect access to the behavior specified by the provided {@code
  60  * MethodHandle} proceeds in order through two phases:
  61  *
  62  * <ol>
  63  *     <li><em>Linkage</em> occurs when the methods in this class are invoked.
  64  * They take as arguments a method type describing the concatenated arguments
  65  * count and types, and optionally the String <em>recipe</em>, plus the
  66  * constants that participate in the String concatenation. The details on
  67  * accepted recipe shapes are described further below. Linkage may involve
  68  * dynamically loading a new class that implements the expected concatenation


1125 
1126                 mv.visitLabel(l0);
1127             }
1128 
1129             mv.visitMethodInsn(
1130                     INVOKEVIRTUAL,
1131                     "java/lang/StringBuilder",
1132                     "toString",
1133                     "()Ljava/lang/String;",
1134                     false
1135             );
1136 
1137             mv.visitInsn(ARETURN);
1138 
1139             mv.visitMaxs(-1, -1);
1140             mv.visitEnd();
1141             cw.visitEnd();
1142 
1143             byte[] classBytes = cw.toByteArray();
1144             try {
1145                 Class<?> innerClass = lookup.defineHiddenClass(classBytes, true, STRONG).lookupClass();
1146                 dumpIfEnabled(className, classBytes);
1147                 return lookup.findStatic(innerClass, METHOD_NAME, args);
1148             } catch (Exception e) {
1149                 dumpIfEnabled(className + "$$FAILED", classBytes);
1150                 throw new StringConcatException("Exception while spinning the class", e);
1151             }
1152         }
1153 
1154         private static void dumpIfEnabled(String name, byte[] bytes) {
1155             if (DUMPER != null) {
1156                 DUMPER.dumpClass(name, bytes);
1157             }
1158         }
1159 
1160         private static String getSBAppendDesc(Class<?> cl) {
1161             if (cl.isPrimitive()) {
1162                 if (cl == Integer.TYPE || cl == Byte.TYPE || cl == Short.TYPE) {
1163                     return "(I)Ljava/lang/StringBuilder;";
1164                 } else if (cl == Boolean.TYPE) {
1165                     return "(Z)Ljava/lang/StringBuilder;";


< prev index next >