Capable to compile the java.lang.invoke stuff jdk8
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 10 Aug 2014 07:02:12 +0200
branchjdk8
changeset 1653bd151459ee4f
parent 1652 8fb89a569621
child 1654 da24a2411ee7
Capable to compile the java.lang.invoke stuff
rt/emul/compact/pom.xml
rt/emul/compact/src/main/java/java/lang/ClassValue.java
rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java
rt/emul/compact/src/main/java/java/lang/invoke/DirectMethodHandle.java
rt/emul/compact/src/main/java/java/lang/invoke/InnerClassLambdaMetafactory.java
rt/emul/compact/src/main/java/java/lang/invoke/InvokerBytecodeGenerator.java
rt/emul/compact/src/main/java/java/lang/invoke/LambdaForm.java
rt/emul/compact/src/main/java/java/lang/invoke/LambdaMetafactory.java
rt/emul/compact/src/main/java/java/lang/invoke/TypeConvertingMethodAdapter.java
rt/emul/mini/src/main/java/java/lang/Class.java
     1.1 --- a/rt/emul/compact/pom.xml	Sun Aug 10 06:21:50 2014 +0200
     1.2 +++ b/rt/emul/compact/pom.xml	Sun Aug 10 07:02:12 2014 +0200
     1.3 @@ -55,8 +55,8 @@
     1.4                    <compilerArguments>
     1.5                        <bootclasspath>netbeans.ignore.jdk.bootclasspath</bootclasspath>
     1.6                    </compilerArguments>
     1.7 -                 <source>1.7</source>
     1.8 -                 <target>1.7</target>
     1.9 +                 <source>1.8</source>
    1.10 +                 <target>1.8</target>
    1.11                </configuration>
    1.12            </plugin>
    1.13            <plugin>
     2.1 --- a/rt/emul/compact/src/main/java/java/lang/ClassValue.java	Sun Aug 10 06:21:50 2014 +0200
     2.2 +++ b/rt/emul/compact/src/main/java/java/lang/ClassValue.java	Sun Aug 10 07:02:12 2014 +0200
     2.3 @@ -186,7 +186,7 @@
     2.4      /** Return the cache, if it exists, else a dummy empty cache. */
     2.5      private static Entry<?>[] getCacheCarefully(Class<?> type) {
     2.6          // racing type.classValueMap{.cacheArray} : null => new Entry[X] <=> new Entry[Y]
     2.7 -        ClassValueMap map = type.classValueMap;
     2.8 +        ClassValueMap map = (ClassValueMap) type.classValueMap;
     2.9          if (map == null)  return EMPTY_CACHE;
    2.10          Entry<?>[] cache = map.getCache();
    2.11          return cache;
    2.12 @@ -364,7 +364,7 @@
    2.13          // racing type.classValueMap : null (blank) => unique ClassValueMap
    2.14          // if a null is observed, a map is created (lazily, synchronously, uniquely)
    2.15          // all further access to that map is synchronized
    2.16 -        ClassValueMap map = type.classValueMap;
    2.17 +        ClassValueMap map = (ClassValueMap)type.classValueMap;
    2.18          if (map != null)  return map;
    2.19          return initializeMap(type);
    2.20      }
    2.21 @@ -374,7 +374,7 @@
    2.22          ClassValueMap map;
    2.23          synchronized (CRITICAL_SECTION) {  // private object to avoid deadlocks
    2.24              // happens about once per type
    2.25 -            if ((map = type.classValueMap) == null)
    2.26 +            if ((map = (ClassValueMap)type.classValueMap) == null)
    2.27                  type.classValueMap = map = new ClassValueMap(type);
    2.28          }
    2.29              return map;
     3.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java	Sun Aug 10 06:21:50 2014 +0200
     3.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java	Sun Aug 10 07:02:12 2014 +0200
     3.3 @@ -25,24 +25,16 @@
     3.4  
     3.5  package java.lang.invoke;
     3.6  
     3.7 -import static jdk.internal.org.objectweb.asm.Opcodes.*;
     3.8  import static java.lang.invoke.LambdaForm.basicTypes;
     3.9 -import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
    3.10  import static java.lang.invoke.MethodHandleStatics.*;
    3.11  
    3.12  import java.lang.invoke.LambdaForm.Name;
    3.13  import java.lang.invoke.LambdaForm.NamedFunction;
    3.14  import java.lang.invoke.MethodHandles.Lookup;
    3.15 -import java.lang.reflect.Field;
    3.16  import java.util.Arrays;
    3.17  import java.util.HashMap;
    3.18  
    3.19  import sun.invoke.util.ValueConversions;
    3.20 -import sun.invoke.util.Wrapper;
    3.21 -
    3.22 -import jdk.internal.org.objectweb.asm.ClassWriter;
    3.23 -import jdk.internal.org.objectweb.asm.MethodVisitor;
    3.24 -import jdk.internal.org.objectweb.asm.Type;
    3.25  
    3.26  /**
    3.27   * The flavor of method handle which emulates an invoke instruction
    3.28 @@ -373,8 +365,9 @@
    3.29                  this.constructor = new MethodHandle[1];
    3.30                  this.getters = new MethodHandle[types.length()];
    3.31              } else {
    3.32 -                this.constructor = Factory.makeCtors(clazz, types, null);
    3.33 -                this.getters = Factory.makeGetters(clazz, types, null);
    3.34 +                throw new IllegalStateException("bound method handle");
    3.35 +//                this.constructor = Factory.makeCtors(clazz, types, null);
    3.36 +//                this.getters = Factory.makeGetters(clazz, types, null);
    3.37              }
    3.38              this.extensions = new SpeciesData[EXTENSION_TYPES.length()];
    3.39          }
    3.40 @@ -382,8 +375,8 @@
    3.41          private void initForBootstrap() {
    3.42              assert(!INIT_DONE);
    3.43              if (constructor[0] == null) {
    3.44 -                Factory.makeCtors(clazz, types, this.constructor);
    3.45 -                Factory.makeGetters(clazz, types, this.getters);
    3.46 +//                Factory.makeCtors(clazz, types, this.constructor);
    3.47 +//                Factory.makeGetters(clazz, types, this.getters);
    3.48              }
    3.49          }
    3.50  
    3.51 @@ -425,7 +418,7 @@
    3.52                  // Use synch. on the placeholder to prevent multiple instantiation of one species.
    3.53                  // Creating this class forces a recursive call to getForClass.
    3.54                  if (lookupCache(types).isPlaceholder())
    3.55 -                    Factory.generateConcreteBMHClass(types);
    3.56 +                    throw new IllegalStateException("Cannot generate anything");
    3.57              }
    3.58              // Reacquire cache lock.
    3.59              d = lookupCache(types);
    3.60 @@ -459,6 +452,7 @@
    3.61              SpeciesData d0 = BoundMethodHandle.SPECIES_DATA;  // trigger class init
    3.62              assert(d0 == null || d0 == lookupCache("")) : d0;
    3.63              try {
    3.64 +                /*
    3.65                  for (Class<?> c : rootCls.getDeclaredClasses()) {
    3.66                      if (rootCls.isAssignableFrom(c)) {
    3.67                          final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
    3.68 @@ -468,6 +462,7 @@
    3.69                          assert(d == lookupCache(d.types));
    3.70                      }
    3.71                  }
    3.72 +                */
    3.73              } catch (Throwable e) {
    3.74                  throw newInternalError(e);
    3.75              }
    3.76 @@ -485,375 +480,7 @@
    3.77          return SpeciesData.get(types);
    3.78      }
    3.79  
    3.80 -    /**
    3.81 -     * Generation of concrete BMH classes.
    3.82 -     *
    3.83 -     * A concrete BMH species is fit for binding a number of values adhering to a
    3.84 -     * given type pattern. Reference types are erased.
    3.85 -     *
    3.86 -     * BMH species are cached by type pattern.
    3.87 -     *
    3.88 -     * A BMH species has a number of fields with the concrete (possibly erased) types of
    3.89 -     * bound values. Setters are provided as an API in BMH. Getters are exposed as MHs,
    3.90 -     * which can be included as names in lambda forms.
    3.91 -     */
    3.92 -    static class Factory {
    3.93  
    3.94 -        static final String JLO_SIG  = "Ljava/lang/Object;";
    3.95 -        static final String JLS_SIG  = "Ljava/lang/String;";
    3.96 -        static final String JLC_SIG  = "Ljava/lang/Class;";
    3.97 -        static final String MH       = "java/lang/invoke/MethodHandle";
    3.98 -        static final String MH_SIG   = "L"+MH+";";
    3.99 -        static final String BMH      = "java/lang/invoke/BoundMethodHandle";
   3.100 -        static final String BMH_SIG  = "L"+BMH+";";
   3.101 -        static final String SPECIES_DATA     = "java/lang/invoke/BoundMethodHandle$SpeciesData";
   3.102 -        static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
   3.103 -
   3.104 -        static final String SPECIES_PREFIX_NAME = "Species_";
   3.105 -        static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
   3.106 -
   3.107 -        static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
   3.108 -        static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
   3.109 -        static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
   3.110 -        static final String VOID_SIG   = "()V";
   3.111 -
   3.112 -        static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
   3.113 -
   3.114 -        static final Class<?>[] TYPES = new Class<?>[] { Object.class, int.class, long.class, float.class, double.class };
   3.115 -
   3.116 -        static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
   3.117 -
   3.118 -        /**
   3.119 -         * Generate a concrete subclass of BMH for a given combination of bound types.
   3.120 -         *
   3.121 -         * A concrete BMH species adheres to the following schema:
   3.122 -         *
   3.123 -         * <pre>
   3.124 -         * class Species_[[types]] extends BoundMethodHandle {
   3.125 -         *     [[fields]]
   3.126 -         *     final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); }
   3.127 -         * }
   3.128 -         * </pre>
   3.129 -         *
   3.130 -         * The {@code [[types]]} signature is precisely the string that is passed to this
   3.131 -         * method.
   3.132 -         *
   3.133 -         * The {@code [[fields]]} section consists of one field definition per character in
   3.134 -         * the type signature, adhering to the naming schema described in the definition of
   3.135 -         * {@link #makeFieldName}.
   3.136 -         *
   3.137 -         * For example, a concrete BMH species for two reference and one integral bound values
   3.138 -         * would have the following shape:
   3.139 -         *
   3.140 -         * <pre>
   3.141 -         * class BoundMethodHandle { ... private static
   3.142 -         * final class Species_LLI extends BoundMethodHandle {
   3.143 -         *     final Object argL0;
   3.144 -         *     final Object argL1;
   3.145 -         *     final int argI2;
   3.146 -         *     public Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
   3.147 -         *         super(mt, lf);
   3.148 -         *         this.argL0 = argL0;
   3.149 -         *         this.argL1 = argL1;
   3.150 -         *         this.argI2 = argI2;
   3.151 -         *     }
   3.152 -         *     public final SpeciesData speciesData() { return SPECIES_DATA; }
   3.153 -         *     public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
   3.154 -         *     public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
   3.155 -         *         return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
   3.156 -         *     }
   3.157 -         *     public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
   3.158 -         *         return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   3.159 -         *     }
   3.160 -         *     public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
   3.161 -         *         return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   3.162 -         *     }
   3.163 -         *     public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
   3.164 -         *         return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   3.165 -         *     }
   3.166 -         *     public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
   3.167 -         *         return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   3.168 -         *     }
   3.169 -         *     public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
   3.170 -         *         return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
   3.171 -         *     }
   3.172 -         * }
   3.173 -         * </pre>
   3.174 -         *
   3.175 -         * @param types the type signature, wherein reference types are erased to 'L'
   3.176 -         * @return the generated concrete BMH class
   3.177 -         */
   3.178 -        static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
   3.179 -            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
   3.180 -
   3.181 -            final String className  = SPECIES_PREFIX_PATH + types;
   3.182 -            final String sourceFile = SPECIES_PREFIX_NAME + types;
   3.183 -            cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
   3.184 -            cw.visitSource(sourceFile, null);
   3.185 -
   3.186 -            // emit static types and SPECIES_DATA fields
   3.187 -            cw.visitField(ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
   3.188 -
   3.189 -            // emit bound argument fields
   3.190 -            for (int i = 0; i < types.length(); ++i) {
   3.191 -                final char t = types.charAt(i);
   3.192 -                final String fieldName = makeFieldName(types, i);
   3.193 -                final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
   3.194 -                cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
   3.195 -            }
   3.196 -
   3.197 -            MethodVisitor mv;
   3.198 -
   3.199 -            // emit constructor
   3.200 -            mv = cw.visitMethod(ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
   3.201 -            mv.visitCode();
   3.202 -            mv.visitVarInsn(ALOAD, 0);
   3.203 -            mv.visitVarInsn(ALOAD, 1);
   3.204 -            mv.visitVarInsn(ALOAD, 2);
   3.205 -
   3.206 -            mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true));
   3.207 -
   3.208 -            for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
   3.209 -                // i counts the arguments, j counts corresponding argument slots
   3.210 -                char t = types.charAt(i);
   3.211 -                mv.visitVarInsn(ALOAD, 0);
   3.212 -                mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
   3.213 -                mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
   3.214 -                if (t == 'J' || t == 'D') {
   3.215 -                    ++j; // adjust argument register access
   3.216 -                }
   3.217 -            }
   3.218 -
   3.219 -            mv.visitInsn(RETURN);
   3.220 -            mv.visitMaxs(0, 0);
   3.221 -            mv.visitEnd();
   3.222 -
   3.223 -            // emit implementation of reinvokerTarget()
   3.224 -            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
   3.225 -            mv.visitCode();
   3.226 -            mv.visitVarInsn(ALOAD, 0);
   3.227 -            mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
   3.228 -            mv.visitTypeInsn(CHECKCAST, MH);
   3.229 -            mv.visitInsn(ARETURN);
   3.230 -            mv.visitMaxs(0, 0);
   3.231 -            mv.visitEnd();
   3.232 -
   3.233 -            // emit implementation of speciesData()
   3.234 -            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
   3.235 -            mv.visitCode();
   3.236 -            mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   3.237 -            mv.visitInsn(ARETURN);
   3.238 -            mv.visitMaxs(0, 0);
   3.239 -            mv.visitEnd();
   3.240 -
   3.241 -            // emit clone()
   3.242 -            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
   3.243 -            mv.visitCode();
   3.244 -            // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
   3.245 -            // obtain constructor
   3.246 -            mv.visitVarInsn(ALOAD, 0);
   3.247 -            mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   3.248 -            mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
   3.249 -            mv.visitInsn(ICONST_0);
   3.250 -            mv.visitInsn(AALOAD);
   3.251 -            // load mt, lf
   3.252 -            mv.visitVarInsn(ALOAD, 1);
   3.253 -            mv.visitVarInsn(ALOAD, 2);
   3.254 -            // put fields on the stack
   3.255 -            emitPushFields(types, className, mv);
   3.256 -            // finally, invoke the constructor and return
   3.257 -            mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false));
   3.258 -            mv.visitInsn(ARETURN);
   3.259 -            mv.visitMaxs(0, 0);
   3.260 -            mv.visitEnd();
   3.261 -
   3.262 -            // for each type, emit cloneExtendT()
   3.263 -            for (Class<?> c : TYPES) {
   3.264 -                char t = Wrapper.basicTypeChar(c);
   3.265 -                mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
   3.266 -                mv.visitCode();
   3.267 -                // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
   3.268 -                // obtain constructor
   3.269 -                mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   3.270 -                int iconstInsn = ICONST_0 + extensionIndex(t);
   3.271 -                assert(iconstInsn <= ICONST_5);
   3.272 -                mv.visitInsn(iconstInsn);
   3.273 -                mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG);
   3.274 -                mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
   3.275 -                mv.visitInsn(ICONST_0);
   3.276 -                mv.visitInsn(AALOAD);
   3.277 -                // load mt, lf
   3.278 -                mv.visitVarInsn(ALOAD, 1);
   3.279 -                mv.visitVarInsn(ALOAD, 2);
   3.280 -                // put fields on the stack
   3.281 -                emitPushFields(types, className, mv);
   3.282 -                // put narg on stack
   3.283 -                mv.visitVarInsn(typeLoadOp(t), 3);
   3.284 -                // finally, invoke the constructor and return
   3.285 -                mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false));
   3.286 -                mv.visitInsn(ARETURN);
   3.287 -                mv.visitMaxs(0, 0);
   3.288 -                mv.visitEnd();
   3.289 -            }
   3.290 -
   3.291 -            // emit class initializer
   3.292 -            mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
   3.293 -            mv.visitCode();
   3.294 -            mv.visitLdcInsn(types);
   3.295 -            mv.visitLdcInsn(Type.getObjectType(className));
   3.296 -            mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG);
   3.297 -            mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
   3.298 -            mv.visitInsn(RETURN);
   3.299 -            mv.visitMaxs(0, 0);
   3.300 -            mv.visitEnd();
   3.301 -
   3.302 -            cw.visitEnd();
   3.303 -
   3.304 -            // load class
   3.305 -            final byte[] classFile = cw.toByteArray();
   3.306 -            InvokerBytecodeGenerator.maybeDump(className, classFile);
   3.307 -            Class<? extends BoundMethodHandle> bmhClass =
   3.308 -                //UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
   3.309 -                UNSAFE.defineClass(className, classFile, 0, classFile.length,
   3.310 -                                   BoundMethodHandle.class.getClassLoader(), null)
   3.311 -                    .asSubclass(BoundMethodHandle.class);
   3.312 -            UNSAFE.ensureClassInitialized(bmhClass);
   3.313 -
   3.314 -            return bmhClass;
   3.315 -        }
   3.316 -
   3.317 -        private static int typeLoadOp(char t) {
   3.318 -            switch (t) {
   3.319 -            case 'L': return ALOAD;
   3.320 -            case 'I': return ILOAD;
   3.321 -            case 'J': return LLOAD;
   3.322 -            case 'F': return FLOAD;
   3.323 -            case 'D': return DLOAD;
   3.324 -            default : throw new InternalError("unrecognized type " + t);
   3.325 -            }
   3.326 -        }
   3.327 -
   3.328 -        private static void emitPushFields(String types, String className, MethodVisitor mv) {
   3.329 -            for (int i = 0; i < types.length(); ++i) {
   3.330 -                char tc = types.charAt(i);
   3.331 -                mv.visitVarInsn(ALOAD, 0);
   3.332 -                mv.visitFieldInsn(GETFIELD, className, makeFieldName(types, i), typeSig(tc));
   3.333 -            }
   3.334 -        }
   3.335 -
   3.336 -        static String typeSig(char t) {
   3.337 -            return t == 'L' ? JLO_SIG : String.valueOf(t);
   3.338 -        }
   3.339 -
   3.340 -        //
   3.341 -        // Getter MH generation.
   3.342 -        //
   3.343 -
   3.344 -        private static MethodHandle makeGetter(Class<?> cbmhClass, String types, int index) {
   3.345 -            String fieldName = makeFieldName(types, index);
   3.346 -            Class<?> fieldType = Wrapper.forBasicType(types.charAt(index)).primitiveType();
   3.347 -            try {
   3.348 -                return LOOKUP.findGetter(cbmhClass, fieldName, fieldType);
   3.349 -            } catch (NoSuchFieldException | IllegalAccessException e) {
   3.350 -                throw newInternalError(e);
   3.351 -            }
   3.352 -        }
   3.353 -
   3.354 -        static MethodHandle[] makeGetters(Class<?> cbmhClass, String types, MethodHandle[] mhs) {
   3.355 -            if (mhs == null)  mhs = new MethodHandle[types.length()];
   3.356 -            for (int i = 0; i < mhs.length; ++i) {
   3.357 -                mhs[i] = makeGetter(cbmhClass, types, i);
   3.358 -                assert(mhs[i].internalMemberName().getDeclaringClass() == cbmhClass);
   3.359 -            }
   3.360 -            return mhs;
   3.361 -        }
   3.362 -
   3.363 -        static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) {
   3.364 -            if (mhs == null)  mhs = new MethodHandle[1];
   3.365 -            mhs[0] = makeCbmhCtor(cbmh, types);
   3.366 -            return mhs;
   3.367 -        }
   3.368 -
   3.369 -        //
   3.370 -        // Auxiliary methods.
   3.371 -        //
   3.372 -
   3.373 -        static SpeciesData speciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
   3.374 -            try {
   3.375 -                Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
   3.376 -                return (SpeciesData) F_SPECIES_DATA.get(null);
   3.377 -            } catch (ReflectiveOperationException ex) {
   3.378 -                throw newInternalError(ex);
   3.379 -            }
   3.380 -        }
   3.381 -
   3.382 -        /**
   3.383 -         * Field names in concrete BMHs adhere to this pattern:
   3.384 -         * arg + type + index
   3.385 -         * where type is a single character (L, I, J, F, D).
   3.386 -         */
   3.387 -        private static String makeFieldName(String types, int index) {
   3.388 -            assert index >= 0 && index < types.length();
   3.389 -            return "arg" + types.charAt(index) + index;
   3.390 -        }
   3.391 -
   3.392 -        private static String makeSignature(String types, boolean ctor) {
   3.393 -            StringBuilder buf = new StringBuilder(SIG_INCIPIT);
   3.394 -            for (char c : types.toCharArray()) {
   3.395 -                buf.append(typeSig(c));
   3.396 -            }
   3.397 -            return buf.append(')').append(ctor ? "V" : BMH_SIG).toString();
   3.398 -        }
   3.399 -
   3.400 -        static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
   3.401 -            try {
   3.402 -                return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null)));
   3.403 -            } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
   3.404 -                throw newInternalError(e);
   3.405 -            }
   3.406 -        }
   3.407 -
   3.408 -        /**
   3.409 -         * Wrap a constructor call in a {@link LambdaForm}.
   3.410 -         *
   3.411 -         * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
   3.412 -         * are turned into bytecode, because the call to the allocator is routed through an MH, and the
   3.413 -         * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
   3.414 -         * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
   3.415 -         * {@link MethodHandle#linkToSpecial}.
   3.416 -         *
   3.417 -         * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
   3.418 -         * result of the {@code <init>} invocation. This entry is replaced.
   3.419 -         */
   3.420 -        private static MethodHandle linkConstructor(MethodHandle cmh) {
   3.421 -            final LambdaForm lf = cmh.form;
   3.422 -            final int initNameIndex = lf.names.length - 1;
   3.423 -            final Name initName = lf.names[initNameIndex];
   3.424 -            final MemberName ctorMN = initName.function.member;
   3.425 -            final MethodType ctorMT = ctorMN.getInvocationType();
   3.426 -
   3.427 -            // obtain function member (call target)
   3.428 -            // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
   3.429 -            final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
   3.430 -            MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
   3.431 -            try {
   3.432 -                linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
   3.433 -                assert(linkerMN.isStatic());
   3.434 -            } catch (ReflectiveOperationException ex) {
   3.435 -                throw newInternalError(ex);
   3.436 -            }
   3.437 -            // extend arguments array
   3.438 -            Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
   3.439 -            newArgs[newArgs.length - 1] = ctorMN;
   3.440 -            // replace function
   3.441 -            final NamedFunction nf = new NamedFunction(linkerMN);
   3.442 -            final Name linkedCtor = new Name(nf, newArgs);
   3.443 -            linkedCtor.initIndex(initNameIndex);
   3.444 -            lf.names[initNameIndex] = linkedCtor;
   3.445 -            return cmh;
   3.446 -        }
   3.447 -
   3.448 -    }
   3.449  
   3.450      private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
   3.451  
     4.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/DirectMethodHandle.java	Sun Aug 10 06:21:50 2014 +0200
     4.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/DirectMethodHandle.java	Sun Aug 10 07:02:12 2014 +0200
     4.3 @@ -25,7 +25,6 @@
     4.4  
     4.5  package java.lang.invoke;
     4.6  
     4.7 -import sun.misc.Unsafe;
     4.8  import java.lang.reflect.Method;
     4.9  import java.util.Arrays;
    4.10  import sun.invoke.util.VerifyAccess;
    4.11 @@ -326,19 +325,19 @@
    4.12              VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
    4.13              // It is a system class.  It is probably in the process of
    4.14              // being initialized, but we will help it along just to be safe.
    4.15 -            if (UNSAFE.shouldBeInitialized(cls)) {
    4.16 -                UNSAFE.ensureClassInitialized(cls);
    4.17 +            if (shouldBeInitialized(cls)) {
    4.18 +                ensureClassInitialized(cls);
    4.19              }
    4.20              return false;
    4.21          }
    4.22 -        return UNSAFE.shouldBeInitialized(cls);
    4.23 +        return shouldBeInitialized(cls);
    4.24      }
    4.25  
    4.26      private static class EnsureInitialized extends ClassValue<WeakReference<Thread>> {
    4.27          @Override
    4.28          protected WeakReference<Thread> computeValue(Class<?> type) {
    4.29 -            UNSAFE.ensureClassInitialized(type);
    4.30 -            if (UNSAFE.shouldBeInitialized(type))
    4.31 +            ensureClassInitialized(type);
    4.32 +            if (shouldBeInitialized(type))
    4.33                  // If the previous call didn't block, this can happen.
    4.34                  // We are executing inside <clinit>.
    4.35                  return new WeakReference<>(Thread.currentThread());
    4.36 @@ -366,14 +365,14 @@
    4.37          // Somebody may still be running defc.<clinit>.
    4.38          if (clinitThread == Thread.currentThread()) {
    4.39              // If anybody is running defc.<clinit>, it is this thread.
    4.40 -            if (UNSAFE.shouldBeInitialized(defc))
    4.41 +            if (shouldBeInitialized(defc))
    4.42                  // Yes, we are running it; keep the barrier for now.
    4.43                  return false;
    4.44          } else {
    4.45              // We are in a random thread.  Block.
    4.46 -            UNSAFE.ensureClassInitialized(defc);
    4.47 +            ensureClassInitialized(defc);
    4.48          }
    4.49 -        assert(!UNSAFE.shouldBeInitialized(defc));
    4.50 +        assert(!shouldBeInitialized(defc));
    4.51          // put it into the final state
    4.52          EnsureInitialized.INSTANCE.remove(defc);
    4.53          return true;
    4.54 @@ -423,7 +422,12 @@
    4.55  
    4.56      /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
    4.57          Constructor dmh = (Constructor)mh;
    4.58 -        return UNSAFE.allocateInstance(dmh.instanceClass);
    4.59 +        try {
    4.60 +            return dmh.instanceClass.newInstance();
    4.61 +//        return UNSAFE.allocateInstance(dmh.instanceClass);
    4.62 +        } catch (IllegalAccessException ex) {
    4.63 +            throw (InstantiationException)new InstantiationException().initCause(ex);
    4.64 +        }
    4.65      }
    4.66  
    4.67      /** This subclass handles non-static field references. */
    4.68 @@ -603,7 +607,7 @@
    4.69              linkerType = MethodType.methodType(ft, Object.class, long.class);
    4.70          else
    4.71              linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
    4.72 -        MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
    4.73 +        MemberName linker = null;//new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
    4.74          try {
    4.75              linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
    4.76          } catch (ReflectiveOperationException ex) {
    4.77 @@ -642,7 +646,7 @@
    4.78              names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
    4.79          Object[] outArgs = new Object[1 + linkerType.parameterCount()];
    4.80          assert(outArgs.length == (isGetter ? 3 : 4));
    4.81 -        outArgs[0] = UNSAFE;
    4.82 +//        outArgs[0] = UNSAFE;
    4.83          if (isStatic) {
    4.84              outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
    4.85              outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
    4.86 @@ -707,7 +711,7 @@
    4.87                  };
    4.88                  for (NamedFunction nf : nfs) {
    4.89                      // Each nf must be statically invocable or we get tied up in our bootstraps.
    4.90 -                    assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
    4.91 +//                    assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
    4.92                      nf.resolve();
    4.93                  }
    4.94              } catch (ReflectiveOperationException ex) {
    4.95 @@ -715,4 +719,12 @@
    4.96              }
    4.97          }
    4.98      }
    4.99 +    
   4.100 +    private static boolean shouldBeInitialized(Class<?> c) {
   4.101 +        return false;
   4.102 +    }
   4.103 +    
   4.104 +    private static void ensureClassInitialized(Class<?> c) {
   4.105 +        c.getName();
   4.106 +    }
   4.107  }
     5.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/InnerClassLambdaMetafactory.java	Sun Aug 10 06:21:50 2014 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,551 +0,0 @@
     5.4 -/*
     5.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 - *
     5.8 - * This code is free software; you can redistribute it and/or modify it
     5.9 - * under the terms of the GNU General Public License version 2 only, as
    5.10 - * published by the Free Software Foundation.  Oracle designates this
    5.11 - * particular file as subject to the "Classpath" exception as provided
    5.12 - * by Oracle in the LICENSE file that accompanied this code.
    5.13 - *
    5.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 - * version 2 for more details (a copy is included in the LICENSE file that
    5.18 - * accompanied this code).
    5.19 - *
    5.20 - * You should have received a copy of the GNU General Public License version
    5.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    5.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 - *
    5.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 - * or visit www.oracle.com if you need additional information or have any
    5.26 - * questions.
    5.27 - */
    5.28 -
    5.29 -package java.lang.invoke;
    5.30 -
    5.31 -import jdk.internal.org.objectweb.asm.*;
    5.32 -import sun.invoke.util.BytecodeDescriptor;
    5.33 -import sun.misc.Unsafe;
    5.34 -import sun.security.action.GetPropertyAction;
    5.35 -
    5.36 -import java.io.FilePermission;
    5.37 -import java.io.Serializable;
    5.38 -import java.lang.reflect.Constructor;
    5.39 -import java.security.AccessController;
    5.40 -import java.security.PrivilegedAction;
    5.41 -import java.util.LinkedHashSet;
    5.42 -import java.util.concurrent.atomic.AtomicInteger;
    5.43 -import java.util.PropertyPermission;
    5.44 -import java.util.Set;
    5.45 -
    5.46 -import static jdk.internal.org.objectweb.asm.Opcodes.*;
    5.47 -
    5.48 -/**
    5.49 - * Lambda metafactory implementation which dynamically creates an
    5.50 - * inner-class-like class per lambda callsite.
    5.51 - *
    5.52 - * @see LambdaMetafactory
    5.53 - */
    5.54 -/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
    5.55 -    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
    5.56 -
    5.57 -    private static final int CLASSFILE_VERSION = 52;
    5.58 -    private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
    5.59 -    private static final String JAVA_LANG_OBJECT = "java/lang/Object";
    5.60 -    private static final String NAME_CTOR = "<init>";
    5.61 -    private static final String NAME_FACTORY = "get$Lambda";
    5.62 -
    5.63 -    //Serialization support
    5.64 -    private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
    5.65 -    private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
    5.66 -    private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
    5.67 -    private static final String DESCR_METHOD_WRITE_OBJECT = "(Ljava/io/ObjectOutputStream;)V";
    5.68 -    private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V";
    5.69 -    private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
    5.70 -    private static final String NAME_METHOD_READ_OBJECT = "readObject";
    5.71 -    private static final String NAME_METHOD_WRITE_OBJECT = "writeObject";
    5.72 -    private static final String DESCR_CTOR_SERIALIZED_LAMBDA
    5.73 -            = MethodType.methodType(void.class,
    5.74 -                                    Class.class,
    5.75 -                                    String.class, String.class, String.class,
    5.76 -                                    int.class, String.class, String.class, String.class,
    5.77 -                                    String.class,
    5.78 -                                    Object[].class).toMethodDescriptorString();
    5.79 -    private static final String DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION
    5.80 -            = MethodType.methodType(void.class, String.class).toMethodDescriptorString();
    5.81 -    private static final String[] SER_HOSTILE_EXCEPTIONS = new String[] {NAME_NOT_SERIALIZABLE_EXCEPTION};
    5.82 -
    5.83 -
    5.84 -    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    5.85 -
    5.86 -    // Used to ensure that each spun class name is unique
    5.87 -    private static final AtomicInteger counter = new AtomicInteger(0);
    5.88 -
    5.89 -
    5.90 -    // See context values in AbstractValidatingLambdaMetafactory
    5.91 -    private final String implMethodClassName;        // Name of type containing implementation "CC"
    5.92 -    private final String implMethodName;             // Name of implementation method "impl"
    5.93 -    private final String implMethodDesc;             // Type descriptor for implementation methods "(I)Ljava/lang/String;"
    5.94 -    private final Class<?> implMethodReturnClass;    // class for implementaion method return type "Ljava/lang/String;"
    5.95 -    private final MethodType constructorType;        // Generated class constructor type "(CC)void"
    5.96 -    private final ClassWriter cw;                    // ASM class writer
    5.97 -    private final String[] argNames;                 // Generated names for the constructor arguments
    5.98 -    private final String[] argDescs;                 // Type descriptors for the constructor arguments
    5.99 -    private final String lambdaClassName;            // Generated name for the generated class "X$$Lambda$1"
   5.100 -
   5.101 -    /**
   5.102 -     * General meta-factory constructor, supporting both standard cases and
   5.103 -     * allowing for uncommon options such as serialization or bridging.
   5.104 -     *
   5.105 -     * @param caller Stacked automatically by VM; represents a lookup context
   5.106 -     *               with the accessibility privileges of the caller.
   5.107 -     * @param invokedType Stacked automatically by VM; the signature of the
   5.108 -     *                    invoked method, which includes the expected static
   5.109 -     *                    type of the returned lambda object, and the static
   5.110 -     *                    types of the captured arguments for the lambda.  In
   5.111 -     *                    the event that the implementation method is an
   5.112 -     *                    instance method, the first argument in the invocation
   5.113 -     *                    signature will correspond to the receiver.
   5.114 -     * @param samMethodName Name of the method in the functional interface to
   5.115 -     *                      which the lambda or method reference is being
   5.116 -     *                      converted, represented as a String.
   5.117 -     * @param samMethodType Type of the method in the functional interface to
   5.118 -     *                      which the lambda or method reference is being
   5.119 -     *                      converted, represented as a MethodType.
   5.120 -     * @param implMethod The implementation method which should be called (with
   5.121 -     *                   suitable adaptation of argument types, return types,
   5.122 -     *                   and adjustment for captured arguments) when methods of
   5.123 -     *                   the resulting functional interface instance are invoked.
   5.124 -     * @param instantiatedMethodType The signature of the primary functional
   5.125 -     *                               interface method after type variables are
   5.126 -     *                               substituted with their instantiation from
   5.127 -     *                               the capture site
   5.128 -     * @param isSerializable Should the lambda be made serializable?  If set,
   5.129 -     *                       either the target type or one of the additional SAM
   5.130 -     *                       types must extend {@code Serializable}.
   5.131 -     * @param markerInterfaces Additional interfaces which the lambda object
   5.132 -     *                       should implement.
   5.133 -     * @param additionalBridges Method types for additional signatures to be
   5.134 -     *                          bridged to the implementation method
   5.135 -     * @throws LambdaConversionException If any of the meta-factory protocol
   5.136 -     * invariants are violated
   5.137 -     */
   5.138 -    public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
   5.139 -                                       MethodType invokedType,
   5.140 -                                       String samMethodName,
   5.141 -                                       MethodType samMethodType,
   5.142 -                                       MethodHandle implMethod,
   5.143 -                                       MethodType instantiatedMethodType,
   5.144 -                                       boolean isSerializable,
   5.145 -                                       Class<?>[] markerInterfaces,
   5.146 -                                       MethodType[] additionalBridges)
   5.147 -            throws LambdaConversionException {
   5.148 -        super(caller, invokedType, samMethodName, samMethodType,
   5.149 -              implMethod, instantiatedMethodType,
   5.150 -              isSerializable, markerInterfaces, additionalBridges);
   5.151 -        implMethodClassName = implDefiningClass.getName().replace('.', '/');
   5.152 -        implMethodName = implInfo.getName();
   5.153 -        implMethodDesc = implMethodType.toMethodDescriptorString();
   5.154 -        implMethodReturnClass = (implKind == MethodHandleInfo.REF_newInvokeSpecial)
   5.155 -                ? implDefiningClass
   5.156 -                : implMethodType.returnType();
   5.157 -        constructorType = invokedType.changeReturnType(Void.TYPE);
   5.158 -        lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
   5.159 -        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
   5.160 -        int parameterCount = invokedType.parameterCount();
   5.161 -        if (parameterCount > 0) {
   5.162 -            argNames = new String[parameterCount];
   5.163 -            argDescs = new String[parameterCount];
   5.164 -            for (int i = 0; i < parameterCount; i++) {
   5.165 -                argNames[i] = "arg$" + (i + 1);
   5.166 -                argDescs[i] = BytecodeDescriptor.unparse(invokedType.parameterType(i));
   5.167 -            }
   5.168 -        } else {
   5.169 -            argNames = argDescs = EMPTY_STRING_ARRAY;
   5.170 -        }
   5.171 -    }
   5.172 -
   5.173 -    /**
   5.174 -     * Build the CallSite. Generate a class file which implements the functional
   5.175 -     * interface, define the class, if there are no parameters create an instance
   5.176 -     * of the class which the CallSite will return, otherwise, generate handles
   5.177 -     * which will call the class' constructor.
   5.178 -     *
   5.179 -     * @return a CallSite, which, when invoked, will return an instance of the
   5.180 -     * functional interface
   5.181 -     * @throws ReflectiveOperationException
   5.182 -     * @throws LambdaConversionException If properly formed functional interface
   5.183 -     * is not found
   5.184 -     */
   5.185 -    @Override
   5.186 -    CallSite buildCallSite() throws LambdaConversionException {
   5.187 -        final Class<?> innerClass = spinInnerClass();
   5.188 -        if (invokedType.parameterCount() == 0) {
   5.189 -            final Constructor[] ctrs = AccessController.doPrivileged(
   5.190 -                    new PrivilegedAction<Constructor[]>() {
   5.191 -                @Override
   5.192 -                public Constructor[] run() {
   5.193 -                    Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
   5.194 -                    if (ctrs.length == 1) {
   5.195 -                        // The lambda implementing inner class constructor is private, set
   5.196 -                        // it accessible (by us) before creating the constant sole instance
   5.197 -                        ctrs[0].setAccessible(true);
   5.198 -                    }
   5.199 -                    return ctrs;
   5.200 -                }
   5.201 -                    });
   5.202 -            if (ctrs.length != 1) {
   5.203 -                throw new LambdaConversionException("Expected one lambda constructor for "
   5.204 -                        + innerClass.getCanonicalName() + ", got " + ctrs.length);
   5.205 -            }
   5.206 -
   5.207 -            try {
   5.208 -                Object inst = ctrs[0].newInstance();
   5.209 -                return new ConstantCallSite(MethodHandles.constant(samBase, inst));
   5.210 -            }
   5.211 -            catch (ReflectiveOperationException e) {
   5.212 -                throw new LambdaConversionException("Exception instantiating lambda object", e);
   5.213 -            }
   5.214 -        } else {
   5.215 -            try {
   5.216 -                UNSAFE.ensureClassInitialized(innerClass);
   5.217 -                return new ConstantCallSite(
   5.218 -                        MethodHandles.Lookup.IMPL_LOOKUP
   5.219 -                             .findStatic(innerClass, NAME_FACTORY, invokedType));
   5.220 -            }
   5.221 -            catch (ReflectiveOperationException e) {
   5.222 -                throw new LambdaConversionException("Exception finding constructor", e);
   5.223 -            }
   5.224 -        }
   5.225 -    }
   5.226 -
   5.227 -    /**
   5.228 -     * Generate a class file which implements the functional
   5.229 -     * interface, define and return the class.
   5.230 -     *
   5.231 -     * @implNote The class that is generated does not include signature
   5.232 -     * information for exceptions that may be present on the SAM method.
   5.233 -     * This is to reduce classfile size, and is harmless as checked exceptions
   5.234 -     * are erased anyway, no one will ever compile against this classfile,
   5.235 -     * and we make no guarantees about the reflective properties of lambda
   5.236 -     * objects.
   5.237 -     *
   5.238 -     * @return a Class which implements the functional interface
   5.239 -     * @throws LambdaConversionException If properly formed functional interface
   5.240 -     * is not found
   5.241 -     */
   5.242 -    private Class<?> spinInnerClass() throws LambdaConversionException {
   5.243 -        String[] interfaces;
   5.244 -        String samIntf = samBase.getName().replace('.', '/');
   5.245 -        boolean accidentallySerializable = !isSerializable && Serializable.class.isAssignableFrom(samBase);
   5.246 -        if (markerInterfaces.length == 0) {
   5.247 -            interfaces = new String[]{samIntf};
   5.248 -        } else {
   5.249 -            // Assure no duplicate interfaces (ClassFormatError)
   5.250 -            Set<String> itfs = new LinkedHashSet<>(markerInterfaces.length + 1);
   5.251 -            itfs.add(samIntf);
   5.252 -            for (Class<?> markerInterface : markerInterfaces) {
   5.253 -                itfs.add(markerInterface.getName().replace('.', '/'));
   5.254 -                accidentallySerializable |= !isSerializable && Serializable.class.isAssignableFrom(markerInterface);
   5.255 -            }
   5.256 -            interfaces = itfs.toArray(new String[itfs.size()]);
   5.257 -        }
   5.258 -
   5.259 -        cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
   5.260 -                 lambdaClassName, null,
   5.261 -                 JAVA_LANG_OBJECT, interfaces);
   5.262 -
   5.263 -        // Generate final fields to be filled in by constructor
   5.264 -        for (int i = 0; i < argDescs.length; i++) {
   5.265 -            FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL,
   5.266 -                                            argNames[i],
   5.267 -                                            argDescs[i],
   5.268 -                                            null, null);
   5.269 -            fv.visitEnd();
   5.270 -        }
   5.271 -
   5.272 -        generateConstructor();
   5.273 -
   5.274 -        if (invokedType.parameterCount() != 0) {
   5.275 -            generateFactory();
   5.276 -        }
   5.277 -
   5.278 -        // Forward the SAM method
   5.279 -        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
   5.280 -                                          samMethodType.toMethodDescriptorString(), null, null);
   5.281 -        new ForwardingMethodGenerator(mv).generate(samMethodType);
   5.282 -
   5.283 -        // Forward the bridges
   5.284 -        if (additionalBridges != null) {
   5.285 -            for (MethodType mt : additionalBridges) {
   5.286 -                mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
   5.287 -                                    mt.toMethodDescriptorString(), null, null);
   5.288 -                new ForwardingMethodGenerator(mv).generate(mt);
   5.289 -            }
   5.290 -        }
   5.291 -
   5.292 -        if (isSerializable)
   5.293 -            generateSerializationFriendlyMethods();
   5.294 -        else if (accidentallySerializable)
   5.295 -            generateSerializationHostileMethods();
   5.296 -
   5.297 -        cw.visitEnd();
   5.298 -
   5.299 -        // Define the generated class in this VM.
   5.300 -
   5.301 -        final byte[] classBytes = cw.toByteArray();
   5.302 -
   5.303 -        // If requested, dump out to a file for debugging purposes
   5.304 -        if (dumper != null) {
   5.305 -            AccessController.doPrivileged(new PrivilegedAction<Void>() {
   5.306 -                @Override
   5.307 -                public Void run() {
   5.308 -                    dumper.dumpClass(lambdaClassName, classBytes);
   5.309 -                    return null;
   5.310 -                }
   5.311 -            }, null,
   5.312 -            new FilePermission("<<ALL FILES>>", "read, write"),
   5.313 -            // createDirectories may need it
   5.314 -            new PropertyPermission("user.dir", "read"));
   5.315 -        }
   5.316 -
   5.317 -        return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
   5.318 -    }
   5.319 -
   5.320 -    /**
   5.321 -     * Generate the factory method for the class
   5.322 -     */
   5.323 -    private void generateFactory() {
   5.324 -        MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
   5.325 -        m.visitCode();
   5.326 -        m.visitTypeInsn(NEW, lambdaClassName);
   5.327 -        m.visitInsn(Opcodes.DUP);
   5.328 -        int parameterCount = invokedType.parameterCount();
   5.329 -        for (int typeIndex = 0, varIndex = 0; typeIndex < parameterCount; typeIndex++) {
   5.330 -            Class<?> argType = invokedType.parameterType(typeIndex);
   5.331 -            m.visitVarInsn(getLoadOpcode(argType), varIndex);
   5.332 -            varIndex += getParameterSize(argType);
   5.333 -        }
   5.334 -        m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorType.toMethodDescriptorString());
   5.335 -        m.visitInsn(ARETURN);
   5.336 -        m.visitMaxs(-1, -1);
   5.337 -        m.visitEnd();
   5.338 -    }
   5.339 -
   5.340 -    /**
   5.341 -     * Generate the constructor for the class
   5.342 -     */
   5.343 -    private void generateConstructor() {
   5.344 -        // Generate constructor
   5.345 -        MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR,
   5.346 -                                            constructorType.toMethodDescriptorString(), null, null);
   5.347 -        ctor.visitCode();
   5.348 -        ctor.visitVarInsn(ALOAD, 0);
   5.349 -        ctor.visitMethodInsn(INVOKESPECIAL, JAVA_LANG_OBJECT, NAME_CTOR,
   5.350 -                             METHOD_DESCRIPTOR_VOID);
   5.351 -        int parameterCount = invokedType.parameterCount();
   5.352 -        for (int i = 0, lvIndex = 0; i < parameterCount; i++) {
   5.353 -            ctor.visitVarInsn(ALOAD, 0);
   5.354 -            Class<?> argType = invokedType.parameterType(i);
   5.355 -            ctor.visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
   5.356 -            lvIndex += getParameterSize(argType);
   5.357 -            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argDescs[i]);
   5.358 -        }
   5.359 -        ctor.visitInsn(RETURN);
   5.360 -        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
   5.361 -        ctor.visitMaxs(-1, -1);
   5.362 -        ctor.visitEnd();
   5.363 -    }
   5.364 -
   5.365 -    /**
   5.366 -     * Generate a writeReplace method that supports serialization
   5.367 -     */
   5.368 -    private void generateSerializationFriendlyMethods() {
   5.369 -        TypeConvertingMethodAdapter mv
   5.370 -                = new TypeConvertingMethodAdapter(
   5.371 -                    cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
   5.372 -                    NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE,
   5.373 -                    null, null));
   5.374 -
   5.375 -        mv.visitCode();
   5.376 -        mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA);
   5.377 -        mv.visitInsn(DUP);
   5.378 -        mv.visitLdcInsn(Type.getType(targetClass));
   5.379 -        mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/'));
   5.380 -        mv.visitLdcInsn(samMethodName);
   5.381 -        mv.visitLdcInsn(samMethodType.toMethodDescriptorString());
   5.382 -        mv.visitLdcInsn(implInfo.getReferenceKind());
   5.383 -        mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/'));
   5.384 -        mv.visitLdcInsn(implInfo.getName());
   5.385 -        mv.visitLdcInsn(implInfo.getMethodType().toMethodDescriptorString());
   5.386 -        mv.visitLdcInsn(instantiatedMethodType.toMethodDescriptorString());
   5.387 -        mv.iconst(argDescs.length);
   5.388 -        mv.visitTypeInsn(ANEWARRAY, JAVA_LANG_OBJECT);
   5.389 -        for (int i = 0; i < argDescs.length; i++) {
   5.390 -            mv.visitInsn(DUP);
   5.391 -            mv.iconst(i);
   5.392 -            mv.visitVarInsn(ALOAD, 0);
   5.393 -            mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argDescs[i]);
   5.394 -            mv.boxIfTypePrimitive(Type.getType(argDescs[i]));
   5.395 -            mv.visitInsn(AASTORE);
   5.396 -        }
   5.397 -        mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
   5.398 -                DESCR_CTOR_SERIALIZED_LAMBDA);
   5.399 -        mv.visitInsn(ARETURN);
   5.400 -        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
   5.401 -        mv.visitMaxs(-1, -1);
   5.402 -        mv.visitEnd();
   5.403 -    }
   5.404 -
   5.405 -    /**
   5.406 -     * Generate a readObject/writeObject method that is hostile to serialization
   5.407 -     */
   5.408 -    private void generateSerializationHostileMethods() {
   5.409 -        MethodVisitor mv = cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
   5.410 -                                          NAME_METHOD_WRITE_OBJECT, DESCR_METHOD_WRITE_OBJECT,
   5.411 -                                          null, SER_HOSTILE_EXCEPTIONS);
   5.412 -        mv.visitCode();
   5.413 -        mv.visitTypeInsn(NEW, NAME_NOT_SERIALIZABLE_EXCEPTION);
   5.414 -        mv.visitInsn(DUP);
   5.415 -        mv.visitLdcInsn("Non-serializable lambda");
   5.416 -        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
   5.417 -                           DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION);
   5.418 -        mv.visitInsn(ATHROW);
   5.419 -        mv.visitMaxs(-1, -1);
   5.420 -        mv.visitEnd();
   5.421 -
   5.422 -        mv = cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
   5.423 -                            NAME_METHOD_READ_OBJECT, DESCR_METHOD_READ_OBJECT,
   5.424 -                            null, SER_HOSTILE_EXCEPTIONS);
   5.425 -        mv.visitCode();
   5.426 -        mv.visitTypeInsn(NEW, NAME_NOT_SERIALIZABLE_EXCEPTION);
   5.427 -        mv.visitInsn(DUP);
   5.428 -        mv.visitLdcInsn("Non-serializable lambda");
   5.429 -        mv.visitMethodInsn(INVOKESPECIAL, NAME_NOT_SERIALIZABLE_EXCEPTION, NAME_CTOR,
   5.430 -                           DESCR_CTOR_NOT_SERIALIZABLE_EXCEPTION);
   5.431 -        mv.visitInsn(ATHROW);
   5.432 -        mv.visitMaxs(-1, -1);
   5.433 -        mv.visitEnd();
   5.434 -    }
   5.435 -
   5.436 -    /**
   5.437 -     * This class generates a method body which calls the lambda implementation
   5.438 -     * method, converting arguments, as needed.
   5.439 -     */
   5.440 -    private class ForwardingMethodGenerator extends TypeConvertingMethodAdapter {
   5.441 -
   5.442 -        ForwardingMethodGenerator(MethodVisitor mv) {
   5.443 -            super(mv);
   5.444 -        }
   5.445 -
   5.446 -        void generate(MethodType methodType) {
   5.447 -            visitCode();
   5.448 -
   5.449 -            if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
   5.450 -                visitTypeInsn(NEW, implMethodClassName);
   5.451 -                visitInsn(DUP);
   5.452 -            }
   5.453 -            for (int i = 0; i < argNames.length; i++) {
   5.454 -                visitVarInsn(ALOAD, 0);
   5.455 -                visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argDescs[i]);
   5.456 -            }
   5.457 -
   5.458 -            convertArgumentTypes(methodType);
   5.459 -
   5.460 -            // Invoke the method we want to forward to
   5.461 -            visitMethodInsn(invocationOpcode(), implMethodClassName,
   5.462 -                            implMethodName, implMethodDesc,
   5.463 -                            implDefiningClass.isInterface());
   5.464 -
   5.465 -            // Convert the return value (if any) and return it
   5.466 -            // Note: if adapting from non-void to void, the 'return'
   5.467 -            // instruction will pop the unneeded result
   5.468 -            Class<?> samReturnClass = methodType.returnType();
   5.469 -            convertType(implMethodReturnClass, samReturnClass, samReturnClass);
   5.470 -            visitInsn(getReturnOpcode(samReturnClass));
   5.471 -            // Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored
   5.472 -            visitMaxs(-1, -1);
   5.473 -            visitEnd();
   5.474 -        }
   5.475 -
   5.476 -        private void convertArgumentTypes(MethodType samType) {
   5.477 -            int lvIndex = 0;
   5.478 -            boolean samIncludesReceiver = implIsInstanceMethod &&
   5.479 -                                                   invokedType.parameterCount() == 0;
   5.480 -            int samReceiverLength = samIncludesReceiver ? 1 : 0;
   5.481 -            if (samIncludesReceiver) {
   5.482 -                // push receiver
   5.483 -                Class<?> rcvrType = samType.parameterType(0);
   5.484 -                visitVarInsn(getLoadOpcode(rcvrType), lvIndex + 1);
   5.485 -                lvIndex += getParameterSize(rcvrType);
   5.486 -                convertType(rcvrType, implDefiningClass, instantiatedMethodType.parameterType(0));
   5.487 -            }
   5.488 -            int samParametersLength = samType.parameterCount();
   5.489 -            int argOffset = implMethodType.parameterCount() - samParametersLength;
   5.490 -            for (int i = samReceiverLength; i < samParametersLength; i++) {
   5.491 -                Class<?> argType = samType.parameterType(i);
   5.492 -                visitVarInsn(getLoadOpcode(argType), lvIndex + 1);
   5.493 -                lvIndex += getParameterSize(argType);
   5.494 -                convertType(argType, implMethodType.parameterType(argOffset + i), instantiatedMethodType.parameterType(i));
   5.495 -            }
   5.496 -        }
   5.497 -
   5.498 -        private int invocationOpcode() throws InternalError {
   5.499 -            switch (implKind) {
   5.500 -                case MethodHandleInfo.REF_invokeStatic:
   5.501 -                    return INVOKESTATIC;
   5.502 -                case MethodHandleInfo.REF_newInvokeSpecial:
   5.503 -                    return INVOKESPECIAL;
   5.504 -                 case MethodHandleInfo.REF_invokeVirtual:
   5.505 -                    return INVOKEVIRTUAL;
   5.506 -                case MethodHandleInfo.REF_invokeInterface:
   5.507 -                    return INVOKEINTERFACE;
   5.508 -                case MethodHandleInfo.REF_invokeSpecial:
   5.509 -                    return INVOKESPECIAL;
   5.510 -                default:
   5.511 -                    throw new InternalError("Unexpected invocation kind: " + implKind);
   5.512 -            }
   5.513 -        }
   5.514 -    }
   5.515 -
   5.516 -    static int getParameterSize(Class<?> c) {
   5.517 -        if (c == Void.TYPE) {
   5.518 -            return 0;
   5.519 -        } else if (c == Long.TYPE || c == Double.TYPE) {
   5.520 -            return 2;
   5.521 -        }
   5.522 -        return 1;
   5.523 -    }
   5.524 -
   5.525 -    static int getLoadOpcode(Class<?> c) {
   5.526 -        if(c == Void.TYPE) {
   5.527 -            throw new InternalError("Unexpected void type of load opcode");
   5.528 -        }
   5.529 -        return ILOAD + getOpcodeOffset(c);
   5.530 -    }
   5.531 -
   5.532 -    static int getReturnOpcode(Class<?> c) {
   5.533 -        if(c == Void.TYPE) {
   5.534 -            return RETURN;
   5.535 -        }
   5.536 -        return IRETURN + getOpcodeOffset(c);
   5.537 -    }
   5.538 -
   5.539 -    private static int getOpcodeOffset(Class<?> c) {
   5.540 -        if (c.isPrimitive()) {
   5.541 -            if (c == Long.TYPE) {
   5.542 -                return 1;
   5.543 -            } else if (c == Float.TYPE) {
   5.544 -                return 2;
   5.545 -            } else if (c == Double.TYPE) {
   5.546 -                return 3;
   5.547 -            }
   5.548 -            return 0;
   5.549 -        } else {
   5.550 -            return 4;
   5.551 -        }
   5.552 -    }
   5.553 -
   5.554 -}
     6.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/InvokerBytecodeGenerator.java	Sun Aug 10 06:21:50 2014 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,1052 +0,0 @@
     6.4 -/*
     6.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     6.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 - *
     6.8 - * This code is free software; you can redistribute it and/or modify it
     6.9 - * under the terms of the GNU General Public License version 2 only, as
    6.10 - * published by the Free Software Foundation.  Oracle designates this
    6.11 - * particular file as subject to the "Classpath" exception as provided
    6.12 - * by Oracle in the LICENSE file that accompanied this code.
    6.13 - *
    6.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 - * version 2 for more details (a copy is included in the LICENSE file that
    6.18 - * accompanied this code).
    6.19 - *
    6.20 - * You should have received a copy of the GNU General Public License version
    6.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 - *
    6.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 - * or visit www.oracle.com if you need additional information or have any
    6.26 - * questions.
    6.27 - */
    6.28 -
    6.29 -package java.lang.invoke;
    6.30 -
    6.31 -import sun.invoke.util.VerifyAccess;
    6.32 -import java.lang.invoke.LambdaForm.Name;
    6.33 -import java.lang.invoke.MethodHandles.Lookup;
    6.34 -
    6.35 -import sun.invoke.util.Wrapper;
    6.36 -
    6.37 -import java.io.*;
    6.38 -import java.util.*;
    6.39 -
    6.40 -import jdk.internal.org.objectweb.asm.*;
    6.41 -
    6.42 -import java.lang.reflect.*;
    6.43 -import static java.lang.invoke.MethodHandleStatics.*;
    6.44 -import static java.lang.invoke.MethodHandleNatives.Constants.*;
    6.45 -import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
    6.46 -import sun.invoke.util.ValueConversions;
    6.47 -import sun.invoke.util.VerifyType;
    6.48 -
    6.49 -/**
    6.50 - * Code generation backend for LambdaForm.
    6.51 - * <p>
    6.52 - * @author John Rose, JSR 292 EG
    6.53 - */
    6.54 -class InvokerBytecodeGenerator {
    6.55 -    /** Define class names for convenience. */
    6.56 -    private static final String MH      = "java/lang/invoke/MethodHandle";
    6.57 -    private static final String BMH     = "java/lang/invoke/BoundMethodHandle";
    6.58 -    private static final String LF      = "java/lang/invoke/LambdaForm";
    6.59 -    private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
    6.60 -    private static final String CLS     = "java/lang/Class";
    6.61 -    private static final String OBJ     = "java/lang/Object";
    6.62 -    private static final String OBJARY  = "[Ljava/lang/Object;";
    6.63 -
    6.64 -    private static final String LF_SIG  = "L" + LF + ";";
    6.65 -    private static final String LFN_SIG = "L" + LFN + ";";
    6.66 -    private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
    6.67 -
    6.68 -    /** Name of its super class*/
    6.69 -    private static final String superName = LF;
    6.70 -
    6.71 -    /** Name of new class */
    6.72 -    private final String className;
    6.73 -
    6.74 -    /** Name of the source file (for stack trace printing). */
    6.75 -    private final String sourceFile;
    6.76 -
    6.77 -    private final LambdaForm lambdaForm;
    6.78 -    private final String     invokerName;
    6.79 -    private final MethodType invokerType;
    6.80 -    private final int[] localsMap;
    6.81 -
    6.82 -    /** ASM bytecode generation. */
    6.83 -    private ClassWriter cw;
    6.84 -    private MethodVisitor mv;
    6.85 -
    6.86 -    private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
    6.87 -    private static final Class<?> HOST_CLASS = LambdaForm.class;
    6.88 -
    6.89 -    private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
    6.90 -                                     String className, String invokerName, MethodType invokerType) {
    6.91 -        if (invokerName.contains(".")) {
    6.92 -            int p = invokerName.indexOf(".");
    6.93 -            className = invokerName.substring(0, p);
    6.94 -            invokerName = invokerName.substring(p+1);
    6.95 -        }
    6.96 -        if (DUMP_CLASS_FILES) {
    6.97 -            className = makeDumpableClassName(className);
    6.98 -        }
    6.99 -        this.className  = superName + "$" + className;
   6.100 -        this.sourceFile = "LambdaForm$" + className;
   6.101 -        this.lambdaForm = lambdaForm;
   6.102 -        this.invokerName = invokerName;
   6.103 -        this.invokerType = invokerType;
   6.104 -        this.localsMap = new int[localsMapSize];
   6.105 -    }
   6.106 -
   6.107 -    private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
   6.108 -        this(null, invokerType.parameterCount(),
   6.109 -             className, invokerName, invokerType);
   6.110 -        // Create an array to map name indexes to locals indexes.
   6.111 -        for (int i = 0; i < localsMap.length; i++) {
   6.112 -            localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
   6.113 -        }
   6.114 -    }
   6.115 -
   6.116 -    private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
   6.117 -        this(form, form.names.length,
   6.118 -             className, form.debugName, invokerType);
   6.119 -        // Create an array to map name indexes to locals indexes.
   6.120 -        Name[] names = form.names;
   6.121 -        for (int i = 0, index = 0; i < localsMap.length; i++) {
   6.122 -            localsMap[i] = index;
   6.123 -            index += Wrapper.forBasicType(names[i].type).stackSlots();
   6.124 -        }
   6.125 -    }
   6.126 -
   6.127 -
   6.128 -    /** instance counters for dumped classes */
   6.129 -    private final static HashMap<String,Integer> DUMP_CLASS_FILES_COUNTERS;
   6.130 -    /** debugging flag for saving generated class files */
   6.131 -    private final static File DUMP_CLASS_FILES_DIR;
   6.132 -
   6.133 -    static {
   6.134 -        if (DUMP_CLASS_FILES) {
   6.135 -            DUMP_CLASS_FILES_COUNTERS = new HashMap<>();
   6.136 -            try {
   6.137 -                File dumpDir = new File("DUMP_CLASS_FILES");
   6.138 -                if (!dumpDir.exists()) {
   6.139 -                    dumpDir.mkdirs();
   6.140 -                }
   6.141 -                DUMP_CLASS_FILES_DIR = dumpDir;
   6.142 -                System.out.println("Dumping class files to "+DUMP_CLASS_FILES_DIR+"/...");
   6.143 -            } catch (Exception e) {
   6.144 -                throw newInternalError(e);
   6.145 -            }
   6.146 -        } else {
   6.147 -            DUMP_CLASS_FILES_COUNTERS = null;
   6.148 -            DUMP_CLASS_FILES_DIR = null;
   6.149 -        }
   6.150 -    }
   6.151 -
   6.152 -    static void maybeDump(final String className, final byte[] classFile) {
   6.153 -        if (DUMP_CLASS_FILES) {
   6.154 -            System.out.println("dump: " + className);
   6.155 -            java.security.AccessController.doPrivileged(
   6.156 -            new java.security.PrivilegedAction<Void>() {
   6.157 -                public Void run() {
   6.158 -                    try {
   6.159 -                        String dumpName = className;
   6.160 -                        //dumpName = dumpName.replace('/', '-');
   6.161 -                        File dumpFile = new File(DUMP_CLASS_FILES_DIR, dumpName+".class");
   6.162 -                        dumpFile.getParentFile().mkdirs();
   6.163 -                        FileOutputStream file = new FileOutputStream(dumpFile);
   6.164 -                        file.write(classFile);
   6.165 -                        file.close();
   6.166 -                        return null;
   6.167 -                    } catch (IOException ex) {
   6.168 -                        throw newInternalError(ex);
   6.169 -                    }
   6.170 -                }
   6.171 -            });
   6.172 -        }
   6.173 -
   6.174 -    }
   6.175 -
   6.176 -    private static String makeDumpableClassName(String className) {
   6.177 -        Integer ctr;
   6.178 -        synchronized (DUMP_CLASS_FILES_COUNTERS) {
   6.179 -            ctr = DUMP_CLASS_FILES_COUNTERS.get(className);
   6.180 -            if (ctr == null)  ctr = 0;
   6.181 -            DUMP_CLASS_FILES_COUNTERS.put(className, ctr+1);
   6.182 -        }
   6.183 -        String sfx = ctr.toString();
   6.184 -        while (sfx.length() < 3)
   6.185 -            sfx = "0"+sfx;
   6.186 -        className += sfx;
   6.187 -        return className;
   6.188 -    }
   6.189 -
   6.190 -    class CpPatch {
   6.191 -        final int index;
   6.192 -        final String placeholder;
   6.193 -        final Object value;
   6.194 -        CpPatch(int index, String placeholder, Object value) {
   6.195 -            this.index = index;
   6.196 -            this.placeholder = placeholder;
   6.197 -            this.value = value;
   6.198 -        }
   6.199 -        public String toString() {
   6.200 -            return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
   6.201 -        }
   6.202 -    }
   6.203 -
   6.204 -    Map<Object, CpPatch> cpPatches = new HashMap<>();
   6.205 -
   6.206 -    int cph = 0;  // for counting constant placeholders
   6.207 -
   6.208 -    String constantPlaceholder(Object arg) {
   6.209 -        String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
   6.210 -        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + arg.toString() + ">>";  // debugging aid
   6.211 -        if (cpPatches.containsKey(cpPlaceholder)) {
   6.212 -            throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
   6.213 -        }
   6.214 -        // insert placeholder in CP and remember the patch
   6.215 -        int index = cw.newConst((Object) cpPlaceholder);  // TODO check if aready in the constant pool
   6.216 -        cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
   6.217 -        return cpPlaceholder;
   6.218 -    }
   6.219 -
   6.220 -    Object[] cpPatches(byte[] classFile) {
   6.221 -        int size = getConstantPoolSize(classFile);
   6.222 -        Object[] res = new Object[size];
   6.223 -        for (CpPatch p : cpPatches.values()) {
   6.224 -            if (p.index >= size)
   6.225 -                throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
   6.226 -            res[p.index] = p.value;
   6.227 -        }
   6.228 -        return res;
   6.229 -    }
   6.230 -
   6.231 -    /**
   6.232 -     * Extract the number of constant pool entries from a given class file.
   6.233 -     *
   6.234 -     * @param classFile the bytes of the class file in question.
   6.235 -     * @return the number of entries in the constant pool.
   6.236 -     */
   6.237 -    private static int getConstantPoolSize(byte[] classFile) {
   6.238 -        // The first few bytes:
   6.239 -        // u4 magic;
   6.240 -        // u2 minor_version;
   6.241 -        // u2 major_version;
   6.242 -        // u2 constant_pool_count;
   6.243 -        return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
   6.244 -    }
   6.245 -
   6.246 -    /**
   6.247 -     * Extract the MemberName of a newly-defined method.
   6.248 -     */
   6.249 -    private MemberName loadMethod(byte[] classFile) {
   6.250 -        Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile));
   6.251 -        return resolveInvokerMember(invokerClass, invokerName, invokerType);
   6.252 -    }
   6.253 -
   6.254 -    /**
   6.255 -     * Define a given class as anonymous class in the runtime system.
   6.256 -     */
   6.257 -    private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) {
   6.258 -        Class<?> invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches);
   6.259 -        UNSAFE.ensureClassInitialized(invokerClass);  // Make sure the class is initialized; VM might complain.
   6.260 -        return invokerClass;
   6.261 -    }
   6.262 -
   6.263 -    private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
   6.264 -        MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
   6.265 -        //System.out.println("resolveInvokerMember => "+member);
   6.266 -        //for (Method m : invokerClass.getDeclaredMethods())  System.out.println("  "+m);
   6.267 -        try {
   6.268 -            member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member, HOST_CLASS, ReflectiveOperationException.class);
   6.269 -        } catch (ReflectiveOperationException e) {
   6.270 -            throw newInternalError(e);
   6.271 -        }
   6.272 -        //System.out.println("resolveInvokerMember => "+member);
   6.273 -        return member;
   6.274 -    }
   6.275 -
   6.276 -    /**
   6.277 -     * Set up class file generation.
   6.278 -     */
   6.279 -    private void classFilePrologue() {
   6.280 -        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
   6.281 -        cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null);
   6.282 -        cw.visitSource(sourceFile, null);
   6.283 -
   6.284 -        String invokerDesc = invokerType.toMethodDescriptorString();
   6.285 -        mv = cw.visitMethod(Opcodes.ACC_STATIC, invokerName, invokerDesc, null, null);
   6.286 -    }
   6.287 -
   6.288 -    /**
   6.289 -     * Tear down class file generation.
   6.290 -     */
   6.291 -    private void classFileEpilogue() {
   6.292 -        mv.visitMaxs(0, 0);
   6.293 -        mv.visitEnd();
   6.294 -    }
   6.295 -
   6.296 -    /*
   6.297 -     * Low-level emit helpers.
   6.298 -     */
   6.299 -    private void emitConst(Object con) {
   6.300 -        if (con == null) {
   6.301 -            mv.visitInsn(Opcodes.ACONST_NULL);
   6.302 -            return;
   6.303 -        }
   6.304 -        if (con instanceof Integer) {
   6.305 -            emitIconstInsn((int) con);
   6.306 -            return;
   6.307 -        }
   6.308 -        if (con instanceof Long) {
   6.309 -            long x = (long) con;
   6.310 -            if (x == (short) x) {
   6.311 -                emitIconstInsn((int) x);
   6.312 -                mv.visitInsn(Opcodes.I2L);
   6.313 -                return;
   6.314 -            }
   6.315 -        }
   6.316 -        if (con instanceof Float) {
   6.317 -            float x = (float) con;
   6.318 -            if (x == (short) x) {
   6.319 -                emitIconstInsn((int) x);
   6.320 -                mv.visitInsn(Opcodes.I2F);
   6.321 -                return;
   6.322 -            }
   6.323 -        }
   6.324 -        if (con instanceof Double) {
   6.325 -            double x = (double) con;
   6.326 -            if (x == (short) x) {
   6.327 -                emitIconstInsn((int) x);
   6.328 -                mv.visitInsn(Opcodes.I2D);
   6.329 -                return;
   6.330 -            }
   6.331 -        }
   6.332 -        if (con instanceof Boolean) {
   6.333 -            emitIconstInsn((boolean) con ? 1 : 0);
   6.334 -            return;
   6.335 -        }
   6.336 -        // fall through:
   6.337 -        mv.visitLdcInsn(con);
   6.338 -    }
   6.339 -
   6.340 -    private void emitIconstInsn(int i) {
   6.341 -        int opcode;
   6.342 -        switch (i) {
   6.343 -        case 0:  opcode = Opcodes.ICONST_0;  break;
   6.344 -        case 1:  opcode = Opcodes.ICONST_1;  break;
   6.345 -        case 2:  opcode = Opcodes.ICONST_2;  break;
   6.346 -        case 3:  opcode = Opcodes.ICONST_3;  break;
   6.347 -        case 4:  opcode = Opcodes.ICONST_4;  break;
   6.348 -        case 5:  opcode = Opcodes.ICONST_5;  break;
   6.349 -        default:
   6.350 -            if (i == (byte) i) {
   6.351 -                mv.visitIntInsn(Opcodes.BIPUSH, i & 0xFF);
   6.352 -            } else if (i == (short) i) {
   6.353 -                mv.visitIntInsn(Opcodes.SIPUSH, (char) i);
   6.354 -            } else {
   6.355 -                mv.visitLdcInsn(i);
   6.356 -            }
   6.357 -            return;
   6.358 -        }
   6.359 -        mv.visitInsn(opcode);
   6.360 -    }
   6.361 -
   6.362 -    /*
   6.363 -     * NOTE: These load/store methods use the localsMap to find the correct index!
   6.364 -     */
   6.365 -    private void emitLoadInsn(char type, int index) {
   6.366 -        int opcode;
   6.367 -        switch (type) {
   6.368 -        case 'I':  opcode = Opcodes.ILOAD;  break;
   6.369 -        case 'J':  opcode = Opcodes.LLOAD;  break;
   6.370 -        case 'F':  opcode = Opcodes.FLOAD;  break;
   6.371 -        case 'D':  opcode = Opcodes.DLOAD;  break;
   6.372 -        case 'L':  opcode = Opcodes.ALOAD;  break;
   6.373 -        default:
   6.374 -            throw new InternalError("unknown type: " + type);
   6.375 -        }
   6.376 -        mv.visitVarInsn(opcode, localsMap[index]);
   6.377 -    }
   6.378 -    private void emitAloadInsn(int index) {
   6.379 -        emitLoadInsn('L', index);
   6.380 -    }
   6.381 -
   6.382 -    private void emitStoreInsn(char type, int index) {
   6.383 -        int opcode;
   6.384 -        switch (type) {
   6.385 -        case 'I':  opcode = Opcodes.ISTORE;  break;
   6.386 -        case 'J':  opcode = Opcodes.LSTORE;  break;
   6.387 -        case 'F':  opcode = Opcodes.FSTORE;  break;
   6.388 -        case 'D':  opcode = Opcodes.DSTORE;  break;
   6.389 -        case 'L':  opcode = Opcodes.ASTORE;  break;
   6.390 -        default:
   6.391 -            throw new InternalError("unknown type: " + type);
   6.392 -        }
   6.393 -        mv.visitVarInsn(opcode, localsMap[index]);
   6.394 -    }
   6.395 -    private void emitAstoreInsn(int index) {
   6.396 -        emitStoreInsn('L', index);
   6.397 -    }
   6.398 -
   6.399 -    /**
   6.400 -     * Emit a boxing call.
   6.401 -     *
   6.402 -     * @param type primitive type class to box.
   6.403 -     */
   6.404 -    private void emitBoxing(Class<?> type) {
   6.405 -        Wrapper wrapper = Wrapper.forPrimitiveType(type);
   6.406 -        String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
   6.407 -        String name  = "valueOf";
   6.408 -        String desc  = "(" + wrapper.basicTypeChar() + ")L" + owner + ";";
   6.409 -        mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
   6.410 -    }
   6.411 -
   6.412 -    /**
   6.413 -     * Emit an unboxing call (plus preceding checkcast).
   6.414 -     *
   6.415 -     * @param type wrapper type class to unbox.
   6.416 -     */
   6.417 -    private void emitUnboxing(Class<?> type) {
   6.418 -        Wrapper wrapper = Wrapper.forWrapperType(type);
   6.419 -        String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
   6.420 -        String name  = wrapper.primitiveSimpleName() + "Value";
   6.421 -        String desc  = "()" + wrapper.basicTypeChar();
   6.422 -        mv.visitTypeInsn(Opcodes.CHECKCAST, owner);
   6.423 -        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
   6.424 -    }
   6.425 -
   6.426 -    /**
   6.427 -     * Emit an implicit conversion.
   6.428 -     *
   6.429 -     * @param ptype type of value present on stack
   6.430 -     * @param pclass type of value required on stack
   6.431 -     */
   6.432 -    private void emitImplicitConversion(char ptype, Class<?> pclass) {
   6.433 -        switch (ptype) {
   6.434 -        case 'L':
   6.435 -            if (VerifyType.isNullConversion(Object.class, pclass))
   6.436 -                return;
   6.437 -            if (isStaticallyNameable(pclass)) {
   6.438 -                mv.visitTypeInsn(Opcodes.CHECKCAST, getInternalName(pclass));
   6.439 -            } else {
   6.440 -                mv.visitLdcInsn(constantPlaceholder(pclass));
   6.441 -                mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
   6.442 -                mv.visitInsn(Opcodes.SWAP);
   6.443 -                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG);
   6.444 -                if (pclass.isArray())
   6.445 -                    mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
   6.446 -            }
   6.447 -            return;
   6.448 -        case 'I':
   6.449 -            if (!VerifyType.isNullConversion(int.class, pclass))
   6.450 -                emitPrimCast(ptype, Wrapper.basicTypeChar(pclass));
   6.451 -            return;
   6.452 -        case 'J':
   6.453 -            assert(pclass == long.class);
   6.454 -            return;
   6.455 -        case 'F':
   6.456 -            assert(pclass == float.class);
   6.457 -            return;
   6.458 -        case 'D':
   6.459 -            assert(pclass == double.class);
   6.460 -            return;
   6.461 -        }
   6.462 -        throw new InternalError("bad implicit conversion: tc="+ptype+": "+pclass);
   6.463 -    }
   6.464 -
   6.465 -    /**
   6.466 -     * Emits an actual return instruction conforming to the given return type.
   6.467 -     */
   6.468 -    private void emitReturnInsn(Class<?> type) {
   6.469 -        int opcode;
   6.470 -        switch (Wrapper.basicTypeChar(type)) {
   6.471 -        case 'I':  opcode = Opcodes.IRETURN;  break;
   6.472 -        case 'J':  opcode = Opcodes.LRETURN;  break;
   6.473 -        case 'F':  opcode = Opcodes.FRETURN;  break;
   6.474 -        case 'D':  opcode = Opcodes.DRETURN;  break;
   6.475 -        case 'L':  opcode = Opcodes.ARETURN;  break;
   6.476 -        case 'V':  opcode = Opcodes.RETURN;   break;
   6.477 -        default:
   6.478 -            throw new InternalError("unknown return type: " + type);
   6.479 -        }
   6.480 -        mv.visitInsn(opcode);
   6.481 -    }
   6.482 -
   6.483 -    private static String getInternalName(Class<?> c) {
   6.484 -        assert(VerifyAccess.isTypeVisible(c, Object.class));
   6.485 -        return c.getName().replace('.', '/');
   6.486 -    }
   6.487 -
   6.488 -    /**
   6.489 -     * Generate customized bytecode for a given LambdaForm.
   6.490 -     */
   6.491 -    static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
   6.492 -        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
   6.493 -        return g.loadMethod(g.generateCustomizedCodeBytes());
   6.494 -    }
   6.495 -
   6.496 -    /**
   6.497 -     * Generate an invoker method for the passed {@link LambdaForm}.
   6.498 -     */
   6.499 -    private byte[] generateCustomizedCodeBytes() {
   6.500 -        classFilePrologue();
   6.501 -
   6.502 -        // Suppress this method in backtraces displayed to the user.
   6.503 -        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
   6.504 -
   6.505 -        // Mark this method as a compiled LambdaForm
   6.506 -        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
   6.507 -
   6.508 -        // Force inlining of this invoker method.
   6.509 -        mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
   6.510 -
   6.511 -        // iterate over the form's names, generating bytecode instructions for each
   6.512 -        // start iterating at the first name following the arguments
   6.513 -        for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
   6.514 -            Name name = lambdaForm.names[i];
   6.515 -            MemberName member = name.function.member();
   6.516 -
   6.517 -            if (isSelectAlternative(member)) {
   6.518 -                // selectAlternative idiom
   6.519 -                // FIXME: make sure this idiom is really present!
   6.520 -                emitSelectAlternative(name, lambdaForm.names[i + 1]);
   6.521 -                i++;  // skip MH.invokeBasic of the selectAlternative result
   6.522 -            } else if (isStaticallyInvocable(member)) {
   6.523 -                emitStaticInvoke(member, name);
   6.524 -            } else {
   6.525 -                emitInvoke(name);
   6.526 -            }
   6.527 -
   6.528 -            // store the result from evaluating to the target name in a local if required
   6.529 -            // (if this is the last value, i.e., the one that is going to be returned,
   6.530 -            // avoid store/load/return and just return)
   6.531 -            if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
   6.532 -                // return value - do nothing
   6.533 -            } else if (name.type != 'V') {
   6.534 -                // non-void: actually assign
   6.535 -                emitStoreInsn(name.type, name.index());
   6.536 -            }
   6.537 -        }
   6.538 -
   6.539 -        // return statement
   6.540 -        emitReturn();
   6.541 -
   6.542 -        classFileEpilogue();
   6.543 -        bogusMethod(lambdaForm);
   6.544 -
   6.545 -        final byte[] classFile = cw.toByteArray();
   6.546 -        maybeDump(className, classFile);
   6.547 -        return classFile;
   6.548 -    }
   6.549 -
   6.550 -    /**
   6.551 -     * Emit an invoke for the given name.
   6.552 -     */
   6.553 -    void emitInvoke(Name name) {
   6.554 -        if (true) {
   6.555 -            // push receiver
   6.556 -            MethodHandle target = name.function.resolvedHandle;
   6.557 -            assert(target != null) : name.exprString();
   6.558 -            mv.visitLdcInsn(constantPlaceholder(target));
   6.559 -            mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
   6.560 -        } else {
   6.561 -            // load receiver
   6.562 -            emitAloadInsn(0);
   6.563 -            mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
   6.564 -            mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
   6.565 -            mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
   6.566 -            // TODO more to come
   6.567 -        }
   6.568 -
   6.569 -        // push arguments
   6.570 -        for (int i = 0; i < name.arguments.length; i++) {
   6.571 -            emitPushArgument(name, i);
   6.572 -        }
   6.573 -
   6.574 -        // invocation
   6.575 -        MethodType type = name.function.methodType();
   6.576 -        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
   6.577 -    }
   6.578 -
   6.579 -    static private Class<?>[] STATICALLY_INVOCABLE_PACKAGES = {
   6.580 -        // Sample classes from each package we are willing to bind to statically:
   6.581 -        java.lang.Object.class,
   6.582 -        java.util.Arrays.class,
   6.583 -        sun.misc.Unsafe.class
   6.584 -        //MethodHandle.class already covered
   6.585 -    };
   6.586 -
   6.587 -    static boolean isStaticallyInvocable(MemberName member) {
   6.588 -        if (member == null)  return false;
   6.589 -        if (member.isConstructor())  return false;
   6.590 -        Class<?> cls = member.getDeclaringClass();
   6.591 -        if (cls.isArray() || cls.isPrimitive())
   6.592 -            return false;  // FIXME
   6.593 -        if (cls.isAnonymousClass() || cls.isLocalClass())
   6.594 -            return false;  // inner class of some sort
   6.595 -        if (cls.getClassLoader() != MethodHandle.class.getClassLoader())
   6.596 -            return false;  // not on BCP
   6.597 -        MethodType mtype = member.getMethodOrFieldType();
   6.598 -        if (!isStaticallyNameable(mtype.returnType()))
   6.599 -            return false;
   6.600 -        for (Class<?> ptype : mtype.parameterArray())
   6.601 -            if (!isStaticallyNameable(ptype))
   6.602 -                return false;
   6.603 -        if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
   6.604 -            return true;   // in java.lang.invoke package
   6.605 -        if (member.isPublic() && isStaticallyNameable(cls))
   6.606 -            return true;
   6.607 -        return false;
   6.608 -    }
   6.609 -
   6.610 -    static boolean isStaticallyNameable(Class<?> cls) {
   6.611 -        while (cls.isArray())
   6.612 -            cls = cls.getComponentType();
   6.613 -        if (cls.isPrimitive())
   6.614 -            return true;  // int[].class, for example
   6.615 -        // could use VerifyAccess.isClassAccessible but the following is a safe approximation
   6.616 -        if (cls.getClassLoader() != Object.class.getClassLoader())
   6.617 -            return false;
   6.618 -        if (VerifyAccess.isSamePackage(MethodHandle.class, cls))
   6.619 -            return true;
   6.620 -        if (!Modifier.isPublic(cls.getModifiers()))
   6.621 -            return false;
   6.622 -        for (Class<?> pkgcls : STATICALLY_INVOCABLE_PACKAGES) {
   6.623 -            if (VerifyAccess.isSamePackage(pkgcls, cls))
   6.624 -                return true;
   6.625 -        }
   6.626 -        return false;
   6.627 -    }
   6.628 -
   6.629 -    /**
   6.630 -     * Emit an invoke for the given name, using the MemberName directly.
   6.631 -     */
   6.632 -    void emitStaticInvoke(MemberName member, Name name) {
   6.633 -        assert(member.equals(name.function.member()));
   6.634 -        String cname = getInternalName(member.getDeclaringClass());
   6.635 -        String mname = member.getName();
   6.636 -        String mtype;
   6.637 -        byte refKind = member.getReferenceKind();
   6.638 -        if (refKind == REF_invokeSpecial) {
   6.639 -            // in order to pass the verifier, we need to convert this to invokevirtual in all cases
   6.640 -            assert(member.canBeStaticallyBound()) : member;
   6.641 -            refKind = REF_invokeVirtual;
   6.642 -        }
   6.643 -
   6.644 -        if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
   6.645 -            // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
   6.646 -            // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
   6.647 -            refKind = REF_invokeInterface;
   6.648 -        }
   6.649 -
   6.650 -        // push arguments
   6.651 -        for (int i = 0; i < name.arguments.length; i++) {
   6.652 -            emitPushArgument(name, i);
   6.653 -        }
   6.654 -
   6.655 -        // invocation
   6.656 -        if (member.isMethod()) {
   6.657 -            mtype = member.getMethodType().toMethodDescriptorString();
   6.658 -            mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
   6.659 -                               member.getDeclaringClass().isInterface());
   6.660 -        } else {
   6.661 -            mtype = MethodType.toFieldDescriptorString(member.getFieldType());
   6.662 -            mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
   6.663 -        }
   6.664 -    }
   6.665 -    int refKindOpcode(byte refKind) {
   6.666 -        switch (refKind) {
   6.667 -        case REF_invokeVirtual:      return Opcodes.INVOKEVIRTUAL;
   6.668 -        case REF_invokeStatic:       return Opcodes.INVOKESTATIC;
   6.669 -        case REF_invokeSpecial:      return Opcodes.INVOKESPECIAL;
   6.670 -        case REF_invokeInterface:    return Opcodes.INVOKEINTERFACE;
   6.671 -        case REF_getField:           return Opcodes.GETFIELD;
   6.672 -        case REF_putField:           return Opcodes.PUTFIELD;
   6.673 -        case REF_getStatic:          return Opcodes.GETSTATIC;
   6.674 -        case REF_putStatic:          return Opcodes.PUTSTATIC;
   6.675 -        }
   6.676 -        throw new InternalError("refKind="+refKind);
   6.677 -    }
   6.678 -
   6.679 -    /**
   6.680 -     * Check if MemberName is a call to MethodHandleImpl.selectAlternative.
   6.681 -     */
   6.682 -    private boolean isSelectAlternative(MemberName member) {
   6.683 -        return member != null &&
   6.684 -               member.getDeclaringClass() == MethodHandleImpl.class &&
   6.685 -               member.getName().equals("selectAlternative");
   6.686 -    }
   6.687 -
   6.688 -    /**
   6.689 -     * Emit bytecode for the selectAlternative idiom.
   6.690 -     *
   6.691 -     * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
   6.692 -     * <blockquote><pre>{@code
   6.693 -     *   Lambda(a0:L,a1:I)=>{
   6.694 -     *     t2:I=foo.test(a1:I);
   6.695 -     *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
   6.696 -     *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
   6.697 -     * }</pre></blockquote>
   6.698 -     */
   6.699 -    private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
   6.700 -        MethodType type = selectAlternativeName.function.methodType();
   6.701 -
   6.702 -        Name receiver = (Name) invokeBasicName.arguments[0];
   6.703 -
   6.704 -        Label L_fallback = new Label();
   6.705 -        Label L_done     = new Label();
   6.706 -
   6.707 -        // load test result
   6.708 -        emitPushArgument(selectAlternativeName, 0);
   6.709 -        mv.visitInsn(Opcodes.ICONST_1);
   6.710 -
   6.711 -        // if_icmpne L_fallback
   6.712 -        mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
   6.713 -
   6.714 -        // invoke selectAlternativeName.arguments[1]
   6.715 -        MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
   6.716 -        emitPushArgument(selectAlternativeName, 1);  // get 2nd argument of selectAlternative
   6.717 -        emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
   6.718 -        emitInvoke(invokeBasicName);
   6.719 -
   6.720 -        // goto L_done
   6.721 -        mv.visitJumpInsn(Opcodes.GOTO, L_done);
   6.722 -
   6.723 -        // L_fallback:
   6.724 -        mv.visitLabel(L_fallback);
   6.725 -
   6.726 -        // invoke selectAlternativeName.arguments[2]
   6.727 -        MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
   6.728 -        emitPushArgument(selectAlternativeName, 2);  // get 3rd argument of selectAlternative
   6.729 -        emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
   6.730 -        emitInvoke(invokeBasicName);
   6.731 -
   6.732 -        // L_done:
   6.733 -        mv.visitLabel(L_done);
   6.734 -    }
   6.735 -
   6.736 -    private void emitPushArgument(Name name, int paramIndex) {
   6.737 -        Object arg = name.arguments[paramIndex];
   6.738 -        char ptype = name.function.parameterType(paramIndex);
   6.739 -        MethodType mtype = name.function.methodType();
   6.740 -        if (arg instanceof Name) {
   6.741 -            Name n = (Name) arg;
   6.742 -            emitLoadInsn(n.type, n.index());
   6.743 -            emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
   6.744 -        } else if ((arg == null || arg instanceof String) && ptype == 'L') {
   6.745 -            emitConst(arg);
   6.746 -        } else {
   6.747 -            if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
   6.748 -                emitConst(arg);
   6.749 -            } else {
   6.750 -                mv.visitLdcInsn(constantPlaceholder(arg));
   6.751 -                emitImplicitConversion('L', mtype.parameterType(paramIndex));
   6.752 -            }
   6.753 -        }
   6.754 -    }
   6.755 -
   6.756 -    /**
   6.757 -     * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
   6.758 -     */
   6.759 -    private void emitReturn() {
   6.760 -        // return statement
   6.761 -        if (lambdaForm.result == -1) {
   6.762 -            // void
   6.763 -            mv.visitInsn(Opcodes.RETURN);
   6.764 -        } else {
   6.765 -            LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
   6.766 -            char rtype = Wrapper.basicTypeChar(invokerType.returnType());
   6.767 -
   6.768 -            // put return value on the stack if it is not already there
   6.769 -            if (lambdaForm.result != lambdaForm.names.length - 1) {
   6.770 -                emitLoadInsn(rn.type, lambdaForm.result);
   6.771 -            }
   6.772 -
   6.773 -            // potentially generate cast
   6.774 -            // rtype is the return type of the invoker - generated code must conform to this
   6.775 -            // rn.type is the type of the result Name in the LF
   6.776 -            if (rtype != rn.type) {
   6.777 -                // need cast
   6.778 -                if (rtype == 'L') {
   6.779 -                    // possibly cast the primitive to the correct type for boxing
   6.780 -                    char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
   6.781 -                    if (boxedType != rn.type) {
   6.782 -                        emitPrimCast(rn.type, boxedType);
   6.783 -                    }
   6.784 -                    // cast primitive to reference ("boxing")
   6.785 -                    emitBoxing(invokerType.returnType());
   6.786 -                } else {
   6.787 -                    // to-primitive cast
   6.788 -                    if (rn.type != 'L') {
   6.789 -                        // prim-to-prim cast
   6.790 -                        emitPrimCast(rn.type, rtype);
   6.791 -                    } else {
   6.792 -                        // ref-to-prim cast ("unboxing")
   6.793 -                        throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
   6.794 -                    }
   6.795 -                }
   6.796 -            }
   6.797 -
   6.798 -            // generate actual return statement
   6.799 -            emitReturnInsn(invokerType.returnType());
   6.800 -        }
   6.801 -    }
   6.802 -
   6.803 -    /**
   6.804 -     * Emit a type conversion bytecode casting from "from" to "to".
   6.805 -     */
   6.806 -    private void emitPrimCast(char from, char to) {
   6.807 -        // Here's how.
   6.808 -        // -   indicates forbidden
   6.809 -        // <-> indicates implicit
   6.810 -        //      to ----> boolean  byte     short    char     int      long     float    double
   6.811 -        // from boolean    <->        -        -        -        -        -        -        -
   6.812 -        //      byte        -       <->       i2s      i2c      <->      i2l      i2f      i2d
   6.813 -        //      short       -       i2b       <->      i2c      <->      i2l      i2f      i2d
   6.814 -        //      char        -       i2b       i2s      <->      <->      i2l      i2f      i2d
   6.815 -        //      int         -       i2b       i2s      i2c      <->      i2l      i2f      i2d
   6.816 -        //      long        -     l2i,i2b   l2i,i2s  l2i,i2c    l2i      <->      l2f      l2d
   6.817 -        //      float       -     f2i,i2b   f2i,i2s  f2i,i2c    f2i      f2l      <->      f2d
   6.818 -        //      double      -     d2i,i2b   d2i,i2s  d2i,i2c    d2i      d2l      d2f      <->
   6.819 -        if (from == to) {
   6.820 -            // no cast required, should be dead code anyway
   6.821 -            return;
   6.822 -        }
   6.823 -        Wrapper wfrom = Wrapper.forBasicType(from);
   6.824 -        Wrapper wto   = Wrapper.forBasicType(to);
   6.825 -        if (wfrom.isSubwordOrInt()) {
   6.826 -            // cast from {byte,short,char,int} to anything
   6.827 -            emitI2X(to);
   6.828 -        } else {
   6.829 -            // cast from {long,float,double} to anything
   6.830 -            if (wto.isSubwordOrInt()) {
   6.831 -                // cast to {byte,short,char,int}
   6.832 -                emitX2I(from);
   6.833 -                if (wto.bitWidth() < 32) {
   6.834 -                    // targets other than int require another conversion
   6.835 -                    emitI2X(to);
   6.836 -                }
   6.837 -            } else {
   6.838 -                // cast to {long,float,double} - this is verbose
   6.839 -                boolean error = false;
   6.840 -                switch (from) {
   6.841 -                case 'J':
   6.842 -                         if (to == 'F') { mv.visitInsn(Opcodes.L2F); }
   6.843 -                    else if (to == 'D') { mv.visitInsn(Opcodes.L2D); }
   6.844 -                    else error = true;
   6.845 -                    break;
   6.846 -                case 'F':
   6.847 -                         if (to == 'J') { mv.visitInsn(Opcodes.F2L); }
   6.848 -                    else if (to == 'D') { mv.visitInsn(Opcodes.F2D); }
   6.849 -                    else error = true;
   6.850 -                    break;
   6.851 -                case 'D':
   6.852 -                         if (to == 'J') { mv.visitInsn(Opcodes.D2L); }
   6.853 -                    else if (to == 'F') { mv.visitInsn(Opcodes.D2F); }
   6.854 -                    else error = true;
   6.855 -                    break;
   6.856 -                default:
   6.857 -                    error = true;
   6.858 -                    break;
   6.859 -                }
   6.860 -                if (error) {
   6.861 -                    throw new IllegalStateException("unhandled prim cast: " + from + "2" + to);
   6.862 -                }
   6.863 -            }
   6.864 -        }
   6.865 -    }
   6.866 -
   6.867 -    private void emitI2X(char type) {
   6.868 -        switch (type) {
   6.869 -        case 'B':  mv.visitInsn(Opcodes.I2B);  break;
   6.870 -        case 'S':  mv.visitInsn(Opcodes.I2S);  break;
   6.871 -        case 'C':  mv.visitInsn(Opcodes.I2C);  break;
   6.872 -        case 'I':  /* naught */                break;
   6.873 -        case 'J':  mv.visitInsn(Opcodes.I2L);  break;
   6.874 -        case 'F':  mv.visitInsn(Opcodes.I2F);  break;
   6.875 -        case 'D':  mv.visitInsn(Opcodes.I2D);  break;
   6.876 -        case 'Z':
   6.877 -            // For compatibility with ValueConversions and explicitCastArguments:
   6.878 -            mv.visitInsn(Opcodes.ICONST_1);
   6.879 -            mv.visitInsn(Opcodes.IAND);
   6.880 -            break;
   6.881 -        default:   throw new InternalError("unknown type: " + type);
   6.882 -        }
   6.883 -    }
   6.884 -
   6.885 -    private void emitX2I(char type) {
   6.886 -        switch (type) {
   6.887 -        case 'J':  mv.visitInsn(Opcodes.L2I);  break;
   6.888 -        case 'F':  mv.visitInsn(Opcodes.F2I);  break;
   6.889 -        case 'D':  mv.visitInsn(Opcodes.D2I);  break;
   6.890 -        default:   throw new InternalError("unknown type: " + type);
   6.891 -        }
   6.892 -    }
   6.893 -
   6.894 -    private static String basicTypeCharSignature(String prefix, MethodType type) {
   6.895 -        StringBuilder buf = new StringBuilder(prefix);
   6.896 -        for (Class<?> ptype : type.parameterList())
   6.897 -            buf.append(Wrapper.forBasicType(ptype).basicTypeChar());
   6.898 -        buf.append('_').append(Wrapper.forBasicType(type.returnType()).basicTypeChar());
   6.899 -        return buf.toString();
   6.900 -    }
   6.901 -
   6.902 -    /**
   6.903 -     * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
   6.904 -     */
   6.905 -    static MemberName generateLambdaFormInterpreterEntryPoint(String sig) {
   6.906 -        assert(LambdaForm.isValidSignature(sig));
   6.907 -        //System.out.println("generateExactInvoker "+sig);
   6.908 -        // compute method type
   6.909 -        // first parameter and return type
   6.910 -        char tret = LambdaForm.signatureReturn(sig);
   6.911 -        MethodType type = MethodType.methodType(LambdaForm.typeClass(tret), MethodHandle.class);
   6.912 -        // other parameter types
   6.913 -        int arity = LambdaForm.signatureArity(sig);
   6.914 -        for (int i = 1; i < arity; i++) {
   6.915 -            type = type.appendParameterTypes(LambdaForm.typeClass(sig.charAt(i)));
   6.916 -        }
   6.917 -        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", "interpret_"+tret, type);
   6.918 -        return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());
   6.919 -    }
   6.920 -
   6.921 -    private byte[] generateLambdaFormInterpreterEntryPointBytes() {
   6.922 -        classFilePrologue();
   6.923 -
   6.924 -        // Suppress this method in backtraces displayed to the user.
   6.925 -        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
   6.926 -
   6.927 -        // Don't inline the interpreter entry.
   6.928 -        mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true);
   6.929 -
   6.930 -        // create parameter array
   6.931 -        emitIconstInsn(invokerType.parameterCount());
   6.932 -        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
   6.933 -
   6.934 -        // fill parameter array
   6.935 -        for (int i = 0; i < invokerType.parameterCount(); i++) {
   6.936 -            Class<?> ptype = invokerType.parameterType(i);
   6.937 -            mv.visitInsn(Opcodes.DUP);
   6.938 -            emitIconstInsn(i);
   6.939 -            emitLoadInsn(Wrapper.basicTypeChar(ptype), i);
   6.940 -            // box if primitive type
   6.941 -            if (ptype.isPrimitive()) {
   6.942 -                emitBoxing(ptype);
   6.943 -            }
   6.944 -            mv.visitInsn(Opcodes.AASTORE);
   6.945 -        }
   6.946 -        // invoke
   6.947 -        emitAloadInsn(0);
   6.948 -        mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", "Ljava/lang/invoke/LambdaForm;");
   6.949 -        mv.visitInsn(Opcodes.SWAP);  // swap form and array; avoid local variable
   6.950 -        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LF, "interpretWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;");
   6.951 -
   6.952 -        // maybe unbox
   6.953 -        Class<?> rtype = invokerType.returnType();
   6.954 -        if (rtype.isPrimitive() && rtype != void.class) {
   6.955 -            emitUnboxing(Wrapper.asWrapperType(rtype));
   6.956 -        }
   6.957 -
   6.958 -        // return statement
   6.959 -        emitReturnInsn(rtype);
   6.960 -
   6.961 -        classFileEpilogue();
   6.962 -        bogusMethod(invokerType);
   6.963 -
   6.964 -        final byte[] classFile = cw.toByteArray();
   6.965 -        maybeDump(className, classFile);
   6.966 -        return classFile;
   6.967 -    }
   6.968 -
   6.969 -    /**
   6.970 -     * Generate bytecode for a NamedFunction invoker.
   6.971 -     */
   6.972 -    static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) {
   6.973 -        MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE;
   6.974 -        String invokerName = basicTypeCharSignature("invoke_", typeForm.erasedType());
   6.975 -        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType);
   6.976 -        return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm));
   6.977 -    }
   6.978 -
   6.979 -    static int nfi = 0;
   6.980 -
   6.981 -    private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
   6.982 -        MethodType dstType = typeForm.erasedType();
   6.983 -        classFilePrologue();
   6.984 -
   6.985 -        // Suppress this method in backtraces displayed to the user.
   6.986 -        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
   6.987 -
   6.988 -        // Force inlining of this invoker method.
   6.989 -        mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
   6.990 -
   6.991 -        // Load receiver
   6.992 -        emitAloadInsn(0);
   6.993 -
   6.994 -        // Load arguments from array
   6.995 -        for (int i = 0; i < dstType.parameterCount(); i++) {
   6.996 -            emitAloadInsn(1);
   6.997 -            emitIconstInsn(i);
   6.998 -            mv.visitInsn(Opcodes.AALOAD);
   6.999 -
  6.1000 -            // Maybe unbox
  6.1001 -            Class<?> dptype = dstType.parameterType(i);
  6.1002 -            if (dptype.isPrimitive()) {
  6.1003 -                Class<?> sptype = dstType.basicType().wrap().parameterType(i);
  6.1004 -                Wrapper dstWrapper = Wrapper.forBasicType(dptype);
  6.1005 -                Wrapper srcWrapper = dstWrapper.isSubwordOrInt() ? Wrapper.INT : dstWrapper;  // narrow subword from int
  6.1006 -                emitUnboxing(srcWrapper.wrapperType());
  6.1007 -                emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
  6.1008 -            }
  6.1009 -        }
  6.1010 -
  6.1011 -        // Invoke
  6.1012 -        String targetDesc = dstType.basicType().toMethodDescriptorString();
  6.1013 -        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", targetDesc);
  6.1014 -
  6.1015 -        // Box primitive types
  6.1016 -        Class<?> rtype = dstType.returnType();
  6.1017 -        if (rtype != void.class && rtype.isPrimitive()) {
  6.1018 -            Wrapper srcWrapper = Wrapper.forBasicType(rtype);
  6.1019 -            Wrapper dstWrapper = srcWrapper.isSubwordOrInt() ? Wrapper.INT : srcWrapper;  // widen subword to int
  6.1020 -            // boolean casts not allowed
  6.1021 -            emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
  6.1022 -            emitBoxing(dstWrapper.primitiveType());
  6.1023 -        }
  6.1024 -
  6.1025 -        // If the return type is void we return a null reference.
  6.1026 -        if (rtype == void.class) {
  6.1027 -            mv.visitInsn(Opcodes.ACONST_NULL);
  6.1028 -        }
  6.1029 -        emitReturnInsn(Object.class);  // NOTE: NamedFunction invokers always return a reference value.
  6.1030 -
  6.1031 -        classFileEpilogue();
  6.1032 -        bogusMethod(dstType);
  6.1033 -
  6.1034 -        final byte[] classFile = cw.toByteArray();
  6.1035 -        maybeDump(className, classFile);
  6.1036 -        return classFile;
  6.1037 -    }
  6.1038 -
  6.1039 -    /**
  6.1040 -     * Emit a bogus method that just loads some string constants. This is to get the constants into the constant pool
  6.1041 -     * for debugging purposes.
  6.1042 -     */
  6.1043 -    private void bogusMethod(Object... os) {
  6.1044 -        if (DUMP_CLASS_FILES) {
  6.1045 -            mv = cw.visitMethod(Opcodes.ACC_STATIC, "dummy", "()V", null, null);
  6.1046 -            for (Object o : os) {
  6.1047 -                mv.visitLdcInsn(o.toString());
  6.1048 -                mv.visitInsn(Opcodes.POP);
  6.1049 -            }
  6.1050 -            mv.visitInsn(Opcodes.RETURN);
  6.1051 -            mv.visitMaxs(0, 0);
  6.1052 -            mv.visitEnd();
  6.1053 -        }
  6.1054 -    }
  6.1055 -}
     7.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/LambdaForm.java	Sun Aug 10 06:21:50 2014 +0200
     7.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/LambdaForm.java	Sun Aug 10 07:02:12 2014 +0200
     7.3 @@ -450,15 +450,16 @@
     7.4          if (vmentry != null && isCompiled) {
     7.5              return vmentry;  // already compiled somehow
     7.6          }
     7.7 -        try {
     7.8 -            vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
     7.9 -            if (TRACE_INTERPRETER)
    7.10 -                traceInterpreter("compileToBytecode", this);
    7.11 -            isCompiled = true;
    7.12 -            return vmentry;
    7.13 -        } catch (Error | Exception ex) {
    7.14 -            throw newInternalError("compileToBytecode", ex);
    7.15 -        }
    7.16 +        throw newInternalError("compileToBytecode", new Exception());
    7.17 +//        try {
    7.18 +//            vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
    7.19 +//            if (TRACE_INTERPRETER)
    7.20 +//                traceInterpreter("compileToBytecode", this);
    7.21 +//            isCompiled = true;
    7.22 +//            return vmentry;
    7.23 +//        } catch (Error | Exception ex) {
    7.24 +//            throw newInternalError("compileToBytecode", ex);
    7.25 +//        }
    7.26      }
    7.27  
    7.28      private static final ConcurrentHashMap<String,LambdaForm> PREPARED_FORMS;
    7.29 @@ -527,7 +528,9 @@
    7.30          if (prep != null)  return prep;
    7.31          assert(isValidSignature(sig));
    7.32          prep = new LambdaForm(sig);
    7.33 -        prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig);
    7.34 +//        prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig);
    7.35 +        if (true) throw new IllegalStateException();
    7.36 +
    7.37          //LambdaForm prep2 = PREPARED_FORMS.putIfAbsent(sig.intern(), prep);
    7.38          return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
    7.39      }
    7.40 @@ -1129,8 +1132,9 @@
    7.41          private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
    7.42              MethodHandle mh = typeForm.namedFunctionInvoker;
    7.43              if (mh != null)  return mh;
    7.44 -            MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm);  // this could take a while
    7.45 -            mh = DirectMethodHandle.make(invoker);
    7.46 +//            MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm);  // this could take a while
    7.47 +            if (true) throw new IllegalStateException();
    7.48 +//            mh = DirectMethodHandle.make(invoker);
    7.49              MethodHandle mh2 = typeForm.namedFunctionInvoker;
    7.50              if (mh2 != null)  return mh2;  // benign race
    7.51              if (!mh.type().equals(INVOKER_METHOD_TYPE))
     8.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/LambdaMetafactory.java	Sun Aug 10 06:21:50 2014 +0200
     8.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/LambdaMetafactory.java	Sun Aug 10 07:02:12 2014 +0200
     8.3 @@ -296,12 +296,13 @@
     8.4                                         MethodType instantiatedMethodType)
     8.5              throws LambdaConversionException {
     8.6          AbstractValidatingLambdaMetafactory mf;
     8.7 -        mf = new InnerClassLambdaMetafactory(caller, invokedType,
     8.8 -                                             invokedName, samMethodType,
     8.9 -                                             implMethod, instantiatedMethodType,
    8.10 -                                             false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
    8.11 -        mf.validateMetafactoryArgs();
    8.12 -        return mf.buildCallSite();
    8.13 +//        mf = new InnerClassLambdaMetafactory(caller, invokedType,
    8.14 +//                                             invokedName, samMethodType,
    8.15 +//                                             implMethod, instantiatedMethodType,
    8.16 +//                                             false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
    8.17 +//        mf.validateMetafactoryArgs();
    8.18 +//        return mf.buildCallSite();
    8.19 +        throw new IllegalStateException();
    8.20      }
    8.21  
    8.22      /**
    8.23 @@ -462,14 +463,15 @@
    8.24              }
    8.25          }
    8.26  
    8.27 -        AbstractValidatingLambdaMetafactory mf
    8.28 -                = new InnerClassLambdaMetafactory(caller, invokedType,
    8.29 -                                                  invokedName, samMethodType,
    8.30 -                                                  implMethod,
    8.31 -                                                  instantiatedMethodType,
    8.32 -                                                  isSerializable,
    8.33 -                                                  markerInterfaces, bridges);
    8.34 -        mf.validateMetafactoryArgs();
    8.35 -        return mf.buildCallSite();
    8.36 +//        AbstractValidatingLambdaMetafactory mf
    8.37 +//                = new InnerClassLambdaMetafactory(caller, invokedType,
    8.38 +//                                                  invokedName, samMethodType,
    8.39 +//                                                  implMethod,
    8.40 +//                                                  instantiatedMethodType,
    8.41 +//                                                  isSerializable,
    8.42 +//                                                  markerInterfaces, bridges);
    8.43 +//        mf.validateMetafactoryArgs();
    8.44 +//        return mf.buildCallSite();
    8.45 +        throw new IllegalStateException();
    8.46      }
    8.47  }
     9.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/TypeConvertingMethodAdapter.java	Sun Aug 10 06:21:50 2014 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,302 +0,0 @@
     9.4 -/*
     9.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
     9.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 - *
     9.8 - * This code is free software; you can redistribute it and/or modify it
     9.9 - * under the terms of the GNU General Public License version 2 only, as
    9.10 - * published by the Free Software Foundation.  Oracle designates this
    9.11 - * particular file as subject to the "Classpath" exception as provided
    9.12 - * by Oracle in the LICENSE file that accompanied this code.
    9.13 - *
    9.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    9.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.17 - * version 2 for more details (a copy is included in the LICENSE file that
    9.18 - * accompanied this code).
    9.19 - *
    9.20 - * You should have received a copy of the GNU General Public License version
    9.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    9.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.23 - *
    9.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.25 - * or visit www.oracle.com if you need additional information or have any
    9.26 - * questions.
    9.27 - */
    9.28 -
    9.29 -package java.lang.invoke;
    9.30 -
    9.31 -import jdk.internal.org.objectweb.asm.MethodVisitor;
    9.32 -import jdk.internal.org.objectweb.asm.Opcodes;
    9.33 -import jdk.internal.org.objectweb.asm.Type;
    9.34 -import sun.invoke.util.BytecodeDescriptor;
    9.35 -import sun.invoke.util.Wrapper;
    9.36 -import static sun.invoke.util.Wrapper.*;
    9.37 -
    9.38 -class TypeConvertingMethodAdapter extends MethodVisitor {
    9.39 -
    9.40 -    TypeConvertingMethodAdapter(MethodVisitor mv) {
    9.41 -        super(Opcodes.ASM5, mv);
    9.42 -    }
    9.43 -
    9.44 -    private static final int NUM_WRAPPERS = Wrapper.values().length;
    9.45 -
    9.46 -    private static final String NAME_OBJECT = "java/lang/Object";
    9.47 -    private static final String WRAPPER_PREFIX = "Ljava/lang/";
    9.48 -
    9.49 -    // Same for all primitives; name of the boxing method
    9.50 -    private static final String NAME_BOX_METHOD = "valueOf";
    9.51 -
    9.52 -    // Table of opcodes for widening primitive conversions; NOP = no conversion
    9.53 -    private static final int[][] wideningOpcodes = new int[NUM_WRAPPERS][NUM_WRAPPERS];
    9.54 -
    9.55 -    private static final Wrapper[] FROM_WRAPPER_NAME = new Wrapper[16];
    9.56 -
    9.57 -    // Table of wrappers for primitives, indexed by ASM type sorts
    9.58 -    private static final Wrapper[] FROM_TYPE_SORT = new Wrapper[16];
    9.59 -
    9.60 -    static {
    9.61 -        for (Wrapper w : Wrapper.values()) {
    9.62 -            if (w.basicTypeChar() != 'L') {
    9.63 -                int wi = hashWrapperName(w.wrapperSimpleName());
    9.64 -                assert (FROM_WRAPPER_NAME[wi] == null);
    9.65 -                FROM_WRAPPER_NAME[wi] = w;
    9.66 -            }
    9.67 -        }
    9.68 -
    9.69 -        for (int i = 0; i < NUM_WRAPPERS; i++) {
    9.70 -            for (int j = 0; j < NUM_WRAPPERS; j++) {
    9.71 -                wideningOpcodes[i][j] = Opcodes.NOP;
    9.72 -            }
    9.73 -        }
    9.74 -
    9.75 -        initWidening(LONG,   Opcodes.I2L, BYTE, SHORT, INT, CHAR);
    9.76 -        initWidening(LONG,   Opcodes.F2L, FLOAT);
    9.77 -        initWidening(FLOAT,  Opcodes.I2F, BYTE, SHORT, INT, CHAR);
    9.78 -        initWidening(FLOAT,  Opcodes.L2F, LONG);
    9.79 -        initWidening(DOUBLE, Opcodes.I2D, BYTE, SHORT, INT, CHAR);
    9.80 -        initWidening(DOUBLE, Opcodes.F2D, FLOAT);
    9.81 -        initWidening(DOUBLE, Opcodes.L2D, LONG);
    9.82 -
    9.83 -        FROM_TYPE_SORT[Type.BYTE] = Wrapper.BYTE;
    9.84 -        FROM_TYPE_SORT[Type.SHORT] = Wrapper.SHORT;
    9.85 -        FROM_TYPE_SORT[Type.INT] = Wrapper.INT;
    9.86 -        FROM_TYPE_SORT[Type.LONG] = Wrapper.LONG;
    9.87 -        FROM_TYPE_SORT[Type.CHAR] = Wrapper.CHAR;
    9.88 -        FROM_TYPE_SORT[Type.FLOAT] = Wrapper.FLOAT;
    9.89 -        FROM_TYPE_SORT[Type.DOUBLE] = Wrapper.DOUBLE;
    9.90 -        FROM_TYPE_SORT[Type.BOOLEAN] = Wrapper.BOOLEAN;
    9.91 -    }
    9.92 -
    9.93 -    private static void initWidening(Wrapper to, int opcode, Wrapper... from) {
    9.94 -        for (Wrapper f : from) {
    9.95 -            wideningOpcodes[f.ordinal()][to.ordinal()] = opcode;
    9.96 -        }
    9.97 -    }
    9.98 -
    9.99 -    /**
   9.100 -     * Class name to Wrapper hash, derived from Wrapper.hashWrap()
   9.101 -     * @param xn
   9.102 -     * @return The hash code 0-15
   9.103 -     */
   9.104 -    private static int hashWrapperName(String xn) {
   9.105 -        if (xn.length() < 3) {
   9.106 -            return 0;
   9.107 -        }
   9.108 -        return (3 * xn.charAt(1) + xn.charAt(2)) % 16;
   9.109 -    }
   9.110 -
   9.111 -    private Wrapper wrapperOrNullFromDescriptor(String desc) {
   9.112 -        if (!desc.startsWith(WRAPPER_PREFIX)) {
   9.113 -            // Not a class type (array or method), so not a boxed type
   9.114 -            // or not in the right package
   9.115 -            return null;
   9.116 -        }
   9.117 -        // Pare it down to the simple class name
   9.118 -        String cname = desc.substring(WRAPPER_PREFIX.length(), desc.length() - 1);
   9.119 -        // Hash to a Wrapper
   9.120 -        Wrapper w = FROM_WRAPPER_NAME[hashWrapperName(cname)];
   9.121 -        if (w == null || w.wrapperSimpleName().equals(cname)) {
   9.122 -            return w;
   9.123 -        } else {
   9.124 -            return null;
   9.125 -        }
   9.126 -    }
   9.127 -
   9.128 -    private static String wrapperName(Wrapper w) {
   9.129 -        return "java/lang/" + w.wrapperSimpleName();
   9.130 -    }
   9.131 -
   9.132 -    private static String unboxMethod(Wrapper w) {
   9.133 -        return w.primitiveSimpleName() + "Value";
   9.134 -    }
   9.135 -
   9.136 -    private static String boxingDescriptor(Wrapper w) {
   9.137 -        return String.format("(%s)L%s;", w.basicTypeChar(), wrapperName(w));
   9.138 -    }
   9.139 -
   9.140 -    private static String unboxingDescriptor(Wrapper w) {
   9.141 -        return "()" + w.basicTypeChar();
   9.142 -    }
   9.143 -
   9.144 -    void boxIfTypePrimitive(Type t) {
   9.145 -        Wrapper w = FROM_TYPE_SORT[t.getSort()];
   9.146 -        if (w != null) {
   9.147 -            box(w);
   9.148 -        }
   9.149 -    }
   9.150 -
   9.151 -    void widen(Wrapper ws, Wrapper wt) {
   9.152 -        if (ws != wt) {
   9.153 -            int opcode = wideningOpcodes[ws.ordinal()][wt.ordinal()];
   9.154 -            if (opcode != Opcodes.NOP) {
   9.155 -                visitInsn(opcode);
   9.156 -            }
   9.157 -        }
   9.158 -    }
   9.159 -
   9.160 -    void box(Wrapper w) {
   9.161 -        visitMethodInsn(Opcodes.INVOKESTATIC,
   9.162 -                wrapperName(w),
   9.163 -                NAME_BOX_METHOD,
   9.164 -                boxingDescriptor(w));
   9.165 -    }
   9.166 -
   9.167 -    /**
   9.168 -     * Convert types by unboxing. The source type is known to be a primitive wrapper.
   9.169 -     * @param ws A primitive wrapper corresponding to wrapped reference source type
   9.170 -     * @param wt A primitive wrapper being converted to
   9.171 -     */
   9.172 -    void unbox(String sname, Wrapper wt) {
   9.173 -        visitMethodInsn(Opcodes.INVOKEVIRTUAL,
   9.174 -                sname,
   9.175 -                unboxMethod(wt),
   9.176 -                unboxingDescriptor(wt));
   9.177 -    }
   9.178 -
   9.179 -    private String descriptorToName(String desc) {
   9.180 -        int last = desc.length() - 1;
   9.181 -        if (desc.charAt(0) == 'L' && desc.charAt(last) == ';') {
   9.182 -            // In descriptor form
   9.183 -            return desc.substring(1, last);
   9.184 -        } else {
   9.185 -            // Already in internal name form
   9.186 -            return desc;
   9.187 -        }
   9.188 -    }
   9.189 -
   9.190 -    void cast(String ds, String dt) {
   9.191 -        String ns = descriptorToName(ds);
   9.192 -        String nt = descriptorToName(dt);
   9.193 -        if (!nt.equals(ns) && !nt.equals(NAME_OBJECT)) {
   9.194 -            visitTypeInsn(Opcodes.CHECKCAST, nt);
   9.195 -        }
   9.196 -    }
   9.197 -
   9.198 -    private boolean isPrimitive(Wrapper w) {
   9.199 -        return w != OBJECT;
   9.200 -    }
   9.201 -
   9.202 -    private Wrapper toWrapper(String desc) {
   9.203 -        char first = desc.charAt(0);
   9.204 -        if (first == '[' || first == '(') {
   9.205 -            first = 'L';
   9.206 -        }
   9.207 -        return Wrapper.forBasicType(first);
   9.208 -    }
   9.209 -
   9.210 -    /**
   9.211 -     * Convert an argument of type 'arg' to be passed to 'target' assuring that it is 'functional'.
   9.212 -     * Insert the needed conversion instructions in the method code.
   9.213 -     * @param arg
   9.214 -     * @param target
   9.215 -     * @param functional
   9.216 -     */
   9.217 -    void convertType(Class<?> arg, Class<?> target, Class<?> functional) {
   9.218 -        if (arg.equals(target) && arg.equals(functional)) {
   9.219 -            return;
   9.220 -        }
   9.221 -        if (arg == Void.TYPE || target == Void.TYPE) {
   9.222 -            return;
   9.223 -        }
   9.224 -        if (arg.isPrimitive()) {
   9.225 -            Wrapper wArg = Wrapper.forPrimitiveType(arg);
   9.226 -            if (target.isPrimitive()) {
   9.227 -                // Both primitives: widening
   9.228 -                widen(wArg, Wrapper.forPrimitiveType(target));
   9.229 -            } else {
   9.230 -                // Primitive argument to reference target
   9.231 -                String dTarget = BytecodeDescriptor.unparse(target);
   9.232 -                Wrapper wPrimTarget = wrapperOrNullFromDescriptor(dTarget);
   9.233 -                if (wPrimTarget != null) {
   9.234 -                    // The target is a boxed primitive type, widen to get there before boxing
   9.235 -                    widen(wArg, wPrimTarget);
   9.236 -                    box(wPrimTarget);
   9.237 -                } else {
   9.238 -                    // Otherwise, box and cast
   9.239 -                    box(wArg);
   9.240 -                    cast(wrapperName(wArg), dTarget);
   9.241 -                }
   9.242 -            }
   9.243 -        } else {
   9.244 -            String dArg = BytecodeDescriptor.unparse(arg);
   9.245 -            String dSrc;
   9.246 -            if (functional.isPrimitive()) {
   9.247 -                dSrc = dArg;
   9.248 -            } else {
   9.249 -                // Cast to convert to possibly more specific type, and generate CCE for invalid arg
   9.250 -                dSrc = BytecodeDescriptor.unparse(functional);
   9.251 -                cast(dArg, dSrc);
   9.252 -            }
   9.253 -            String dTarget = BytecodeDescriptor.unparse(target);
   9.254 -            if (target.isPrimitive()) {
   9.255 -                Wrapper wTarget = toWrapper(dTarget);
   9.256 -                // Reference argument to primitive target
   9.257 -                Wrapper wps = wrapperOrNullFromDescriptor(dSrc);
   9.258 -                if (wps != null) {
   9.259 -                    if (wps.isSigned() || wps.isFloating()) {
   9.260 -                        // Boxed number to primitive
   9.261 -                        unbox(wrapperName(wps), wTarget);
   9.262 -                    } else {
   9.263 -                        // Character or Boolean
   9.264 -                        unbox(wrapperName(wps), wps);
   9.265 -                        widen(wps, wTarget);
   9.266 -                    }
   9.267 -                } else {
   9.268 -                    // Source type is reference type, but not boxed type,
   9.269 -                    // assume it is super type of target type
   9.270 -                    String intermediate;
   9.271 -                    if (wTarget.isSigned() || wTarget.isFloating()) {
   9.272 -                        // Boxed number to primitive
   9.273 -                        intermediate = "java/lang/Number";
   9.274 -                    } else {
   9.275 -                        // Character or Boolean
   9.276 -                        intermediate = wrapperName(wTarget);
   9.277 -                    }
   9.278 -                    cast(dSrc, intermediate);
   9.279 -                    unbox(intermediate, wTarget);
   9.280 -                }
   9.281 -            } else {
   9.282 -                // Both reference types: just case to target type
   9.283 -                cast(dSrc, dTarget);
   9.284 -            }
   9.285 -        }
   9.286 -    }
   9.287 -
   9.288 -    /**
   9.289 -     * The following method is copied from
   9.290 -     * org.objectweb.asm.commons.InstructionAdapter. Part of ASM: a very small
   9.291 -     * and fast Java bytecode manipulation framework.
   9.292 -     * Copyright (c) 2000-2005 INRIA, France Telecom All rights reserved.
   9.293 -     */
   9.294 -    void iconst(final int cst) {
   9.295 -        if (cst >= -1 && cst <= 5) {
   9.296 -            mv.visitInsn(Opcodes.ICONST_0 + cst);
   9.297 -        } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
   9.298 -            mv.visitIntInsn(Opcodes.BIPUSH, cst);
   9.299 -        } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
   9.300 -            mv.visitIntInsn(Opcodes.SIPUSH, cst);
   9.301 -        } else {
   9.302 -            mv.visitLdcInsn(cst);
   9.303 -        }
   9.304 -    }
   9.305 -}
    10.1 --- a/rt/emul/mini/src/main/java/java/lang/Class.java	Sun Aug 10 06:21:50 2014 +0200
    10.2 +++ b/rt/emul/mini/src/main/java/java/lang/Class.java	Sun Aug 10 07:02:12 2014 +0200
    10.3 @@ -94,6 +94,11 @@
    10.4      private static final int ENUM      = 0x00004000;
    10.5      private static final int SYNTHETIC = 0x00001000;
    10.6  
    10.7 +    /* Backing store of user-defined values pertaining to this class.
    10.8 +     * Maintained by the ClassValue class.
    10.9 +     */
   10.10 +    transient Object classValueMap;
   10.11 +    
   10.12      /*
   10.13       * Constructor. Only the Java Virtual Machine creates Class
   10.14       * objects.