1.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleNatives.java Sun Aug 17 20:09:05 2014 +0200
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,536 +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.MethodHandleNatives.Constants.*;
1.32 -import static java.lang.invoke.MethodHandleStatics.*;
1.33 -import java.lang.invoke.MethodHandles.Lookup;
1.34 -import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
1.35 -import java.lang.reflect.Constructor;
1.36 -import java.lang.reflect.Field;
1.37 -import java.lang.reflect.Member;
1.38 -import java.lang.reflect.Method;
1.39 -
1.40 -/**
1.41 - * The JVM interface for the method handles package is all here.
1.42 - * This is an interface internal and private to an implementation of JSR 292.
1.43 - * <em>This class is not part of the JSR 292 standard.</em>
1.44 - * @author jrose
1.45 - */
1.46 -class MethodHandleNatives {
1.47 -
1.48 - private MethodHandleNatives() { } // static only
1.49 -
1.50 - /// MemberName support
1.51 -
1.52 - static void init(MemberName self, Object ref) {
1.53 - final Member mem = (Member)ref;
1.54 - self.clazz = mem.getDeclaringClass();
1.55 - int mod = mem.getModifiers();
1.56 - if (ref instanceof Method) {
1.57 - mod |= MemberName.IS_METHOD;
1.58 - }
1.59 - if (ref instanceof Constructor) {
1.60 - mod |= MemberName.IS_CONSTRUCTOR;
1.61 - }
1.62 - self.flags = mod;
1.63 - }
1.64 -
1.65 - static void expand(MemberName self) {
1.66 - }
1.67 -
1.68 - static MemberName resolve(MemberName self, Class<?> caller) throws LinkageError {
1.69 - return self;
1.70 - }
1.71 - static int getMembers(Class<?> defc, String matchName, String matchSig,
1.72 - int matchFlags, Class<?> caller, int skip, MemberName[] results) {
1.73 - int orig = skip;
1.74 - for (Method m : defc.getMethods()) {
1.75 - if (skip == results.length) {
1.76 - break;
1.77 - }
1.78 - MemberName mn = new MemberName(m);
1.79 - results[skip++] = mn;
1.80 - }
1.81 - for (Constructor m : defc.getConstructors()) {
1.82 - if (skip == results.length) {
1.83 - break;
1.84 - }
1.85 - MemberName mn = new MemberName(m);
1.86 - results[skip++] = mn;
1.87 - }
1.88 -// for (Field m : defc.getFields()) {
1.89 -// if (skip == results.length) {
1.90 -// break;
1.91 -// }
1.92 -// MemberName mn = new MemberName(m);
1.93 -// results[skip++] = mn;
1.94 -// }
1.95 - return skip - orig;
1.96 - }
1.97 -
1.98 - /// Field layout queries parallel to sun.misc.Unsafe:
1.99 - static native long objectFieldOffset(MemberName self); // e.g., returns vmindex
1.100 - static native long staticFieldOffset(MemberName self); // e.g., returns vmindex
1.101 - static native Object staticFieldBase(MemberName self); // e.g., returns clazz
1.102 - static native Object getMemberVMInfo(MemberName self); // returns {vmindex,vmtarget}
1.103 -
1.104 - /// MethodHandle support
1.105 -
1.106 - /// CallSite support
1.107 -
1.108 - /** Tell the JVM that we need to change the target of a CallSite. */
1.109 - static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
1.110 - static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
1.111 -
1.112 - static {
1.113 - // The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
1.114 - MethodHandleImpl.initStatics();
1.115 -}
1.116 -
1.117 - // All compile-time constants go here.
1.118 - // There is an opportunity to check them against the JVM's idea of them.
1.119 - static class Constants {
1.120 - Constants() { } // static only
1.121 - // MethodHandleImpl
1.122 - static final int // for getConstant
1.123 - GC_COUNT_GWT = 4,
1.124 - GC_LAMBDA_SUPPORT = 5;
1.125 -
1.126 - // MemberName
1.127 - // The JVM uses values of -2 and above for vtable indexes.
1.128 - // Field values are simple positive offsets.
1.129 - // Ref: src/share/vm/oops/methodOop.hpp
1.130 - // This value is negative enough to avoid such numbers,
1.131 - // but not too negative.
1.132 - static final int
1.133 - MN_IS_METHOD = 0x00010000, // method (not constructor)
1.134 - MN_IS_CONSTRUCTOR = 0x00020000, // constructor
1.135 - MN_IS_FIELD = 0x00040000, // field
1.136 - MN_IS_TYPE = 0x00080000, // nested type
1.137 - MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
1.138 - MN_REFERENCE_KIND_SHIFT = 24, // refKind
1.139 - MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
1.140 - // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
1.141 - MN_SEARCH_SUPERCLASSES = 0x00100000,
1.142 - MN_SEARCH_INTERFACES = 0x00200000;
1.143 -
1.144 - /**
1.145 - * Basic types as encoded in the JVM. These code values are not
1.146 - * intended for use outside this class. They are used as part of
1.147 - * a private interface between the JVM and this class.
1.148 - */
1.149 - static final int
1.150 - T_BOOLEAN = 4,
1.151 - T_CHAR = 5,
1.152 - T_FLOAT = 6,
1.153 - T_DOUBLE = 7,
1.154 - T_BYTE = 8,
1.155 - T_SHORT = 9,
1.156 - T_INT = 10,
1.157 - T_LONG = 11,
1.158 - T_OBJECT = 12,
1.159 - //T_ARRAY = 13
1.160 - T_VOID = 14,
1.161 - //T_ADDRESS = 15
1.162 - T_ILLEGAL = 99;
1.163 -
1.164 - /**
1.165 - * Constant pool entry types.
1.166 - */
1.167 - static final byte
1.168 - CONSTANT_Utf8 = 1,
1.169 - CONSTANT_Integer = 3,
1.170 - CONSTANT_Float = 4,
1.171 - CONSTANT_Long = 5,
1.172 - CONSTANT_Double = 6,
1.173 - CONSTANT_Class = 7,
1.174 - CONSTANT_String = 8,
1.175 - CONSTANT_Fieldref = 9,
1.176 - CONSTANT_Methodref = 10,
1.177 - CONSTANT_InterfaceMethodref = 11,
1.178 - CONSTANT_NameAndType = 12,
1.179 - CONSTANT_MethodHandle = 15, // JSR 292
1.180 - CONSTANT_MethodType = 16, // JSR 292
1.181 - CONSTANT_InvokeDynamic = 18,
1.182 - CONSTANT_LIMIT = 19; // Limit to tags found in classfiles
1.183 -
1.184 - /**
1.185 - * Access modifier flags.
1.186 - */
1.187 - static final char
1.188 - ACC_PUBLIC = 0x0001,
1.189 - ACC_PRIVATE = 0x0002,
1.190 - ACC_PROTECTED = 0x0004,
1.191 - ACC_STATIC = 0x0008,
1.192 - ACC_FINAL = 0x0010,
1.193 - ACC_SYNCHRONIZED = 0x0020,
1.194 - ACC_VOLATILE = 0x0040,
1.195 - ACC_TRANSIENT = 0x0080,
1.196 - ACC_NATIVE = 0x0100,
1.197 - ACC_INTERFACE = 0x0200,
1.198 - ACC_ABSTRACT = 0x0400,
1.199 - ACC_STRICT = 0x0800,
1.200 - ACC_SYNTHETIC = 0x1000,
1.201 - ACC_ANNOTATION = 0x2000,
1.202 - ACC_ENUM = 0x4000,
1.203 - // aliases:
1.204 - ACC_SUPER = ACC_SYNCHRONIZED,
1.205 - ACC_BRIDGE = ACC_VOLATILE,
1.206 - ACC_VARARGS = ACC_TRANSIENT;
1.207 -
1.208 - /**
1.209 - * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
1.210 - */
1.211 - static final byte
1.212 - REF_NONE = 0, // null value
1.213 - REF_getField = 1,
1.214 - REF_getStatic = 2,
1.215 - REF_putField = 3,
1.216 - REF_putStatic = 4,
1.217 - REF_invokeVirtual = 5,
1.218 - REF_invokeStatic = 6,
1.219 - REF_invokeSpecial = 7,
1.220 - REF_newInvokeSpecial = 8,
1.221 - REF_invokeInterface = 9,
1.222 - REF_LIMIT = 10;
1.223 - }
1.224 -
1.225 - static boolean refKindIsValid(int refKind) {
1.226 - return (refKind > REF_NONE && refKind < REF_LIMIT);
1.227 - }
1.228 - static boolean refKindIsField(byte refKind) {
1.229 - assert(refKindIsValid(refKind));
1.230 - return (refKind <= REF_putStatic);
1.231 - }
1.232 - static boolean refKindIsGetter(byte refKind) {
1.233 - assert(refKindIsValid(refKind));
1.234 - return (refKind <= REF_getStatic);
1.235 - }
1.236 - static boolean refKindIsSetter(byte refKind) {
1.237 - return refKindIsField(refKind) && !refKindIsGetter(refKind);
1.238 - }
1.239 - static boolean refKindIsMethod(byte refKind) {
1.240 - return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
1.241 - }
1.242 - static boolean refKindIsConstructor(byte refKind) {
1.243 - return (refKind == REF_newInvokeSpecial);
1.244 - }
1.245 - static boolean refKindHasReceiver(byte refKind) {
1.246 - assert(refKindIsValid(refKind));
1.247 - return (refKind & 1) != 0;
1.248 - }
1.249 - static boolean refKindIsStatic(byte refKind) {
1.250 - return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
1.251 - }
1.252 - static boolean refKindDoesDispatch(byte refKind) {
1.253 - assert(refKindIsValid(refKind));
1.254 - return (refKind == REF_invokeVirtual ||
1.255 - refKind == REF_invokeInterface);
1.256 - }
1.257 - static {
1.258 - final int HR_MASK = ((1 << REF_getField) |
1.259 - (1 << REF_putField) |
1.260 - (1 << REF_invokeVirtual) |
1.261 - (1 << REF_invokeSpecial) |
1.262 - (1 << REF_invokeInterface)
1.263 - );
1.264 - for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
1.265 - assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
1.266 - }
1.267 - }
1.268 - static String refKindName(byte refKind) {
1.269 - assert(refKindIsValid(refKind));
1.270 - switch (refKind) {
1.271 - case REF_getField: return "getField";
1.272 - case REF_getStatic: return "getStatic";
1.273 - case REF_putField: return "putField";
1.274 - case REF_putStatic: return "putStatic";
1.275 - case REF_invokeVirtual: return "invokeVirtual";
1.276 - case REF_invokeStatic: return "invokeStatic";
1.277 - case REF_invokeSpecial: return "invokeSpecial";
1.278 - case REF_newInvokeSpecial: return "newInvokeSpecial";
1.279 - case REF_invokeInterface: return "invokeInterface";
1.280 - default: return "REF_???";
1.281 - }
1.282 - }
1.283 -
1.284 - private static native int getNamedCon(int which, Object[] name);
1.285 - static boolean verifyConstants() {
1.286 - Object[] box = { null };
1.287 - for (int i = 0; ; i++) {
1.288 - box[0] = null;
1.289 - int vmval = getNamedCon(i, box);
1.290 - if (box[0] == null) break;
1.291 - String name = (String) box[0];
1.292 - try {
1.293 - Field con = Constants.class.getDeclaredField(name);
1.294 - int jval = con.getInt(null);
1.295 - if (jval == vmval) continue;
1.296 - String err = (name+": JVM has "+vmval+" while Java has "+jval);
1.297 - if (name.equals("CONV_OP_LIMIT")) {
1.298 - System.err.println("warning: "+err);
1.299 - continue;
1.300 - }
1.301 - throw new InternalError(err);
1.302 - } catch (IllegalAccessException ex) {
1.303 - String err = (name+": JVM has "+vmval+" which Java does not define");
1.304 - // ignore exotic ops the JVM cares about; we just wont issue them
1.305 - //System.err.println("warning: "+err);
1.306 - continue;
1.307 - }
1.308 - }
1.309 - return true;
1.310 - }
1.311 - static {
1.312 - assert(verifyConstants());
1.313 - }
1.314 -
1.315 - // Up-calls from the JVM.
1.316 - // These must NOT be public.
1.317 -
1.318 - /**
1.319 - * The JVM is linking an invokedynamic instruction. Create a reified call site for it.
1.320 - */
1.321 - static MemberName linkCallSite(Object callerObj,
1.322 - Object bootstrapMethodObj,
1.323 - Object nameObj, Object typeObj,
1.324 - Object staticArguments,
1.325 - Object[] appendixResult) {
1.326 - MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
1.327 - Class<?> caller = (Class<?>)callerObj;
1.328 - String name = nameObj.toString().intern();
1.329 - MethodType type = (MethodType)typeObj;
1.330 - CallSite callSite = CallSite.makeSite(bootstrapMethod,
1.331 - name,
1.332 - type,
1.333 - staticArguments,
1.334 - caller);
1.335 - if (callSite instanceof ConstantCallSite) {
1.336 - appendixResult[0] = callSite.dynamicInvoker();
1.337 - return Invokers.linkToTargetMethod(type);
1.338 - } else {
1.339 - appendixResult[0] = callSite;
1.340 - return Invokers.linkToCallSiteMethod(type);
1.341 - }
1.342 - }
1.343 -
1.344 - /**
1.345 - * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
1.346 - */
1.347 - static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
1.348 - return MethodType.makeImpl(rtype, ptypes, true);
1.349 - }
1.350 -
1.351 - /**
1.352 - * The JVM wants to link a call site that requires a dynamic type check.
1.353 - * Name is a type-checking invoker, invokeExact or invoke.
1.354 - * Return a JVM method (MemberName) to handle the invoking.
1.355 - * The method assumes the following arguments on the stack:
1.356 - * 0: the method handle being invoked
1.357 - * 1-N: the arguments to the method handle invocation
1.358 - * N+1: an optional, implicitly added argument (typically the given MethodType)
1.359 - * <p>
1.360 - * The nominal method at such a call site is an instance of
1.361 - * a signature-polymorphic method (see @PolymorphicSignature).
1.362 - * Such method instances are user-visible entities which are
1.363 - * "split" from the generic placeholder method in {@code MethodHandle}.
1.364 - * (Note that the placeholder method is not identical with any of
1.365 - * its instances. If invoked reflectively, is guaranteed to throw an
1.366 - * {@code UnsupportedOperationException}.)
1.367 - * If the signature-polymorphic method instance is ever reified,
1.368 - * it appears as a "copy" of the original placeholder
1.369 - * (a native final member of {@code MethodHandle}) except
1.370 - * that its type descriptor has shape required by the instance,
1.371 - * and the method instance is <em>not</em> varargs.
1.372 - * The method instance is also marked synthetic, since the
1.373 - * method (by definition) does not appear in Java source code.
1.374 - * <p>
1.375 - * The JVM is allowed to reify this method as instance metadata.
1.376 - * For example, {@code invokeBasic} is always reified.
1.377 - * But the JVM may instead call {@code linkMethod}.
1.378 - * If the result is an * ordered pair of a {@code (method, appendix)},
1.379 - * the method gets all the arguments (0..N inclusive)
1.380 - * plus the appendix (N+1), and uses the appendix to complete the call.
1.381 - * In this way, one reusable method (called a "linker method")
1.382 - * can perform the function of any number of polymorphic instance
1.383 - * methods.
1.384 - * <p>
1.385 - * Linker methods are allowed to be weakly typed, with any or
1.386 - * all references rewritten to {@code Object} and any primitives
1.387 - * (except {@code long}/{@code float}/{@code double})
1.388 - * rewritten to {@code int}.
1.389 - * A linker method is trusted to return a strongly typed result,
1.390 - * according to the specific method type descriptor of the
1.391 - * signature-polymorphic instance it is emulating.
1.392 - * This can involve (as necessary) a dynamic check using
1.393 - * data extracted from the appendix argument.
1.394 - * <p>
1.395 - * The JVM does not inspect the appendix, other than to pass
1.396 - * it verbatim to the linker method at every call.
1.397 - * This means that the JDK runtime has wide latitude
1.398 - * for choosing the shape of each linker method and its
1.399 - * corresponding appendix.
1.400 - * Linker methods should be generated from {@code LambdaForm}s
1.401 - * so that they do not become visible on stack traces.
1.402 - * <p>
1.403 - * The {@code linkMethod} call is free to omit the appendix
1.404 - * (returning null) and instead emulate the required function
1.405 - * completely in the linker method.
1.406 - * As a corner case, if N==255, no appendix is possible.
1.407 - * In this case, the method returned must be custom-generated to
1.408 - * to perform any needed type checking.
1.409 - * <p>
1.410 - * If the JVM does not reify a method at a call site, but instead
1.411 - * calls {@code linkMethod}, the corresponding call represented
1.412 - * in the bytecodes may mention a valid method which is not
1.413 - * representable with a {@code MemberName}.
1.414 - * Therefore, use cases for {@code linkMethod} tend to correspond to
1.415 - * special cases in reflective code such as {@code findVirtual}
1.416 - * or {@code revealDirect}.
1.417 - */
1.418 - static MemberName linkMethod(Class<?> callerClass, int refKind,
1.419 - Class<?> defc, String name, Object type,
1.420 - Object[] appendixResult) {
1.421 - if (!TRACE_METHOD_LINKAGE)
1.422 - return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
1.423 - return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
1.424 - }
1.425 - static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
1.426 - Class<?> defc, String name, Object type,
1.427 - Object[] appendixResult) {
1.428 - try {
1.429 - if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
1.430 - return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
1.431 - }
1.432 - } catch (Throwable ex) {
1.433 - if (ex instanceof LinkageError)
1.434 - throw (LinkageError) ex;
1.435 - else
1.436 - throw new LinkageError(ex.getMessage(), ex);
1.437 - }
1.438 - throw new LinkageError("no such method "+defc.getName()+"."+name+type);
1.439 - }
1.440 - private static MethodType fixMethodType(Class<?> callerClass, Object type) {
1.441 - if (type instanceof MethodType)
1.442 - return (MethodType) type;
1.443 - else
1.444 - return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
1.445 - }
1.446 - // Tracing logic:
1.447 - static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
1.448 - Class<?> defc, String name, Object type,
1.449 - Object[] appendixResult) {
1.450 - System.out.println("linkMethod "+defc.getName()+"."+
1.451 - name+type+"/"+Integer.toHexString(refKind));
1.452 - try {
1.453 - MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
1.454 - System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
1.455 - return res;
1.456 - } catch (Throwable ex) {
1.457 - System.out.println("linkMethod => throw "+ex);
1.458 - throw ex;
1.459 - }
1.460 - }
1.461 -
1.462 -
1.463 - /**
1.464 - * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
1.465 - * It will make an up-call to this method. (Do not change the name or signature.)
1.466 - * The type argument is a Class for field requests and a MethodType for non-fields.
1.467 - * <p>
1.468 - * Recent versions of the JVM may also pass a resolved MemberName for the type.
1.469 - * In that case, the name is ignored and may be null.
1.470 - */
1.471 - static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
1.472 - Class<?> defc, String name, Object type) {
1.473 - try {
1.474 - Lookup lookup = IMPL_LOOKUP.in(callerClass);
1.475 - assert(refKindIsValid(refKind));
1.476 - return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
1.477 - } catch (IllegalAccessException ex) {
1.478 - Throwable cause = ex.getCause();
1.479 - if (cause instanceof AbstractMethodError) {
1.480 - throw (AbstractMethodError) cause;
1.481 - } else {
1.482 - Error err = new IllegalAccessError(ex.getMessage());
1.483 - throw initCauseFrom(err, ex);
1.484 - }
1.485 - } catch (NoSuchMethodException ex) {
1.486 - Error err = new NoSuchMethodError(ex.getMessage());
1.487 - throw initCauseFrom(err, ex);
1.488 - } catch (NoSuchFieldException ex) {
1.489 - Error err = new NoSuchFieldError(ex.getMessage());
1.490 - throw initCauseFrom(err, ex);
1.491 - } catch (ReflectiveOperationException ex) {
1.492 - Error err = new IncompatibleClassChangeError();
1.493 - throw initCauseFrom(err, ex);
1.494 - }
1.495 - }
1.496 -
1.497 - /**
1.498 - * Use best possible cause for err.initCause(), substituting the
1.499 - * cause for err itself if the cause has the same (or better) type.
1.500 - */
1.501 - static private Error initCauseFrom(Error err, Exception ex) {
1.502 - Throwable th = ex.getCause();
1.503 - if (err.getClass().isInstance(th))
1.504 - return (Error) th;
1.505 - err.initCause(th == null ? ex : th);
1.506 - return err;
1.507 - }
1.508 -
1.509 - /**
1.510 - * Is this method a caller-sensitive method?
1.511 - * I.e., does it call Reflection.getCallerClass or a similer method
1.512 - * to ask about the identity of its caller?
1.513 - */
1.514 - static boolean isCallerSensitive(MemberName mem) {
1.515 - if (!mem.isInvocable()) return false; // fields are not caller sensitive
1.516 -
1.517 - return mem.isCallerSensitive() || canBeCalledVirtual(mem);
1.518 - }
1.519 -
1.520 - static boolean canBeCalledVirtual(MemberName mem) {
1.521 - assert(mem.isInvocable());
1.522 - Class<?> defc = mem.getDeclaringClass();
1.523 - switch (mem.getName()) {
1.524 - case "checkMemberAccess":
1.525 - return true; //canBeCalledVirtual(mem, java.lang.SecurityManager.class);
1.526 - case "getContextClassLoader":
1.527 - return canBeCalledVirtual(mem, java.lang.Thread.class);
1.528 - }
1.529 - return false;
1.530 - }
1.531 -
1.532 - static boolean canBeCalledVirtual(MemberName symbolicRef, Class<?> definingClass) {
1.533 - Class<?> symbolicRefClass = symbolicRef.getDeclaringClass();
1.534 - if (symbolicRefClass == definingClass) return true;
1.535 - if (symbolicRef.isStatic() || symbolicRef.isPrivate()) return false;
1.536 - return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef
1.537 - symbolicRefClass.isInterface()); // Mdef implements Msym
1.538 - }
1.539 -}