rt/emul/compact/src/main/java/java/lang/invoke/DirectMethodHandle.java
branchjdk8
changeset 1675 cd50c1894ce5
parent 1674 eca8e9c3ec3e
child 1678 35daab73e225
     1.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/DirectMethodHandle.java	Sun Aug 17 20:09:05 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,730 +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 java.lang.reflect.Method;
    1.32 -import java.util.Arrays;
    1.33 -import sun.invoke.util.VerifyAccess;
    1.34 -import static java.lang.invoke.MethodHandleNatives.Constants.*;
    1.35 -import static java.lang.invoke.LambdaForm.*;
    1.36 -import static java.lang.invoke.MethodTypeForm.*;
    1.37 -import static java.lang.invoke.MethodHandleStatics.*;
    1.38 -import java.lang.ref.WeakReference;
    1.39 -import java.lang.reflect.Field;
    1.40 -import sun.invoke.util.ValueConversions;
    1.41 -import sun.invoke.util.VerifyType;
    1.42 -import sun.invoke.util.Wrapper;
    1.43 -
    1.44 -/**
    1.45 - * The flavor of method handle which implements a constant reference
    1.46 - * to a class member.
    1.47 - * @author jrose
    1.48 - */
    1.49 -class DirectMethodHandle extends MethodHandle {
    1.50 -    final MemberName member;
    1.51 -
    1.52 -    // Constructors and factory methods in this class *must* be package scoped or private.
    1.53 -    private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
    1.54 -        super(mtype, form);
    1.55 -        if (!member.isResolved())  throw new InternalError();
    1.56 -
    1.57 -        if (member.getDeclaringClass().isInterface() &&
    1.58 -                member.isMethod() && !member.isAbstract()) {
    1.59 -            // Check for corner case: invokeinterface of Object method
    1.60 -            MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
    1.61 -            m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
    1.62 -            if (m != null && m.isPublic()) {
    1.63 -                member = m;
    1.64 -            }
    1.65 -        }
    1.66 -
    1.67 -        this.member = member;
    1.68 -    }
    1.69 -
    1.70 -    // Factory methods:
    1.71 -    static DirectMethodHandle make(byte refKind, Class<?> receiver, MemberName member) {
    1.72 -        MethodType mtype = member.getMethodOrFieldType();
    1.73 -        if (!member.isStatic()) {
    1.74 -            if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
    1.75 -                throw new InternalError(member.toString());
    1.76 -            mtype = mtype.insertParameterTypes(0, receiver);
    1.77 -        }
    1.78 -        if (!member.isField()) {
    1.79 -            if (refKind == REF_invokeSpecial) {
    1.80 -                member = member.asSpecial();
    1.81 -                LambdaForm lform = preparedLambdaForm(member);
    1.82 -                return new Special(mtype, lform, member);
    1.83 -            } else {
    1.84 -                LambdaForm lform = preparedLambdaForm(member);
    1.85 -                return new DirectMethodHandle(mtype, lform, member);
    1.86 -            }
    1.87 -        } else {
    1.88 -            LambdaForm lform = preparedFieldLambdaForm(member);
    1.89 -            if (member.isStatic()) {
    1.90 -                long offset = MethodHandleNatives.staticFieldOffset(member);
    1.91 -                Object base = MethodHandleNatives.staticFieldBase(member);
    1.92 -                return new StaticAccessor(mtype, lform, member, base, offset);
    1.93 -            } else {
    1.94 -                long offset = MethodHandleNatives.objectFieldOffset(member);
    1.95 -                assert(offset == (int)offset);
    1.96 -                return new Accessor(mtype, lform, member, (int)offset);
    1.97 -            }
    1.98 -        }
    1.99 -    }
   1.100 -    static DirectMethodHandle make(Class<?> receiver, MemberName member) {
   1.101 -        byte refKind = member.getReferenceKind();
   1.102 -        if (refKind == REF_invokeSpecial)
   1.103 -            refKind =  REF_invokeVirtual;
   1.104 -        return make(refKind, receiver, member);
   1.105 -    }
   1.106 -    static DirectMethodHandle make(MemberName member) {
   1.107 -        if (member.isConstructor())
   1.108 -            return makeAllocator(member);
   1.109 -        return make(member.getDeclaringClass(), member);
   1.110 -    }
   1.111 -    static DirectMethodHandle make(Method method) {
   1.112 -        return make(method.getDeclaringClass(), new MemberName(method));
   1.113 -    }
   1.114 -    static DirectMethodHandle make(Field field) {
   1.115 -        return make(field.getDeclaringClass(), new MemberName(field));
   1.116 -    }
   1.117 -    private static DirectMethodHandle makeAllocator(MemberName ctor) {
   1.118 -        assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
   1.119 -        Class<?> instanceClass = ctor.getDeclaringClass();
   1.120 -        ctor = ctor.asConstructor();
   1.121 -        assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
   1.122 -        MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
   1.123 -        LambdaForm lform = preparedLambdaForm(ctor);
   1.124 -        MemberName init = ctor.asSpecial();
   1.125 -        assert(init.getMethodType().returnType() == void.class);
   1.126 -        return new Constructor(mtype, lform, ctor, init, instanceClass);
   1.127 -    }
   1.128 -
   1.129 -    @Override
   1.130 -    MethodHandle copyWith(MethodType mt, LambdaForm lf) {
   1.131 -        return new DirectMethodHandle(mt, lf, member);
   1.132 -    }
   1.133 -
   1.134 -    @Override
   1.135 -    String internalProperties() {
   1.136 -        return "/DMH="+member.toString();
   1.137 -    }
   1.138 -
   1.139 -    //// Implementation methods.
   1.140 -    @Override
   1.141 -    MethodHandle viewAsType(MethodType newType) {
   1.142 -        return new DirectMethodHandle(newType, form, member);
   1.143 -    }
   1.144 -    @Override
   1.145 -    @ForceInline
   1.146 -    MemberName internalMemberName() {
   1.147 -        return member;
   1.148 -    }
   1.149 -
   1.150 -    @Override
   1.151 -    MethodHandle bindArgument(int pos, char basicType, Object value) {
   1.152 -        // If the member needs dispatching, do so.
   1.153 -        if (pos == 0 && basicType == 'L') {
   1.154 -            DirectMethodHandle concrete = maybeRebind(value);
   1.155 -            if (concrete != null)
   1.156 -                return concrete.bindReceiver(value);
   1.157 -        }
   1.158 -        return super.bindArgument(pos, basicType, value);
   1.159 -    }
   1.160 -
   1.161 -    @Override
   1.162 -    MethodHandle bindReceiver(Object receiver) {
   1.163 -        // If the member needs dispatching, do so.
   1.164 -        DirectMethodHandle concrete = maybeRebind(receiver);
   1.165 -        if (concrete != null)
   1.166 -            return concrete.bindReceiver(receiver);
   1.167 -        return super.bindReceiver(receiver);
   1.168 -    }
   1.169 -
   1.170 -    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
   1.171 -
   1.172 -    private DirectMethodHandle maybeRebind(Object receiver) {
   1.173 -        if (receiver != null) {
   1.174 -            switch (member.getReferenceKind()) {
   1.175 -            case REF_invokeInterface:
   1.176 -            case REF_invokeVirtual:
   1.177 -                // Pre-dispatch the member.
   1.178 -                Class<?> concreteClass = receiver.getClass();
   1.179 -                MemberName concrete = new MemberName(concreteClass, member.getName(), member.getMethodType(), REF_invokeSpecial);
   1.180 -                concrete = IMPL_NAMES.resolveOrNull(REF_invokeSpecial, concrete, concreteClass);
   1.181 -                if (concrete != null)
   1.182 -                    return new DirectMethodHandle(type(), preparedLambdaForm(concrete), concrete);
   1.183 -                break;
   1.184 -            }
   1.185 -        }
   1.186 -        return null;
   1.187 -    }
   1.188 -
   1.189 -    /**
   1.190 -     * Create a LF which can invoke the given method.
   1.191 -     * Cache and share this structure among all methods with
   1.192 -     * the same basicType and refKind.
   1.193 -     */
   1.194 -    private static LambdaForm preparedLambdaForm(MemberName m) {
   1.195 -        assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
   1.196 -        MethodType mtype = m.getInvocationType().basicType();
   1.197 -        assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
   1.198 -        int which;
   1.199 -        switch (m.getReferenceKind()) {
   1.200 -        case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
   1.201 -        case REF_invokeStatic:     which = LF_INVSTATIC;     break;
   1.202 -        case REF_invokeSpecial:    which = LF_INVSPECIAL;    break;
   1.203 -        case REF_invokeInterface:  which = LF_INVINTERFACE;  break;
   1.204 -        case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
   1.205 -        default:  throw new InternalError(m.toString());
   1.206 -        }
   1.207 -        if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
   1.208 -            // precompute the barrier-free version:
   1.209 -            preparedLambdaForm(mtype, which);
   1.210 -            which = LF_INVSTATIC_INIT;
   1.211 -        }
   1.212 -        LambdaForm lform = preparedLambdaForm(mtype, which);
   1.213 -        maybeCompile(lform, m);
   1.214 -        assert(lform.methodType().dropParameterTypes(0, 1)
   1.215 -                .equals(m.getInvocationType().basicType()))
   1.216 -                : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
   1.217 -        return lform;
   1.218 -    }
   1.219 -
   1.220 -    private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
   1.221 -        LambdaForm lform = mtype.form().cachedLambdaForm(which);
   1.222 -        if (lform != null)  return lform;
   1.223 -        lform = makePreparedLambdaForm(mtype, which);
   1.224 -        return mtype.form().setCachedLambdaForm(which, lform);
   1.225 -    }
   1.226 -
   1.227 -    private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
   1.228 -        boolean needsInit = (which == LF_INVSTATIC_INIT);
   1.229 -        boolean doesAlloc = (which == LF_NEWINVSPECIAL);
   1.230 -        String linkerName, lambdaName;
   1.231 -        switch (which) {
   1.232 -        case LF_INVVIRTUAL:    linkerName = "linkToVirtual";    lambdaName = "DMH.invokeVirtual";    break;
   1.233 -        case LF_INVSTATIC:     linkerName = "linkToStatic";     lambdaName = "DMH.invokeStatic";     break;
   1.234 -        case LF_INVSTATIC_INIT:linkerName = "linkToStatic";     lambdaName = "DMH.invokeStaticInit"; break;
   1.235 -        case LF_INVSPECIAL:    linkerName = "linkToSpecial";    lambdaName = "DMH.invokeSpecial";    break;
   1.236 -        case LF_INVINTERFACE:  linkerName = "linkToInterface";  lambdaName = "DMH.invokeInterface";  break;
   1.237 -        case LF_NEWINVSPECIAL: linkerName = "linkToSpecial";    lambdaName = "DMH.newInvokeSpecial"; break;
   1.238 -        default:  throw new InternalError("which="+which);
   1.239 -        }
   1.240 -        MethodType mtypeWithArg = mtype.appendParameterTypes(MemberName.class);
   1.241 -        if (doesAlloc)
   1.242 -            mtypeWithArg = mtypeWithArg
   1.243 -                    .insertParameterTypes(0, Object.class)  // insert newly allocated obj
   1.244 -                    .changeReturnType(void.class);          // <init> returns void
   1.245 -        MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
   1.246 -        try {
   1.247 -            linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
   1.248 -        } catch (ReflectiveOperationException ex) {
   1.249 -            throw newInternalError(ex);
   1.250 -        }
   1.251 -        final int DMH_THIS    = 0;
   1.252 -        final int ARG_BASE    = 1;
   1.253 -        final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
   1.254 -        int nameCursor = ARG_LIMIT;
   1.255 -        final int NEW_OBJ     = (doesAlloc ? nameCursor++ : -1);
   1.256 -        final int GET_MEMBER  = nameCursor++;
   1.257 -        final int LINKER_CALL = nameCursor++;
   1.258 -        Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   1.259 -        assert(names.length == nameCursor);
   1.260 -        if (doesAlloc) {
   1.261 -            // names = { argx,y,z,... new C, init method }
   1.262 -            names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
   1.263 -            names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
   1.264 -        } else if (needsInit) {
   1.265 -            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
   1.266 -        } else {
   1.267 -            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
   1.268 -        }
   1.269 -        Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
   1.270 -        assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
   1.271 -        int result = LambdaForm.LAST_RESULT;
   1.272 -        if (doesAlloc) {
   1.273 -            assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
   1.274 -            System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
   1.275 -            outArgs[0] = names[NEW_OBJ];
   1.276 -            result = NEW_OBJ;
   1.277 -        }
   1.278 -        names[LINKER_CALL] = new Name(linker, outArgs);
   1.279 -        lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
   1.280 -        LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
   1.281 -        // This is a tricky bit of code.  Don't send it through the LF interpreter.
   1.282 -        lform.compileToBytecode();
   1.283 -        return lform;
   1.284 -    }
   1.285 -
   1.286 -    private static void maybeCompile(LambdaForm lform, MemberName m) {
   1.287 -        if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
   1.288 -            // Help along bootstrapping...
   1.289 -            lform.compileToBytecode();
   1.290 -    }
   1.291 -
   1.292 -    /** Static wrapper for DirectMethodHandle.internalMemberName. */
   1.293 -    @ForceInline
   1.294 -    /*non-public*/ static Object internalMemberName(Object mh) {
   1.295 -        return ((DirectMethodHandle)mh).member;
   1.296 -    }
   1.297 -
   1.298 -    /** Static wrapper for DirectMethodHandle.internalMemberName.
   1.299 -     * This one also forces initialization.
   1.300 -     */
   1.301 -    /*non-public*/ static Object internalMemberNameEnsureInit(Object mh) {
   1.302 -        DirectMethodHandle dmh = (DirectMethodHandle)mh;
   1.303 -        dmh.ensureInitialized();
   1.304 -        return dmh.member;
   1.305 -    }
   1.306 -
   1.307 -    /*non-public*/ static
   1.308 -    boolean shouldBeInitialized(MemberName member) {
   1.309 -        switch (member.getReferenceKind()) {
   1.310 -        case REF_invokeStatic:
   1.311 -        case REF_getStatic:
   1.312 -        case REF_putStatic:
   1.313 -        case REF_newInvokeSpecial:
   1.314 -            break;
   1.315 -        default:
   1.316 -            // No need to initialize the class on this kind of member.
   1.317 -            return false;
   1.318 -        }
   1.319 -        Class<?> cls = member.getDeclaringClass();
   1.320 -        if (cls == ValueConversions.class ||
   1.321 -            cls == MethodHandleImpl.class ||
   1.322 -            cls == Invokers.class) {
   1.323 -            // These guys have lots of <clinit> DMH creation but we know
   1.324 -            // the MHs will not be used until the system is booted.
   1.325 -            return false;
   1.326 -        }
   1.327 -        if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
   1.328 -            VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
   1.329 -            // It is a system class.  It is probably in the process of
   1.330 -            // being initialized, but we will help it along just to be safe.
   1.331 -            if (shouldBeInitialized(cls)) {
   1.332 -                ensureClassInitialized(cls);
   1.333 -            }
   1.334 -            return false;
   1.335 -        }
   1.336 -        return shouldBeInitialized(cls);
   1.337 -    }
   1.338 -
   1.339 -    private static class EnsureInitialized extends ClassValue<WeakReference<Thread>> {
   1.340 -        @Override
   1.341 -        protected WeakReference<Thread> computeValue(Class<?> type) {
   1.342 -            ensureClassInitialized(type);
   1.343 -            if (shouldBeInitialized(type))
   1.344 -                // If the previous call didn't block, this can happen.
   1.345 -                // We are executing inside <clinit>.
   1.346 -                return new WeakReference<>(Thread.currentThread());
   1.347 -            return null;
   1.348 -        }
   1.349 -        static final EnsureInitialized INSTANCE = new EnsureInitialized();
   1.350 -    }
   1.351 -
   1.352 -    private void ensureInitialized() {
   1.353 -        if (checkInitialized(member)) {
   1.354 -            // The coast is clear.  Delete the <clinit> barrier.
   1.355 -            if (member.isField())
   1.356 -                updateForm(preparedFieldLambdaForm(member));
   1.357 -            else
   1.358 -                updateForm(preparedLambdaForm(member));
   1.359 -        }
   1.360 -    }
   1.361 -    private static boolean checkInitialized(MemberName member) {
   1.362 -        Class<?> defc = member.getDeclaringClass();
   1.363 -        WeakReference<Thread> ref = EnsureInitialized.INSTANCE.get(defc);
   1.364 -        if (ref == null) {
   1.365 -            return true;  // the final state
   1.366 -        }
   1.367 -        Thread clinitThread = ref.get();
   1.368 -        // Somebody may still be running defc.<clinit>.
   1.369 -        if (clinitThread == Thread.currentThread()) {
   1.370 -            // If anybody is running defc.<clinit>, it is this thread.
   1.371 -            if (shouldBeInitialized(defc))
   1.372 -                // Yes, we are running it; keep the barrier for now.
   1.373 -                return false;
   1.374 -        } else {
   1.375 -            // We are in a random thread.  Block.
   1.376 -            ensureClassInitialized(defc);
   1.377 -        }
   1.378 -        assert(!shouldBeInitialized(defc));
   1.379 -        // put it into the final state
   1.380 -        EnsureInitialized.INSTANCE.remove(defc);
   1.381 -        return true;
   1.382 -    }
   1.383 -
   1.384 -    /*non-public*/ static void ensureInitialized(Object mh) {
   1.385 -        ((DirectMethodHandle)mh).ensureInitialized();
   1.386 -    }
   1.387 -
   1.388 -    /** This subclass represents invokespecial instructions. */
   1.389 -    static class Special extends DirectMethodHandle {
   1.390 -        private Special(MethodType mtype, LambdaForm form, MemberName member) {
   1.391 -            super(mtype, form, member);
   1.392 -        }
   1.393 -        @Override
   1.394 -        boolean isInvokeSpecial() {
   1.395 -            return true;
   1.396 -        }
   1.397 -        @Override
   1.398 -        MethodHandle viewAsType(MethodType newType) {
   1.399 -            return new Special(newType, form, member);
   1.400 -        }
   1.401 -    }
   1.402 -
   1.403 -    /** This subclass handles constructor references. */
   1.404 -    static class Constructor extends DirectMethodHandle {
   1.405 -        final MemberName initMethod;
   1.406 -        final Class<?>   instanceClass;
   1.407 -
   1.408 -        private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
   1.409 -                            MemberName initMethod, Class<?> instanceClass) {
   1.410 -            super(mtype, form, constructor);
   1.411 -            this.initMethod = initMethod;
   1.412 -            this.instanceClass = instanceClass;
   1.413 -            assert(initMethod.isResolved());
   1.414 -        }
   1.415 -        @Override
   1.416 -        MethodHandle viewAsType(MethodType newType) {
   1.417 -            return new Constructor(newType, form, member, initMethod, instanceClass);
   1.418 -        }
   1.419 -    }
   1.420 -
   1.421 -    /*non-public*/ static Object constructorMethod(Object mh) {
   1.422 -        Constructor dmh = (Constructor)mh;
   1.423 -        return dmh.initMethod;
   1.424 -    }
   1.425 -
   1.426 -    /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
   1.427 -        Constructor dmh = (Constructor)mh;
   1.428 -        try {
   1.429 -            return dmh.instanceClass.newInstance();
   1.430 -//        return UNSAFE.allocateInstance(dmh.instanceClass);
   1.431 -        } catch (IllegalAccessException ex) {
   1.432 -            throw (InstantiationException)new InstantiationException().initCause(ex);
   1.433 -        }
   1.434 -    }
   1.435 -
   1.436 -    /** This subclass handles non-static field references. */
   1.437 -    static class Accessor extends DirectMethodHandle {
   1.438 -        final Class<?> fieldType;
   1.439 -        final int      fieldOffset;
   1.440 -        private Accessor(MethodType mtype, LambdaForm form, MemberName member,
   1.441 -                         int fieldOffset) {
   1.442 -            super(mtype, form, member);
   1.443 -            this.fieldType   = member.getFieldType();
   1.444 -            this.fieldOffset = fieldOffset;
   1.445 -        }
   1.446 -
   1.447 -        @Override Object checkCast(Object obj) {
   1.448 -            return fieldType.cast(obj);
   1.449 -        }
   1.450 -        @Override
   1.451 -        MethodHandle viewAsType(MethodType newType) {
   1.452 -            return new Accessor(newType, form, member, fieldOffset);
   1.453 -        }
   1.454 -    }
   1.455 -
   1.456 -    @ForceInline
   1.457 -    /*non-public*/ static long fieldOffset(Object accessorObj) {
   1.458 -        // Note: We return a long because that is what Unsafe.getObject likes.
   1.459 -        // We store a plain int because it is more compact.
   1.460 -        return ((Accessor)accessorObj).fieldOffset;
   1.461 -    }
   1.462 -
   1.463 -    @ForceInline
   1.464 -    /*non-public*/ static Object checkBase(Object obj) {
   1.465 -        // Note that the object's class has already been verified,
   1.466 -        // since the parameter type of the Accessor method handle
   1.467 -        // is either member.getDeclaringClass or a subclass.
   1.468 -        // This was verified in DirectMethodHandle.make.
   1.469 -        // Therefore, the only remaining check is for null.
   1.470 -        // Since this check is *not* guaranteed by Unsafe.getInt
   1.471 -        // and its siblings, we need to make an explicit one here.
   1.472 -        obj.getClass();  // maybe throw NPE
   1.473 -        return obj;
   1.474 -    }
   1.475 -
   1.476 -    /** This subclass handles static field references. */
   1.477 -    static class StaticAccessor extends DirectMethodHandle {
   1.478 -        final private Class<?> fieldType;
   1.479 -        final private Object   staticBase;
   1.480 -        final private long     staticOffset;
   1.481 -
   1.482 -        private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
   1.483 -                               Object staticBase, long staticOffset) {
   1.484 -            super(mtype, form, member);
   1.485 -            this.fieldType    = member.getFieldType();
   1.486 -            this.staticBase   = staticBase;
   1.487 -            this.staticOffset = staticOffset;
   1.488 -        }
   1.489 -
   1.490 -        @Override Object checkCast(Object obj) {
   1.491 -            return fieldType.cast(obj);
   1.492 -        }
   1.493 -        @Override
   1.494 -        MethodHandle viewAsType(MethodType newType) {
   1.495 -            return new StaticAccessor(newType, form, member, staticBase, staticOffset);
   1.496 -        }
   1.497 -    }
   1.498 -
   1.499 -    @ForceInline
   1.500 -    /*non-public*/ static Object nullCheck(Object obj) {
   1.501 -        obj.getClass();
   1.502 -        return obj;
   1.503 -    }
   1.504 -
   1.505 -    @ForceInline
   1.506 -    /*non-public*/ static Object staticBase(Object accessorObj) {
   1.507 -        return ((StaticAccessor)accessorObj).staticBase;
   1.508 -    }
   1.509 -
   1.510 -    @ForceInline
   1.511 -    /*non-public*/ static long staticOffset(Object accessorObj) {
   1.512 -        return ((StaticAccessor)accessorObj).staticOffset;
   1.513 -    }
   1.514 -
   1.515 -    @ForceInline
   1.516 -    /*non-public*/ static Object checkCast(Object mh, Object obj) {
   1.517 -        return ((DirectMethodHandle) mh).checkCast(obj);
   1.518 -    }
   1.519 -
   1.520 -    Object checkCast(Object obj) {
   1.521 -        return member.getReturnType().cast(obj);
   1.522 -    }
   1.523 -
   1.524 -    // Caching machinery for field accessors:
   1.525 -    private static byte
   1.526 -            AF_GETFIELD        = 0,
   1.527 -            AF_PUTFIELD        = 1,
   1.528 -            AF_GETSTATIC       = 2,
   1.529 -            AF_PUTSTATIC       = 3,
   1.530 -            AF_GETSTATIC_INIT  = 4,
   1.531 -            AF_PUTSTATIC_INIT  = 5,
   1.532 -            AF_LIMIT           = 6;
   1.533 -    // Enumerate the different field kinds using Wrapper,
   1.534 -    // with an extra case added for checked references.
   1.535 -    private static int
   1.536 -            FT_LAST_WRAPPER    = Wrapper.values().length-1,
   1.537 -            FT_UNCHECKED_REF   = Wrapper.OBJECT.ordinal(),
   1.538 -            FT_CHECKED_REF     = FT_LAST_WRAPPER+1,
   1.539 -            FT_LIMIT           = FT_LAST_WRAPPER+2;
   1.540 -    private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
   1.541 -        return ((formOp * FT_LIMIT * 2)
   1.542 -                + (isVolatile ? FT_LIMIT : 0)
   1.543 -                + ftypeKind);
   1.544 -    }
   1.545 -    private static final LambdaForm[] ACCESSOR_FORMS
   1.546 -            = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
   1.547 -    private static int ftypeKind(Class<?> ftype) {
   1.548 -        if (ftype.isPrimitive())
   1.549 -            return Wrapper.forPrimitiveType(ftype).ordinal();
   1.550 -        else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
   1.551 -            return FT_UNCHECKED_REF;
   1.552 -        else
   1.553 -            return FT_CHECKED_REF;
   1.554 -    }
   1.555 -
   1.556 -    /**
   1.557 -     * Create a LF which can access the given field.
   1.558 -     * Cache and share this structure among all fields with
   1.559 -     * the same basicType and refKind.
   1.560 -     */
   1.561 -    private static LambdaForm preparedFieldLambdaForm(MemberName m) {
   1.562 -        Class<?> ftype = m.getFieldType();
   1.563 -        boolean isVolatile = m.isVolatile();
   1.564 -        byte formOp;
   1.565 -        switch (m.getReferenceKind()) {
   1.566 -        case REF_getField:      formOp = AF_GETFIELD;    break;
   1.567 -        case REF_putField:      formOp = AF_PUTFIELD;    break;
   1.568 -        case REF_getStatic:     formOp = AF_GETSTATIC;   break;
   1.569 -        case REF_putStatic:     formOp = AF_PUTSTATIC;   break;
   1.570 -        default:  throw new InternalError(m.toString());
   1.571 -        }
   1.572 -        if (shouldBeInitialized(m)) {
   1.573 -            // precompute the barrier-free version:
   1.574 -            preparedFieldLambdaForm(formOp, isVolatile, ftype);
   1.575 -            assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
   1.576 -                   (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
   1.577 -            formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
   1.578 -        }
   1.579 -        LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
   1.580 -        maybeCompile(lform, m);
   1.581 -        assert(lform.methodType().dropParameterTypes(0, 1)
   1.582 -                .equals(m.getInvocationType().basicType()))
   1.583 -                : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
   1.584 -        return lform;
   1.585 -    }
   1.586 -    private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
   1.587 -        int afIndex = afIndex(formOp, isVolatile, ftypeKind(ftype));
   1.588 -        LambdaForm lform = ACCESSOR_FORMS[afIndex];
   1.589 -        if (lform != null)  return lform;
   1.590 -        lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind(ftype));
   1.591 -        ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
   1.592 -        return lform;
   1.593 -    }
   1.594 -
   1.595 -    private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
   1.596 -        boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
   1.597 -        boolean isStatic  = (formOp >= AF_GETSTATIC);
   1.598 -        boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
   1.599 -        boolean needsCast = (ftypeKind == FT_CHECKED_REF);
   1.600 -        Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]);
   1.601 -        Class<?> ft = fw.primitiveType();
   1.602 -        assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
   1.603 -        String tname  = fw.primitiveSimpleName();
   1.604 -        String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
   1.605 -        if (isVolatile)  ctname += "Volatile";
   1.606 -        String getOrPut = (isGetter ? "get" : "put");
   1.607 -        String linkerName = (getOrPut + ctname);  // getObject, putIntVolatile, etc.
   1.608 -        MethodType linkerType;
   1.609 -        if (isGetter)
   1.610 -            linkerType = MethodType.methodType(ft, Object.class, long.class);
   1.611 -        else
   1.612 -            linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
   1.613 -        MemberName linker = null;//new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
   1.614 -        try {
   1.615 -            linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
   1.616 -        } catch (ReflectiveOperationException ex) {
   1.617 -            throw newInternalError(ex);
   1.618 -        }
   1.619 -
   1.620 -        // What is the external type of the lambda form?
   1.621 -        MethodType mtype;
   1.622 -        if (isGetter)
   1.623 -            mtype = MethodType.methodType(ft);
   1.624 -        else
   1.625 -            mtype = MethodType.methodType(void.class, ft);
   1.626 -        mtype = mtype.basicType();  // erase short to int, etc.
   1.627 -        if (!isStatic)
   1.628 -            mtype = mtype.insertParameterTypes(0, Object.class);
   1.629 -        final int DMH_THIS  = 0;
   1.630 -        final int ARG_BASE  = 1;
   1.631 -        final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
   1.632 -        // if this is for non-static access, the base pointer is stored at this index:
   1.633 -        final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
   1.634 -        // if this is for write access, the value to be written is stored at this index:
   1.635 -        final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
   1.636 -        int nameCursor = ARG_LIMIT;
   1.637 -        final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
   1.638 -        final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
   1.639 -        final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
   1.640 -        final int INIT_BAR  = (needsInit ? nameCursor++ : -1);
   1.641 -        final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
   1.642 -        final int LINKER_CALL = nameCursor++;
   1.643 -        final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
   1.644 -        final int RESULT    = nameCursor-1;  // either the call or the cast
   1.645 -        Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
   1.646 -        if (needsInit)
   1.647 -            names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
   1.648 -        if (needsCast && !isGetter)
   1.649 -            names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
   1.650 -        Object[] outArgs = new Object[1 + linkerType.parameterCount()];
   1.651 -        assert(outArgs.length == (isGetter ? 3 : 4));
   1.652 -//        outArgs[0] = UNSAFE;
   1.653 -        if (isStatic) {
   1.654 -            outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
   1.655 -            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
   1.656 -        } else {
   1.657 -            outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
   1.658 -            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
   1.659 -        }
   1.660 -        if (!isGetter) {
   1.661 -            outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
   1.662 -        }
   1.663 -        for (Object a : outArgs)  assert(a != null);
   1.664 -        names[LINKER_CALL] = new Name(linker, outArgs);
   1.665 -        if (needsCast && isGetter)
   1.666 -            names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
   1.667 -        for (Name n : names)  assert(n != null);
   1.668 -        String fieldOrStatic = (isStatic ? "Static" : "Field");
   1.669 -        String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
   1.670 -        if (needsCast)  lambdaName += "Cast";
   1.671 -        if (needsInit)  lambdaName += "Init";
   1.672 -        return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
   1.673 -    }
   1.674 -
   1.675 -    /**
   1.676 -     * Pre-initialized NamedFunctions for bootstrapping purposes.
   1.677 -     * Factored in an inner class to delay initialization until first usage.
   1.678 -     */
   1.679 -    private static class Lazy {
   1.680 -        static final NamedFunction
   1.681 -                NF_internalMemberName,
   1.682 -                NF_internalMemberNameEnsureInit,
   1.683 -                NF_ensureInitialized,
   1.684 -                NF_fieldOffset,
   1.685 -                NF_checkBase,
   1.686 -                NF_staticBase,
   1.687 -                NF_staticOffset,
   1.688 -                NF_checkCast,
   1.689 -                NF_allocateInstance,
   1.690 -                NF_constructorMethod;
   1.691 -        static {
   1.692 -            try {
   1.693 -                NamedFunction nfs[] = {
   1.694 -                        NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
   1.695 -                                .getDeclaredMethod("internalMemberName", Object.class)),
   1.696 -                        NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
   1.697 -                                .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
   1.698 -                        NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
   1.699 -                                .getDeclaredMethod("ensureInitialized", Object.class)),
   1.700 -                        NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
   1.701 -                                .getDeclaredMethod("fieldOffset", Object.class)),
   1.702 -                        NF_checkBase = new NamedFunction(DirectMethodHandle.class
   1.703 -                                .getDeclaredMethod("checkBase", Object.class)),
   1.704 -                        NF_staticBase = new NamedFunction(DirectMethodHandle.class
   1.705 -                                .getDeclaredMethod("staticBase", Object.class)),
   1.706 -                        NF_staticOffset = new NamedFunction(DirectMethodHandle.class
   1.707 -                                .getDeclaredMethod("staticOffset", Object.class)),
   1.708 -                        NF_checkCast = new NamedFunction(DirectMethodHandle.class
   1.709 -                                .getDeclaredMethod("checkCast", Object.class, Object.class)),
   1.710 -                        NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
   1.711 -                                .getDeclaredMethod("allocateInstance", Object.class)),
   1.712 -                        NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
   1.713 -                                .getDeclaredMethod("constructorMethod", Object.class))
   1.714 -                };
   1.715 -                for (NamedFunction nf : nfs) {
   1.716 -                    // Each nf must be statically invocable or we get tied up in our bootstraps.
   1.717 -//                    assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
   1.718 -                    nf.resolve();
   1.719 -                }
   1.720 -            } catch (ReflectiveOperationException ex) {
   1.721 -                throw newInternalError(ex);
   1.722 -            }
   1.723 -        }
   1.724 -    }
   1.725 -    
   1.726 -    private static boolean shouldBeInitialized(Class<?> c) {
   1.727 -        return false;
   1.728 -    }
   1.729 -    
   1.730 -    private static void ensureClassInitialized(Class<?> c) {
   1.731 -        c.getName();
   1.732 -    }
   1.733 -}