rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java
branchjdk8
changeset 1675 cd50c1894ce5
parent 1674 eca8e9c3ec3e
child 1678 35daab73e225
     1.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java	Sun Aug 17 20:09:05 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,491 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.  Oracle designates this
    1.11 - * particular file as subject to the "Classpath" exception as provided
    1.12 - * by Oracle in the LICENSE file that accompanied this code.
    1.13 - *
    1.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 - * version 2 for more details (a copy is included in the LICENSE file that
    1.18 - * accompanied this code).
    1.19 - *
    1.20 - * You should have received a copy of the GNU General Public License version
    1.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 - *
    1.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 - * or visit www.oracle.com if you need additional information or have any
    1.26 - * questions.
    1.27 - */
    1.28 -
    1.29 -package java.lang.invoke;
    1.30 -
    1.31 -import static java.lang.invoke.LambdaForm.basicTypes;
    1.32 -import static java.lang.invoke.MethodHandleStatics.*;
    1.33 -
    1.34 -import java.lang.invoke.LambdaForm.Name;
    1.35 -import java.lang.invoke.LambdaForm.NamedFunction;
    1.36 -import java.lang.invoke.MethodHandles.Lookup;
    1.37 -import java.util.Arrays;
    1.38 -import java.util.HashMap;
    1.39 -
    1.40 -import sun.invoke.util.ValueConversions;
    1.41 -
    1.42 -/**
    1.43 - * The flavor of method handle which emulates an invoke instruction
    1.44 - * on a predetermined argument.  The JVM dispatches to the correct method
    1.45 - * when the handle is created, not when it is invoked.
    1.46 - *
    1.47 - * All bound arguments are encapsulated in dedicated species.
    1.48 - */
    1.49 -/* non-public */ abstract class BoundMethodHandle extends MethodHandle {
    1.50 -
    1.51 -    /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
    1.52 -        super(type, form);
    1.53 -    }
    1.54 -
    1.55 -    //
    1.56 -    // BMH API and internals
    1.57 -    //
    1.58 -
    1.59 -    static MethodHandle bindSingle(MethodType type, LambdaForm form, char xtype, Object x) {
    1.60 -        // for some type signatures, there exist pre-defined concrete BMH classes
    1.61 -        try {
    1.62 -            switch (xtype) {
    1.63 -            case 'L':
    1.64 -                if (true)  return bindSingle(type, form, x);  // Use known fast path.
    1.65 -                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('L').constructor[0].invokeBasic(type, form, x);
    1.66 -            case 'I':
    1.67 -                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('I').constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x));
    1.68 -            case 'J':
    1.69 -                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('J').constructor[0].invokeBasic(type, form, (long) x);
    1.70 -            case 'F':
    1.71 -                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('F').constructor[0].invokeBasic(type, form, (float) x);
    1.72 -            case 'D':
    1.73 -                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('D').constructor[0].invokeBasic(type, form, (double) x);
    1.74 -            default : throw new InternalError("unexpected xtype: " + xtype);
    1.75 -            }
    1.76 -        } catch (Throwable t) {
    1.77 -            throw newInternalError(t);
    1.78 -        }
    1.79 -    }
    1.80 -
    1.81 -    static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
    1.82 -            return new Species_L(type, form, x);
    1.83 -    }
    1.84 -
    1.85 -    MethodHandle cloneExtend(MethodType type, LambdaForm form, char xtype, Object x) {
    1.86 -        try {
    1.87 -            switch (xtype) {
    1.88 -            case 'L': return cloneExtendL(type, form, x);
    1.89 -            case 'I': return cloneExtendI(type, form, ValueConversions.widenSubword(x));
    1.90 -            case 'J': return cloneExtendJ(type, form, (long) x);
    1.91 -            case 'F': return cloneExtendF(type, form, (float) x);
    1.92 -            case 'D': return cloneExtendD(type, form, (double) x);
    1.93 -            }
    1.94 -        } catch (Throwable t) {
    1.95 -            throw newInternalError(t);
    1.96 -        }
    1.97 -        throw new InternalError("unexpected type: " + xtype);
    1.98 -    }
    1.99 -
   1.100 -    @Override
   1.101 -    MethodHandle bindArgument(int pos, char basicType, Object value) {
   1.102 -        MethodType type = type().dropParameterTypes(pos, pos+1);
   1.103 -        LambdaForm form = internalForm().bind(1+pos, speciesData());
   1.104 -        return cloneExtend(type, form, basicType, value);
   1.105 -    }
   1.106 -
   1.107 -    @Override
   1.108 -    MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
   1.109 -        LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
   1.110 -        try {
   1.111 -             return clone(srcType, form);
   1.112 -         } catch (Throwable t) {
   1.113 -             throw newInternalError(t);
   1.114 -         }
   1.115 -    }
   1.116 -
   1.117 -    @Override
   1.118 -    MethodHandle permuteArguments(MethodType newType, int[] reorder) {
   1.119 -        try {
   1.120 -             return clone(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList())));
   1.121 -         } catch (Throwable t) {
   1.122 -             throw newInternalError(t);
   1.123 -         }
   1.124 -    }
   1.125 -
   1.126 -    static final String EXTENSION_TYPES = "LIJFD";
   1.127 -    static final byte INDEX_L = 0, INDEX_I = 1, INDEX_J = 2, INDEX_F = 3, INDEX_D = 4;
   1.128 -    static byte extensionIndex(char type) {
   1.129 -        int i = EXTENSION_TYPES.indexOf(type);
   1.130 -        if (i < 0)  throw new InternalError();
   1.131 -        return (byte) i;
   1.132 -    }
   1.133 -
   1.134 -    /**
   1.135 -     * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
   1.136 -     * static field containing this value, and they must accordingly implement this method.
   1.137 -     */
   1.138 -    protected abstract SpeciesData speciesData();
   1.139 -
   1.140 -    @Override
   1.141 -    final Object internalProperties() {
   1.142 -        return "/BMH="+internalValues();
   1.143 -    }
   1.144 -
   1.145 -    @Override
   1.146 -    final Object internalValues() {
   1.147 -        Object[] boundValues = new Object[speciesData().fieldCount()];
   1.148 -        for (int i = 0; i < boundValues.length; ++i) {
   1.149 -            boundValues[i] = arg(i);
   1.150 -        }
   1.151 -        return Arrays.asList(boundValues);
   1.152 -    }
   1.153 -
   1.154 -    public final Object arg(int i) {
   1.155 -        try {
   1.156 -            switch (speciesData().fieldType(i)) {
   1.157 -            case 'L': return argL(i);
   1.158 -            case 'I': return argI(i);
   1.159 -            case 'F': return argF(i);
   1.160 -            case 'D': return argD(i);
   1.161 -            case 'J': return argJ(i);
   1.162 -            }
   1.163 -        } catch (Throwable ex) {
   1.164 -            throw newInternalError(ex);
   1.165 -        }
   1.166 -        throw new InternalError("unexpected type: " + speciesData().types+"."+i);
   1.167 -    }
   1.168 -    public final Object argL(int i) throws Throwable { return          speciesData().getters[i].invokeBasic(this); }
   1.169 -    public final int    argI(int i) throws Throwable { return (int)    speciesData().getters[i].invokeBasic(this); }
   1.170 -    public final float  argF(int i) throws Throwable { return (float)  speciesData().getters[i].invokeBasic(this); }
   1.171 -    public final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); }
   1.172 -    public final long   argJ(int i) throws Throwable { return (long)   speciesData().getters[i].invokeBasic(this); }
   1.173 -
   1.174 -    //
   1.175 -    // cloning API
   1.176 -    //
   1.177 -
   1.178 -    public abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable;
   1.179 -    public abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable;
   1.180 -    public abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int    narg) throws Throwable;
   1.181 -    public abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long   narg) throws Throwable;
   1.182 -    public abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float  narg) throws Throwable;
   1.183 -    public abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable;
   1.184 -
   1.185 -    // The following is a grossly irregular hack:
   1.186 -    @Override MethodHandle reinvokerTarget() {
   1.187 -        try {
   1.188 -            return (MethodHandle) argL(0);
   1.189 -        } catch (Throwable ex) {
   1.190 -            throw newInternalError(ex);
   1.191 -        }
   1.192 -    }
   1.193 -
   1.194 -    //
   1.195 -    // concrete BMH classes required to close bootstrap loops
   1.196 -    //
   1.197 -
   1.198 -    private  // make it private to force users to access the enclosing class first
   1.199 -    static final class Species_L extends BoundMethodHandle {
   1.200 -        final Object argL0;
   1.201 -        public Species_L(MethodType mt, LambdaForm lf, Object argL0) {
   1.202 -            super(mt, lf);
   1.203 -            this.argL0 = argL0;
   1.204 -        }
   1.205 -        // The following is a grossly irregular hack:
   1.206 -        @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
   1.207 -        @Override
   1.208 -        public SpeciesData speciesData() {
   1.209 -            return SPECIES_DATA;
   1.210 -        }
   1.211 -        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
   1.212 -        @Override
   1.213 -        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
   1.214 -            return new Species_L(mt, lf, argL0);
   1.215 -        }
   1.216 -        @Override
   1.217 -        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
   1.218 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
   1.219 -        }
   1.220 -        @Override
   1.221 -        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
   1.222 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg);
   1.223 -        }
   1.224 -        @Override
   1.225 -        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
   1.226 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg);
   1.227 -        }
   1.228 -        @Override
   1.229 -        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
   1.230 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg);
   1.231 -        }
   1.232 -        @Override
   1.233 -        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
   1.234 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg);
   1.235 -        }
   1.236 -    }
   1.237 -
   1.238 -/*
   1.239 -    static final class Species_LL extends BoundMethodHandle {
   1.240 -        final Object argL0;
   1.241 -        final Object argL1;
   1.242 -        public Species_LL(MethodType mt, LambdaForm lf, Object argL0, Object argL1) {
   1.243 -            super(mt, lf);
   1.244 -            this.argL0 = argL0;
   1.245 -            this.argL1 = argL1;
   1.246 -        }
   1.247 -        @Override
   1.248 -        public SpeciesData speciesData() {
   1.249 -            return SPECIES_DATA;
   1.250 -        }
   1.251 -        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LL", Species_LL.class);
   1.252 -        @Override
   1.253 -        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
   1.254 -            return new Species_LL(mt, lf, argL0, argL1);
   1.255 -        }
   1.256 -        @Override
   1.257 -        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
   1.258 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
   1.259 -        }
   1.260 -        @Override
   1.261 -        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
   1.262 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
   1.263 -        }
   1.264 -        @Override
   1.265 -        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
   1.266 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
   1.267 -        }
   1.268 -        @Override
   1.269 -        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
   1.270 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
   1.271 -        }
   1.272 -        @Override
   1.273 -        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
   1.274 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
   1.275 -        }
   1.276 -    }
   1.277 -
   1.278 -    static final class Species_JL extends BoundMethodHandle {
   1.279 -        final long argJ0;
   1.280 -        final Object argL1;
   1.281 -        public Species_JL(MethodType mt, LambdaForm lf, long argJ0, Object argL1) {
   1.282 -            super(mt, lf);
   1.283 -            this.argJ0 = argJ0;
   1.284 -            this.argL1 = argL1;
   1.285 -        }
   1.286 -        @Override
   1.287 -        public SpeciesData speciesData() {
   1.288 -            return SPECIES_DATA;
   1.289 -        }
   1.290 -        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("JL", Species_JL.class);
   1.291 -        @Override public final long   argJ0() { return argJ0; }
   1.292 -        @Override public final Object argL1() { return argL1; }
   1.293 -        @Override
   1.294 -        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
   1.295 -            return new Species_JL(mt, lf, argJ0, argL1);
   1.296 -        }
   1.297 -        @Override
   1.298 -        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
   1.299 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
   1.300 -        }
   1.301 -        @Override
   1.302 -        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
   1.303 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
   1.304 -        }
   1.305 -        @Override
   1.306 -        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
   1.307 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
   1.308 -        }
   1.309 -        @Override
   1.310 -        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
   1.311 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
   1.312 -        }
   1.313 -        @Override
   1.314 -        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
   1.315 -            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
   1.316 -        }
   1.317 -    }
   1.318 -*/
   1.319 -
   1.320 -    //
   1.321 -    // BMH species meta-data
   1.322 -    //
   1.323 -
   1.324 -    /**
   1.325 -     * Meta-data wrapper for concrete BMH classes.
   1.326 -     */
   1.327 -    static class SpeciesData {
   1.328 -        final String                             types;
   1.329 -        final Class<? extends BoundMethodHandle> clazz;
   1.330 -        // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
   1.331 -        // Therefore, we need a non-final link in the chain.  Use array elements.
   1.332 -        final MethodHandle[]                     constructor;
   1.333 -        final MethodHandle[]                     getters;
   1.334 -        final SpeciesData[]                      extensions;
   1.335 -
   1.336 -        public int fieldCount() {
   1.337 -            return types.length();
   1.338 -        }
   1.339 -        public char fieldType(int i) {
   1.340 -            return types.charAt(i);
   1.341 -        }
   1.342 -
   1.343 -        public String toString() {
   1.344 -            return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
   1.345 -        }
   1.346 -
   1.347 -        /**
   1.348 -         * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
   1.349 -         * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
   1.350 -         * getter.
   1.351 -         */
   1.352 -        Name getterName(Name mhName, int i) {
   1.353 -            MethodHandle mh = getters[i];
   1.354 -            assert(mh != null) : this+"."+i;
   1.355 -            return new Name(mh, mhName);
   1.356 -        }
   1.357 -
   1.358 -        NamedFunction getterFunction(int i) {
   1.359 -            return new NamedFunction(getters[i]);
   1.360 -        }
   1.361 -
   1.362 -        static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
   1.363 -
   1.364 -        private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
   1.365 -            this.types = types;
   1.366 -            this.clazz = clazz;
   1.367 -            if (!INIT_DONE) {
   1.368 -                this.constructor = new MethodHandle[1];
   1.369 -                this.getters = new MethodHandle[types.length()];
   1.370 -            } else {
   1.371 -                throw new IllegalStateException("bound method handle");
   1.372 -//                this.constructor = Factory.makeCtors(clazz, types, null);
   1.373 -//                this.getters = Factory.makeGetters(clazz, types, null);
   1.374 -            }
   1.375 -            this.extensions = new SpeciesData[EXTENSION_TYPES.length()];
   1.376 -        }
   1.377 -
   1.378 -        private void initForBootstrap() {
   1.379 -            assert(!INIT_DONE);
   1.380 -            if (constructor[0] == null) {
   1.381 -//                Factory.makeCtors(clazz, types, this.constructor);
   1.382 -//                Factory.makeGetters(clazz, types, this.getters);
   1.383 -            }
   1.384 -        }
   1.385 -
   1.386 -        private SpeciesData(String types) {
   1.387 -            // Placeholder only.
   1.388 -            this.types = types;
   1.389 -            this.clazz = null;
   1.390 -            this.constructor = null;
   1.391 -            this.getters = null;
   1.392 -            this.extensions = null;
   1.393 -        }
   1.394 -        private boolean isPlaceholder() { return clazz == null; }
   1.395 -
   1.396 -        private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();
   1.397 -        static { CACHE.put("", EMPTY); }  // make bootstrap predictable
   1.398 -        private static final boolean INIT_DONE;  // set after <clinit> finishes...
   1.399 -
   1.400 -        SpeciesData extendWithType(char type) {
   1.401 -            int i = extensionIndex(type);
   1.402 -            SpeciesData d = extensions[i];
   1.403 -            if (d != null)  return d;
   1.404 -            extensions[i] = d = get(types+type);
   1.405 -            return d;
   1.406 -        }
   1.407 -
   1.408 -        SpeciesData extendWithIndex(byte index) {
   1.409 -            SpeciesData d = extensions[index];
   1.410 -            if (d != null)  return d;
   1.411 -            extensions[index] = d = get(types+EXTENSION_TYPES.charAt(index));
   1.412 -            return d;
   1.413 -        }
   1.414 -
   1.415 -        private static SpeciesData get(String types) {
   1.416 -            // Acquire cache lock for query.
   1.417 -            SpeciesData d = lookupCache(types);
   1.418 -            if (!d.isPlaceholder())
   1.419 -                return d;
   1.420 -            synchronized (d) {
   1.421 -                // Use synch. on the placeholder to prevent multiple instantiation of one species.
   1.422 -                // Creating this class forces a recursive call to getForClass.
   1.423 -                if (lookupCache(types).isPlaceholder())
   1.424 -                    throw new IllegalStateException("Cannot generate anything");
   1.425 -            }
   1.426 -            // Reacquire cache lock.
   1.427 -            d = lookupCache(types);
   1.428 -            // Class loading must have upgraded the cache.
   1.429 -            assert(d != null && !d.isPlaceholder());
   1.430 -            return d;
   1.431 -        }
   1.432 -        static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
   1.433 -            // clazz is a new class which is initializing its SPECIES_DATA field
   1.434 -            return updateCache(types, new SpeciesData(types, clazz));
   1.435 -        }
   1.436 -        private static synchronized SpeciesData lookupCache(String types) {
   1.437 -            SpeciesData d = CACHE.get(types);
   1.438 -            if (d != null)  return d;
   1.439 -            d = new SpeciesData(types);
   1.440 -            assert(d.isPlaceholder());
   1.441 -            CACHE.put(types, d);
   1.442 -            return d;
   1.443 -        }
   1.444 -        private static synchronized SpeciesData updateCache(String types, SpeciesData d) {
   1.445 -            SpeciesData d2;
   1.446 -            assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
   1.447 -            assert(!d.isPlaceholder());
   1.448 -            CACHE.put(types, d);
   1.449 -            return d;
   1.450 -        }
   1.451 -
   1.452 -        static {
   1.453 -            // pre-fill the BMH speciesdata cache with BMH's inner classes
   1.454 -            final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
   1.455 -            SpeciesData d0 = BoundMethodHandle.SPECIES_DATA;  // trigger class init
   1.456 -            assert(d0 == null || d0 == lookupCache("")) : d0;
   1.457 -            try {
   1.458 -                /*
   1.459 -                for (Class<?> c : rootCls.getDeclaredClasses()) {
   1.460 -                    if (rootCls.isAssignableFrom(c)) {
   1.461 -                        final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
   1.462 -                        SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
   1.463 -                        assert(d != null) : cbmh.getName();
   1.464 -                        assert(d.clazz == cbmh);
   1.465 -                        assert(d == lookupCache(d.types));
   1.466 -                    }
   1.467 -                }
   1.468 -                */
   1.469 -            } catch (Throwable e) {
   1.470 -                throw newInternalError(e);
   1.471 -            }
   1.472 -
   1.473 -            for (SpeciesData d : CACHE.values()) {
   1.474 -                d.initForBootstrap();
   1.475 -            }
   1.476 -            // Note:  Do not simplify this, because INIT_DONE must not be
   1.477 -            // a compile-time constant during bootstrapping.
   1.478 -            INIT_DONE = Boolean.TRUE;
   1.479 -        }
   1.480 -    }
   1.481 -
   1.482 -    static SpeciesData getSpeciesData(String types) {
   1.483 -        return SpeciesData.get(types);
   1.484 -    }
   1.485 -
   1.486 -
   1.487 -
   1.488 -    private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
   1.489 -
   1.490 -    /**
   1.491 -     * All subclasses must provide such a value describing their type signature.
   1.492 -     */
   1.493 -    static final SpeciesData SPECIES_DATA = SpeciesData.EMPTY;
   1.494 -}