1 /*
   2  * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.invoke.util.BytecodeDescriptor;
  29 import sun.invoke.util.VerifyAccess;
  30 
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.Field;
  33 import java.lang.reflect.Method;
  34 import java.lang.reflect.Member;
  35 import java.lang.reflect.Modifier;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collections;
  39 import java.util.Iterator;
  40 import java.util.List;
  41 import java.util.Objects;
  42 import sun.misc.JavaLangAccess;
  43 import sun.misc.SharedSecrets;
  44 
  45 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  46 import static java.lang.invoke.MethodHandleStatics.*;
  47 import sun.misc.Unsafe;
  48 
  49 
  50 /**
  51  * A {@code MemberName} is a compact symbolic datum which fully characterizes
  52  * a method or field reference.
  53  * A member name refers to a field, method, constructor, or member type.
  54  * Every member name has a simple name (a string) and a type (either a Class or MethodType).
  55  * A member name may also have a non-null declaring class, or it may be simply
  56  * a naked name/type pair.
  57  * A member name may also have non-zero modifier flags.
  58  * Finally, a member name may be either resolved or unresolved.
  59  * <p>
  60  * Whether resolved or not, a member name provides no access rights or
  61  * invocation capability to its possessor.  It is merely a compact
  62  * representation of all symbolic information necessary to link to
  63  * and properly use the named member.
  64  * <p>
  65  * When resolved, a member name's internal implementation may include references to JVM metadata.
  66  * This representation is stateless and only descriptive.
  67  * It provides no private information and no capability to use the member.
  68  * Resolved MemberNames are always interned (except for Class MemberNames)
  69  * which allows updating when classes are redefined.
  70  * <p>
  71  * By contrast, a {@linkplain java.lang.reflect.Method} contains fuller information
  72  * about the internals of a method (except its bytecodes) and also
  73  * allows invocation.  A MemberName is much lighter than a Method,
  74  * since it contains about 7 fields to the 16 of Method (plus its sub-arrays),
  75  * and those seven fields omit much of the information in Method.
  76  * @author jrose
  77  */
  78 /*non-public*/ final class MemberName implements Member, Cloneable {
  79     private Class<?>   clazz;       // class in which the method is defined
  80     private String     name;        // may be null if not yet materialized
  81     private Object     type;        // may be null if not yet materialized
  82     private int        flags;       // modifier bits; see reflect.Modifier
  83     private MemberName next;        // used for a linked list of MemberNames known to VM
  84     //@Injected JVM_Method* vmtarget;
  85     //@Injected int         vmindex;
  86     private Object     resolution;  // if null, this guy is resolved
  87 
  88     private static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
  89 
  90     // bare-bones constructor; the JVM will fill it in
  91     MemberName() { }
  92 
  93     /** Create a name for the given class.  The resulting name will be in a resolved state. */
  94     public MemberName(Class<?> type) {
  95         init(type.getDeclaringClass(), type.getSimpleName(), type,
  96                 flagsMods(IS_TYPE, type.getModifiers(), REF_NONE));
  97         initResolved(true);
  98     }
  99 
 100     // Construction from symbolic parts, for queries:
 101     /** Create a field or type name from the given components:
 102      *  Declaring class, name, type, reference kind.
 103      *  The declaring class may be supplied as null if this is to be a bare name and type.
 104      *  The resulting name will in an unresolved state.
 105      */
 106     public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
 107         init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
 108         initResolved(false);
 109     }
 110 
 111     /** Create a field or type name from the given components:  Declaring class, name, type.
 112      *  The declaring class may be supplied as null if this is to be a bare name and type.
 113      *  The modifier flags default to zero.
 114      *  The resulting name will in an unresolved state.
 115      */
 116     public MemberName(Class<?> defClass, String name, Class<?> type, Void unused) {
 117         this(defClass, name, type, REF_NONE);
 118         initResolved(false);
 119     }
 120 
 121     /** Create a method or constructor name from the given components:  Declaring class, name, type, modifiers.
 122      *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
 123      *  The declaring class may be supplied as null if this is to be a bare name and type.
 124      *  The last argument is optional, a boolean which requests REF_invokeSpecial.
 125      *  The resulting name will in an unresolved state.
 126      */
 127     public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
 128         int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
 129         init(defClass, name, type, flagsMods(initFlags, 0, refKind));
 130         initResolved(false);
 131     }
 132 
 133     /** Create a method, constructor, or field name from the given components:
 134      *  Reference kind, declaring class, name, type.
 135      */
 136     public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
 137         int kindFlags;
 138         if (MethodHandleNatives.refKindIsField(refKind)) {
 139             kindFlags = IS_FIELD;
 140             if (!(type instanceof Class))
 141                 throw newIllegalArgumentException("not a field type");
 142         } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
 143             kindFlags = IS_METHOD;
 144             if (!(type instanceof MethodType))
 145                 throw newIllegalArgumentException("not a method type");
 146         } else if (refKind == REF_newInvokeSpecial) {
 147             kindFlags = IS_CONSTRUCTOR;
 148             if (!(type instanceof MethodType) ||
 149                 !CONSTRUCTOR_NAME.equals(name))
 150                 throw newIllegalArgumentException("not a constructor type or name");
 151         } else {
 152             throw newIllegalArgumentException("bad reference kind "+refKind);
 153         }
 154         init(defClass, name, type, flagsMods(kindFlags, 0, refKind));
 155         initResolved(false);
 156     }
 157 
 158     /** Create a name for the given reflected method.  The resulting name will be in a resolved state. */
 159     public static MemberName make(Method m) {
 160         return make(m, false);
 161     }
 162 
 163     @SuppressWarnings("LeakingThisInConstructor")
 164     private MemberName(Method m, boolean wantSpecial) {
 165         m.getClass();  // NPE check
 166         // fill in vmtarget, vmindex while we have m in hand:
 167         MethodHandleNatives.init(this, m);
 168         if (clazz == null) {  // MHN.init failed
 169             if (m.getDeclaringClass() == MethodHandle.class &&
 170                 isMethodHandleInvokeName(m.getName())) {
 171                 // The JVM did not reify this signature-polymorphic instance.
 172                 // Need a special case here.
 173                 // See comments on MethodHandleNatives.linkMethod.
 174                 MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
 175                 int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual);
 176                 init(MethodHandle.class, m.getName(), type, flags);
 177                 if (isMethodHandleInvoke()) {
 178                     return;
 179                 }
 180             }
 181             throw new LinkageError(m.toString());
 182         }
 183         assert(isResolved() && this.clazz != null);
 184         this.name = m.getName();
 185         if (this.type == null) {
 186             this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
 187         }
 188         if (wantSpecial) {
 189             if (isAbstract()) {
 190                 throw new AbstractMethodError(this.toString());
 191             }
 192             if (getReferenceKind() == REF_invokeVirtual) {
 193                 changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 194             } else if (getReferenceKind() == REF_invokeInterface) {
 195                 // invokeSpecial on a default method
 196                 changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 197             }
 198         }
 199     }
 200 
 201     public static MemberName make(Method m, boolean wantSpecial) {
 202         // Unreflected member names are resolved so intern them here.
 203         MemberName tmp0 = null;
 204         InternTransaction tx = new InternTransaction(m.getDeclaringClass());
 205         while (tmp0 == null) {
 206             MemberName tmp = new MemberName(m, wantSpecial);
 207             tmp0 = tx.tryIntern(tmp);
 208         }
 209         return tmp0;
 210     }
 211 
 212     @SuppressWarnings("LeakingThisInConstructor")
 213     private MemberName(Constructor<?> ctor) {
 214         ctor.getClass();  // NPE check
 215         // fill in vmtarget, vmindex while we have ctor in hand:
 216         MethodHandleNatives.init(this, ctor);
 217         assert(isResolved() && this.clazz != null);
 218         this.name = CONSTRUCTOR_NAME;
 219         if (this.type == null) {
 220             this.type = new Object[] { void.class, ctor.getParameterTypes() };
 221         }
 222     }
 223 
 224     /**
 225      * Create a name for the given reflected constructor.
 226      * The resulting name will be in a resolved state.
 227      */
 228     public static MemberName make(Constructor<?> ctor) {
 229         // Unreflected member names are resolved so intern them here.
 230         MemberName tmp0 = null;
 231         InternTransaction tx = new InternTransaction(ctor.getDeclaringClass());
 232         while (tmp0 == null) {
 233             MemberName tmp = new MemberName(ctor);
 234             tmp0 = tx.tryIntern(tmp);
 235         }
 236         return tmp0;
 237     }
 238 
 239     /**
 240      * Create a name for the given reflected field.
 241      * The resulting name will be in a resolved state.
 242      */
 243     public static MemberName make(Field field) {
 244         return make(field, false);
 245     }
 246 
 247     @SuppressWarnings("LeakingThisInConstructor")
 248     private MemberName(Field field, boolean makeSetter) {
 249         field.getClass();  // NPE check
 250         // fill in vmtarget, vmindex while we have field in hand:
 251         MethodHandleNatives.init(this, field);
 252         assert(isResolved() && this.clazz != null);
 253         this.name = field.getName();
 254         this.type = field.getType();
 255         byte refKind = this.getReferenceKind();
 256         assert(refKind == (isStatic() ? REF_getStatic : REF_getField));
 257         if (makeSetter) {
 258             assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 259             changeReferenceKind((byte)(refKind + (REF_putStatic - REF_getStatic)), refKind);
 260         }
 261     }
 262 
 263     /**
 264      * Create a name for the given reflected field, optionally making it a setter.
 265      * The resulting name will be in a resolved state.
 266      */
 267     public static MemberName make(Field field, boolean makeSetter) {
 268         // Unreflected member names are resolved so intern them here.
 269         MemberName tmp0 = null;
 270         InternTransaction tx = new InternTransaction(field.getDeclaringClass());
 271         while (tmp0 == null) {
 272             MemberName tmp = new MemberName(field, makeSetter);
 273             tmp0 = tx.tryIntern(tmp);
 274         }
 275         return tmp0;
 276     }
 277 
 278     /** Initialize a query.   It is not resolved. */
 279     private void init(Class<?> defClass, String name, Object type, int flags) {
 280         // defining class is allowed to be null (for a naked name/type pair)
 281         //name.toString();  // null check
 282         //type.equals(type);  // null check
 283         // fill in fields:
 284         this.clazz = defClass;
 285         this.name = name;
 286         this.type = type;
 287         this.flags = flags;
 288         assert(testAnyFlags(ALL_KINDS));
 289         assert(this.resolution == null);  // nobody should have touched this yet
 290         //assert(referenceKindIsConsistent());  // do this after resolution
 291     }
 292 
 293     private void initResolved(boolean isResolved) {
 294         assert(this.resolution == null);  // not initialized yet!
 295         if (!isResolved)
 296             this.resolution = this;
 297         assert(isResolved() == isResolved);
 298     }
 299 
 300     /**
 301      * Helper method to intern this member name in the declaring class' member name table.
 302      */
 303     @SuppressWarnings("unchecked")
 304     private MemberName intern(int transaction_token) {
 305         return internMemberName(clazz, this, transaction_token);
 306     }
 307 
 308     /**
 309      * Helper method to obtain the transaction token for interning, given Class clazz.
 310      * @param clazz
 311      * @return transaction token (class redefinition count)
 312      */
 313     static private int internTxnToken(Class clazz) {
 314         return clazz == null ? 0 : jla.getClassRedefinedCount(clazz);
 315     }
 316 
 317     /**
 318      * Helper method to obtain the transaction token for interning, given this.
 319      * @return
 320      */
 321     private int internTxnToken() {
 322         return internTxnToken(clazz);
 323     }
 324 
 325     /**
 326      * Helper method to conditionally intern cloned+modified member names.
 327      */
 328     private MemberName intern(MemberName likeThis, int transaction_token) {
 329         if (likeThis.isResolved())
 330             return intern(transaction_token);
 331         else
 332             return this;
 333     }
 334 
 335     /**
 336      * Helper class to handle the case where the class checked for no
 337      * redefinition may not be correct; resolution can end up with a different
 338      * class.
 339      */
 340     static class InternTransaction {
 341         Class<?> tx_class;
 342         int txn_token;
 343 
 344         InternTransaction(Class<?> tx_class) {
 345             this.tx_class = tx_class;
 346             this.txn_token = internTxnToken(tx_class);
 347         }
 348 
 349         /**
 350          * If member_name is not resolved, returns member_name; if is resolved,
 351          * attempts to intern member_name (once) while checking for races.
 352          *
 353          * @param member_name
 354          * @return member_name if not resolved, null if racing, otherwise
 355          *         value of interned member_name.
 356          */
 357         MemberName tryIntern(MemberName member_name) {
 358             if (member_name.isResolved()) {
 359                 if (member_name.clazz != tx_class) {
 360                     Class prev_tx_class = tx_class;
 361                     int prev_txn_token = txn_token;
 362                     tx_class = member_name.clazz;
 363                     txn_token = internTxnToken(tx_class);
 364                     // Zero is a special case.
 365                     if (txn_token != 0 ||
 366                         prev_txn_token != internTxnToken(prev_tx_class)) {
 367                         // Resolved class is different and at least one
 368                         // redef of it occurred, therefore repeat with
 369                         // proper class for race consistency checking.
 370                         return null;
 371                     }
 372                 }
 373                 member_name = member_name.intern(txn_token);
 374                 if (member_name == null) {
 375                     // Update the token for the next try.
 376                     txn_token = internTxnToken(tx_class);
 377                 }
 378             }
 379             return member_name;
 380         }
 381     }
 382 
 383     /** Return the declaring class of this member.
 384      *  In the case of a bare name and type, the declaring class will be null.
 385      */
 386     @Override
 387     public Class<?> getDeclaringClass() {
 388         return clazz;
 389     }
 390 
 391     /** Utility method producing the class loader of the declaring class. */
 392     public ClassLoader getClassLoader() {
 393         return clazz.getClassLoader();
 394     }
 395 
 396     /** Return the simple name of this member.
 397      *  For a type, it is the same as {@link Class#getSimpleName}.
 398      *  For a method or field, it is the simple name of the member.
 399      *  For a constructor, it is always {@code "&lt;init&gt;"}.
 400      */
 401     @Override
 402     public String getName() {
 403         if (name == null) {
 404             expandFromVM();
 405             if (name == null) {
 406                 return null;
 407             }
 408         }
 409         return name;
 410     }
 411 
 412     public MethodType getMethodOrFieldType() {
 413         if (isInvocable())
 414             return getMethodType();
 415         if (isGetter())
 416             return MethodType.methodType(getFieldType());
 417         if (isSetter())
 418             return MethodType.methodType(void.class, getFieldType());
 419         throw new InternalError("not a method or field: "+this);
 420     }
 421 
 422     /** Return the declared type of this member, which
 423      *  must be a method or constructor.
 424      */
 425     public MethodType getMethodType() {
 426         if (type == null) {
 427             expandFromVM();
 428             if (type == null) {
 429                 return null;
 430             }
 431         }
 432         if (!isInvocable()) {
 433             throw newIllegalArgumentException("not invocable, no method type");
 434         }
 435 
 436         {
 437             // Get a snapshot of type which doesn't get changed by racing threads.
 438             final Object type = this.type;
 439             if (type instanceof MethodType) {
 440                 return (MethodType) type;
 441             }
 442         }
 443 
 444         // type is not a MethodType yet.  Convert it thread-safely.
 445         synchronized (this) {
 446             if (type instanceof String) {
 447                 String sig = (String) type;
 448                 MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
 449                 type = res;
 450             } else if (type instanceof Object[]) {
 451                 Object[] typeInfo = (Object[]) type;
 452                 Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
 453                 Class<?> rtype = (Class<?>) typeInfo[0];
 454                 MethodType res = MethodType.methodType(rtype, ptypes);
 455                 type = res;
 456             }
 457             // Make sure type is a MethodType for racing threads.
 458             assert type instanceof MethodType : "bad method type " + type;
 459         }
 460         return (MethodType) type;
 461     }
 462 
 463     /** Return the actual type under which this method or constructor must be invoked.
 464      *  For non-static methods or constructors, this is the type with a leading parameter,
 465      *  a reference to declaring class.  For static methods, it is the same as the declared type.
 466      */
 467     public MethodType getInvocationType() {
 468         MethodType itype = getMethodOrFieldType();
 469         if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
 470             return itype.changeReturnType(clazz);
 471         if (!isStatic())
 472             return itype.insertParameterTypes(0, clazz);
 473         return itype;
 474     }
 475 
 476     /** Utility method producing the parameter types of the method type. */
 477     public Class<?>[] getParameterTypes() {
 478         return getMethodType().parameterArray();
 479     }
 480 
 481     /** Utility method producing the return type of the method type. */
 482     public Class<?> getReturnType() {
 483         return getMethodType().returnType();
 484     }
 485 
 486     /** Return the declared type of this member, which
 487      *  must be a field or type.
 488      *  If it is a type member, that type itself is returned.
 489      */
 490     public Class<?> getFieldType() {
 491         if (type == null) {
 492             expandFromVM();
 493             if (type == null) {
 494                 return null;
 495             }
 496         }
 497         if (isInvocable()) {
 498             throw newIllegalArgumentException("not a field or nested class, no simple type");
 499         }
 500 
 501         {
 502             // Get a snapshot of type which doesn't get changed by racing threads.
 503             final Object type = this.type;
 504             if (type instanceof Class<?>) {
 505                 return (Class<?>) type;
 506             }
 507         }
 508 
 509         // type is not a Class yet.  Convert it thread-safely.
 510         synchronized (this) {
 511             if (type instanceof String) {
 512                 String sig = (String) type;
 513                 MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
 514                 Class<?> res = mtype.returnType();
 515                 type = res;
 516             }
 517             // Make sure type is a Class for racing threads.
 518             assert type instanceof Class<?> : "bad field type " + type;
 519         }
 520         return (Class<?>) type;
 521     }
 522 
 523     /** Utility method to produce either the method type or field type of this member. */
 524     public Object getType() {
 525         return (isInvocable() ? getMethodType() : getFieldType());
 526     }
 527 
 528     /** Utility method to produce the signature of this member,
 529      *  used within the class file format to describe its type.
 530      */
 531     public String getSignature() {
 532         if (type == null) {
 533             expandFromVM();
 534             if (type == null) {
 535                 return null;
 536             }
 537         }
 538         if (isInvocable())
 539             return BytecodeDescriptor.unparse(getMethodType());
 540         else
 541             return BytecodeDescriptor.unparse(getFieldType());
 542     }
 543 
 544     /** Return the modifier flags of this member.
 545      *  @see java.lang.reflect.Modifier
 546      */
 547     @Override
 548     public int getModifiers() {
 549         return (flags & RECOGNIZED_MODIFIERS);
 550     }
 551 
 552     /** Return the reference kind of this member, or zero if none.
 553      */
 554     public byte getReferenceKind() {
 555         return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
 556     }
 557     private boolean referenceKindIsConsistent() {
 558         byte refKind = getReferenceKind();
 559         if (refKind == REF_NONE)  return isType();
 560         if (isField()) {
 561             assert(staticIsConsistent());
 562             assert(MethodHandleNatives.refKindIsField(refKind));
 563         } else if (isConstructor()) {
 564             assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
 565         } else if (isMethod()) {
 566             assert(staticIsConsistent());
 567             assert(MethodHandleNatives.refKindIsMethod(refKind));
 568             if (clazz.isInterface())
 569                 assert(refKind == REF_invokeInterface ||
 570                        refKind == REF_invokeStatic    ||
 571                        refKind == REF_invokeSpecial   ||
 572                        refKind == REF_invokeVirtual && isObjectPublicMethod());
 573         } else {
 574             assert(false);
 575         }
 576         return true;
 577     }
 578     private boolean isObjectPublicMethod() {
 579         if (clazz == Object.class)  return true;
 580         MethodType mtype = getMethodType();
 581         if (name.equals("toString") && mtype.returnType() == String.class && mtype.parameterCount() == 0)
 582             return true;
 583         if (name.equals("hashCode") && mtype.returnType() == int.class && mtype.parameterCount() == 0)
 584             return true;
 585         if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class)
 586             return true;
 587         return false;
 588     }
 589     /*non-public*/ boolean referenceKindIsConsistentWith(int originalRefKind) {
 590         int refKind = getReferenceKind();
 591         if (refKind == originalRefKind)  return true;
 592         switch (originalRefKind) {
 593         case REF_invokeInterface:
 594             // Looking up an interface method, can get (e.g.) Object.hashCode
 595             assert(refKind == REF_invokeVirtual ||
 596                    refKind == REF_invokeSpecial) : this;
 597             return true;
 598         case REF_invokeVirtual:
 599         case REF_newInvokeSpecial:
 600             // Looked up a virtual, can get (e.g.) final String.hashCode.
 601             assert(refKind == REF_invokeSpecial) : this;
 602             return true;
 603         }
 604         assert(false) : this+" != "+MethodHandleNatives.refKindName((byte)originalRefKind);
 605         return true;
 606     }
 607     private boolean staticIsConsistent() {
 608         byte refKind = getReferenceKind();
 609         return MethodHandleNatives.refKindIsStatic(refKind) == isStatic() || getModifiers() == 0;
 610     }
 611     private boolean vminfoIsConsistent() {
 612         byte refKind = getReferenceKind();
 613         assert(isResolved());  // else don't call
 614         Object vminfo = MethodHandleNatives.getMemberVMInfo(this);
 615         assert(vminfo instanceof Object[]);
 616         long vmindex = (Long) ((Object[])vminfo)[0];
 617         Object vmtarget = ((Object[])vminfo)[1];
 618         if (MethodHandleNatives.refKindIsField(refKind)) {
 619             assert(vmindex >= 0) : vmindex + ":" + this;
 620             assert(vmtarget instanceof Class);
 621         } else {
 622             if (MethodHandleNatives.refKindDoesDispatch(refKind))
 623                 assert(vmindex >= 0) : vmindex + ":" + this;
 624             else
 625                 assert(vmindex < 0) : vmindex;
 626             assert(vmtarget instanceof MemberName) : vmtarget + " in " + this;
 627         }
 628         return true;
 629     }
 630 
 631     private MemberName changeReferenceKind(byte refKind, byte oldKind) {
 632         assert(getReferenceKind() == oldKind);
 633         assert(MethodHandleNatives.refKindIsValid(refKind));
 634         flags += (((int)refKind - oldKind) << MN_REFERENCE_KIND_SHIFT);
 635         return this;
 636     }
 637 
 638     private boolean testFlags(int mask, int value) {
 639         return (flags & mask) == value;
 640     }
 641     private boolean testAllFlags(int mask) {
 642         return testFlags(mask, mask);
 643     }
 644     private boolean testAnyFlags(int mask) {
 645         return !testFlags(mask, 0);
 646     }
 647 
 648     /** Utility method to query if this member is a method handle invocation (invoke or invokeExact).
 649      *  Also returns true for the non-public MH.invokeBasic.
 650      */
 651     public boolean isMethodHandleInvoke() {
 652         final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
 653         final int negs = Modifier.STATIC;
 654         if (testFlags(bits | negs, bits) &&
 655             clazz == MethodHandle.class) {
 656             return isMethodHandleInvokeName(name);
 657         }
 658         return false;
 659     }
 660     public static boolean isMethodHandleInvokeName(String name) {
 661         switch (name) {
 662         case "invoke":
 663         case "invokeExact":
 664         case "invokeBasic":  // internal sig-poly method
 665             return true;
 666         default:
 667             return false;
 668         }
 669     }
 670     private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
 671 
 672     /** Utility method to query the modifier flags of this member. */
 673     public boolean isStatic() {
 674         return Modifier.isStatic(flags);
 675     }
 676     /** Utility method to query the modifier flags of this member. */
 677     public boolean isPublic() {
 678         return Modifier.isPublic(flags);
 679     }
 680     /** Utility method to query the modifier flags of this member. */
 681     public boolean isPrivate() {
 682         return Modifier.isPrivate(flags);
 683     }
 684     /** Utility method to query the modifier flags of this member. */
 685     public boolean isProtected() {
 686         return Modifier.isProtected(flags);
 687     }
 688     /** Utility method to query the modifier flags of this member. */
 689     public boolean isFinal() {
 690         return Modifier.isFinal(flags);
 691     }
 692     /** Utility method to query whether this member or its defining class is final. */
 693     public boolean canBeStaticallyBound() {
 694         return Modifier.isFinal(flags | clazz.getModifiers());
 695     }
 696     /** Utility method to query the modifier flags of this member. */
 697     public boolean isVolatile() {
 698         return Modifier.isVolatile(flags);
 699     }
 700     /** Utility method to query the modifier flags of this member. */
 701     public boolean isAbstract() {
 702         return Modifier.isAbstract(flags);
 703     }
 704     /** Utility method to query the modifier flags of this member. */
 705     public boolean isNative() {
 706         return Modifier.isNative(flags);
 707     }
 708     // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
 709 
 710     // unofficial modifier flags, used by HotSpot:
 711     static final int BRIDGE    = 0x00000040;
 712     static final int VARARGS   = 0x00000080;
 713     static final int SYNTHETIC = 0x00001000;
 714     static final int ANNOTATION= 0x00002000;
 715     static final int ENUM      = 0x00004000;
 716     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 717     public boolean isBridge() {
 718         return testAllFlags(IS_METHOD | BRIDGE);
 719     }
 720     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 721     public boolean isVarargs() {
 722         return testAllFlags(VARARGS) && isInvocable();
 723     }
 724     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 725     @Override
 726     public boolean isSynthetic() {
 727         return testAllFlags(SYNTHETIC);
 728     }
 729 
 730     static final String CONSTRUCTOR_NAME = "<init>";  // the ever-popular
 731 
 732     // modifiers exported by the JVM:
 733     static final int RECOGNIZED_MODIFIERS = 0xFFFF;
 734 
 735     // private flags, not part of RECOGNIZED_MODIFIERS:
 736     static final int
 737             IS_METHOD        = MN_IS_METHOD,        // method (not constructor)
 738             IS_CONSTRUCTOR   = MN_IS_CONSTRUCTOR,   // constructor
 739             IS_FIELD         = MN_IS_FIELD,         // field
 740             IS_TYPE          = MN_IS_TYPE,          // nested type
 741             CALLER_SENSITIVE = MN_CALLER_SENSITIVE; // @CallerSensitive annotation detected
 742 
 743     static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
 744     static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
 745     static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
 746     static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
 747     static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
 748 
 749     /** Utility method to query whether this member is a method or constructor. */
 750     public boolean isInvocable() {
 751         return testAnyFlags(IS_INVOCABLE);
 752     }
 753     /** Utility method to query whether this member is a method, constructor, or field. */
 754     public boolean isFieldOrMethod() {
 755         return testAnyFlags(IS_FIELD_OR_METHOD);
 756     }
 757     /** Query whether this member is a method. */
 758     public boolean isMethod() {
 759         return testAllFlags(IS_METHOD);
 760     }
 761     /** Query whether this member is a constructor. */
 762     public boolean isConstructor() {
 763         return testAllFlags(IS_CONSTRUCTOR);
 764     }
 765     /** Query whether this member is a field. */
 766     public boolean isField() {
 767         return testAllFlags(IS_FIELD);
 768     }
 769     /** Query whether this member is a type. */
 770     public boolean isType() {
 771         return testAllFlags(IS_TYPE);
 772     }
 773     /** Utility method to query whether this member is neither public, private, nor protected. */
 774     public boolean isPackage() {
 775         return !testAnyFlags(ALL_ACCESS);
 776     }
 777     /** Query whether this member has a CallerSensitive annotation. */
 778     public boolean isCallerSensitive() {
 779         return testAllFlags(CALLER_SENSITIVE);
 780     }
 781 
 782     /** Utility method to query whether this member is accessible from a given lookup class. */
 783     public boolean isAccessibleFrom(Class<?> lookupClass) {
 784         return VerifyAccess.isMemberAccessible(this.getDeclaringClass(), this.getDeclaringClass(), flags,
 785                                                lookupClass, ALL_ACCESS|MethodHandles.Lookup.PACKAGE);
 786     }
 787 
 788     /**
 789      * Calls down to the VM to fill in the fields.  This method is
 790      * synchronized to avoid racing calls.
 791      */
 792     private void expandFromVM() {
 793         if (type != null) {
 794             return;
 795         }
 796         if (!isResolved()) {
 797             return;
 798         }
 799         MethodHandleNatives.expand(this);
 800     }
 801 
 802     // Capturing information from the Core Reflection API:
 803     private static int flagsMods(int flags, int mods, byte refKind) {
 804         assert((flags & RECOGNIZED_MODIFIERS) == 0);
 805         assert((mods & ~RECOGNIZED_MODIFIERS) == 0);
 806         assert((refKind & ~MN_REFERENCE_KIND_MASK) == 0);
 807         return flags | mods | (refKind << MN_REFERENCE_KIND_SHIFT);
 808     }
 809 
 810     public MemberName asSpecial() {
 811         switch (getReferenceKind()) {
 812         case REF_invokeSpecial:     return this;
 813         case REF_invokeVirtual:     return cloneAndChangeReferenceKindAndIntern(REF_invokeSpecial, REF_invokeVirtual);
 814         case REF_invokeInterface:   return cloneAndChangeReferenceKindAndIntern(REF_invokeSpecial, REF_invokeInterface);
 815         case REF_newInvokeSpecial:  return cloneAndChangeReferenceKindAndIntern(REF_invokeSpecial, REF_newInvokeSpecial);
 816         }
 817         throw new IllegalArgumentException(this.toString());
 818     }
 819     /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
 820      *  In that case it must already be REF_invokeSpecial.
 821      */
 822     public MemberName asConstructor() {
 823         switch (getReferenceKind()) {
 824         case REF_invokeSpecial:     return cloneAndChangeReferenceKindAndIntern(REF_newInvokeSpecial, REF_invokeSpecial);
 825         case REF_newInvokeSpecial:  return this;
 826         }
 827         throw new IllegalArgumentException(this.toString());
 828     }
 829     /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind
 830      *  REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface.
 831      *  The end result is to get a fully virtualized version of the MN.
 832      *  (Note that resolving in the JVM will sometimes devirtualize, changing
 833      *  REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface
 834      *  in some corner cases to either of the previous two; this transform
 835      *  undoes that change under the assumption that it occurred.)
 836      */
 837     public MemberName asNormalOriginal() {
 838         byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
 839         byte refKind = getReferenceKind();
 840         byte newRefKind = refKind;
 841         MemberName result = this;
 842         switch (refKind) {
 843         case REF_invokeInterface:
 844         case REF_invokeVirtual:
 845         case REF_invokeSpecial:
 846             newRefKind = normalVirtual;
 847             break;
 848         }
 849         if (newRefKind == refKind)
 850             return this;
 851         result = cloneAndChangeReferenceKindAndIntern(newRefKind, refKind);
 852         assert(this.referenceKindIsConsistentWith(result.getReferenceKind()));
 853         return result;
 854     }
 855 
 856     /**
 857      * Clones, changes reference kind in the clone, and if this is resolved,
 858      * also interns the result, repeating the intern operation till it succeeds.
 859      *
 860      * @param refKind
 861      * @param oldKind
 862      * @return
 863      */
 864     private MemberName cloneAndChangeReferenceKindAndIntern(byte refKind, byte oldKind) {
 865         MemberName tmp0 = null;
 866         while (tmp0 == null) {
 867             int tx_token = internTxnToken(); // this and clone will have same token
 868             tmp0 = clone().changeReferenceKind(refKind, oldKind).intern(this, tx_token);
 869         }
 870         return tmp0;
 871     }
 872 
 873     public boolean isGetter() {
 874         return MethodHandleNatives.refKindIsGetter(getReferenceKind());
 875     }
 876     public boolean isSetter() {
 877         return MethodHandleNatives.refKindIsSetter(getReferenceKind());
 878     }
 879     public MemberName asSetter() {
 880         byte refKind = getReferenceKind();
 881         assert(MethodHandleNatives.refKindIsGetter(refKind));
 882         assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 883         byte setterRefKind = (byte)(refKind + (REF_putField - REF_getField));
 884         return cloneAndChangeReferenceKindAndIntern(setterRefKind, refKind);
 885     }
 886     /**
 887      * Create a name for a signature-polymorphic invoker.
 888      * This is a placeholder for a signature-polymorphic instance
 889      * (of MH.invokeExact, etc.) that the JVM does not reify.
 890      * The returned MemberName is not resolved.
 891      * See comments on {@link MethodHandleNatives#linkMethod}.
 892      */
 893     static MemberName makeMethodHandleInvoke(String name, MethodType type) {
 894         return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC);
 895     }
 896     static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) {
 897         MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual);
 898         mem.flags |= mods;  // it's not resolved, but add these modifiers anyway
 899         assert(mem.isMethodHandleInvoke()) : mem;
 900         return mem;
 901     }
 902 
 903     // locally useful cloner
 904     @Override protected MemberName clone() {
 905         try {
 906             return (MemberName) super.clone();
 907         } catch (CloneNotSupportedException ex) {
 908             throw newInternalError(ex);
 909         }
 910      }
 911 
 912     /** Get the definition of this member name.
 913      *  This may be in a super-class of the declaring class of this member.
 914      */
 915     public MemberName getDefinition() {
 916         if (!isResolved())  throw new IllegalStateException("must be resolved: "+this);
 917         if (isType())  return this;
 918         MemberName res = this.clone();
 919         res.clazz = null;
 920         res.type = null;
 921         res.name = null;
 922         res.resolution = res;
 923         res.expandFromVM();
 924         assert(res.getName().equals(this.getName()));
 925         return res;
 926     }
 927 
 928     @Override
 929     public int hashCode() {
 930         return Objects.hash(clazz, getReferenceKind(), name, getType());
 931     }
 932     @Override
 933     public boolean equals(Object that) {
 934         return (that instanceof MemberName && this.equals((MemberName)that));
 935     }
 936 
 937     /** Decide if two member names have exactly the same symbolic content.
 938      *  Does not take into account any actual class members, so even if
 939      *  two member names resolve to the same actual member, they may
 940      *  be distinct references.
 941      */
 942     public boolean equals(MemberName that) {
 943         if (this == that)  return true;
 944         if (that == null)  return false;
 945         return this.clazz == that.clazz
 946                 && this.getReferenceKind() == that.getReferenceKind()
 947                 && Objects.equals(this.name, that.name)
 948                 && Objects.equals(this.getType(), that.getType());
 949     }
 950 
 951     /** Query whether this member name is resolved to a non-static, non-final method.
 952      */
 953     public boolean hasReceiverTypeDispatch() {
 954         return MethodHandleNatives.refKindDoesDispatch(getReferenceKind());
 955     }
 956 
 957     /** Query whether this member name is resolved.
 958      *  A resolved member name is one for which the JVM has found
 959      *  a method, constructor, field, or type binding corresponding exactly to the name.
 960      *  (Document?)
 961      */
 962     public boolean isResolved() {
 963         return resolution == null;
 964     }
 965 
 966     void checkForTypeAlias() {
 967         if (isInvocable()) {
 968             MethodType type;
 969             if (this.type instanceof MethodType)
 970                 type = (MethodType) this.type;
 971             else
 972                 this.type = type = getMethodType();
 973             if (type.erase() == type)  return;
 974             if (VerifyAccess.isTypeVisible(type, clazz))  return;
 975             throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
 976         } else {
 977             Class<?> type;
 978             if (this.type instanceof Class<?>)
 979                 type = (Class<?>) this.type;
 980             else
 981                 this.type = type = getFieldType();
 982             if (VerifyAccess.isTypeVisible(type, clazz))  return;
 983             throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
 984         }
 985     }
 986 
 987 
 988     /** Produce a string form of this member name.
 989      *  For types, it is simply the type's own string (as reported by {@code toString}).
 990      *  For fields, it is {@code "DeclaringClass.name/type"}.
 991      *  For methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}.
 992      *  If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
 993      *  If the member is unresolved, a prefix {@code "*."} is prepended.
 994      */
 995     @SuppressWarnings("LocalVariableHidesMemberVariable")
 996     @Override
 997     public String toString() {
 998         if (isType())
 999             return type.toString();  // class java.lang.String
1000         // else it is a field, method, or constructor
1001         StringBuilder buf = new StringBuilder();
1002         if (getDeclaringClass() != null) {
1003             buf.append(getName(clazz));
1004             buf.append('.');
1005         }
1006         String name = getName();
1007         buf.append(name == null ? "*" : name);
1008         Object type = getType();
1009         if (!isInvocable()) {
1010             buf.append('/');
1011             buf.append(type == null ? "*" : getName(type));
1012         } else {
1013             buf.append(type == null ? "(*)*" : getName(type));
1014         }
1015         byte refKind = getReferenceKind();
1016         if (refKind != REF_NONE) {
1017             buf.append('/');
1018             buf.append(MethodHandleNatives.refKindName(refKind));
1019         }
1020         //buf.append("#").append(System.identityHashCode(this));
1021         return buf.toString();
1022     }
1023     private static String getName(Object obj) {
1024         if (obj instanceof Class<?>)
1025             return ((Class<?>)obj).getName();
1026         return String.valueOf(obj);
1027     }
1028 
1029     public IllegalAccessException makeAccessException(String message, Object from) {
1030         message = message + ": "+ toString();
1031         if (from != null)  message += ", from " + from;
1032         return new IllegalAccessException(message);
1033     }
1034     private String message() {
1035         if (isResolved())
1036             return "no access";
1037         else if (isConstructor())
1038             return "no such constructor";
1039         else if (isMethod())
1040             return "no such method";
1041         else
1042             return "no such field";
1043     }
1044     public ReflectiveOperationException makeAccessException() {
1045         String message = message() + ": "+ toString();
1046         ReflectiveOperationException ex;
1047         if (isResolved() || !(resolution instanceof NoSuchMethodError ||
1048                               resolution instanceof NoSuchFieldError))
1049             ex = new IllegalAccessException(message);
1050         else if (isConstructor())
1051             ex = new NoSuchMethodException(message);
1052         else if (isMethod())
1053             ex = new NoSuchMethodException(message);
1054         else
1055             ex = new NoSuchFieldException(message);
1056         if (resolution instanceof Throwable)
1057             ex.initCause((Throwable) resolution);
1058         return ex;
1059     }
1060 
1061     /** Actually making a query requires an access check. */
1062     /*non-public*/ static Factory getFactory() {
1063         return Factory.INSTANCE;
1064     }
1065     /** A factory type for resolving member names with the help of the VM.
1066      *  TBD: Define access-safe public constructors for this factory.
1067      */
1068     /*non-public*/ static class Factory {
1069         private Factory() { } // singleton pattern
1070         static Factory INSTANCE = new Factory();
1071 
1072         private final static int ALLOWED_FLAGS = ALL_KINDS;
1073 
1074         /// Queries
1075         List<MemberName> getMembers(Class<?> defc,
1076                 String matchName, Object matchType,
1077                 int matchFlags, Class<?> lookupClass) {
1078             matchFlags &= ALLOWED_FLAGS;
1079             String matchSig = null;
1080             if (matchType != null) {
1081                 matchSig = BytecodeDescriptor.unparse(matchType);
1082                 if (matchSig.startsWith("("))
1083                     matchFlags &= ~(ALL_KINDS & ~IS_INVOCABLE);
1084                 else
1085                     matchFlags &= ~(ALL_KINDS & ~IS_FIELD);
1086             }
1087             final int BUF_MAX = 0x2000;
1088             int len1 = matchName == null ? 10 : matchType == null ? 4 : 1;
1089             MemberName[] buf = newMemberBuffer(len1);
1090             int totalCount = 0;
1091             ArrayList<MemberName[]> bufs = null;
1092             int bufCount = 0;
1093             for (;;) {
1094                 bufCount = MethodHandleNatives.getMembers(defc,
1095                         matchName, matchSig, matchFlags,
1096                         lookupClass,
1097                         totalCount, buf);
1098                 if (bufCount <= buf.length) {
1099                     if (bufCount < 0)  bufCount = 0;
1100                     totalCount += bufCount;
1101                     break;
1102                 }
1103                 // JVM returned to us with an intentional overflow!
1104                 totalCount += buf.length;
1105                 int excess = bufCount - buf.length;
1106                 if (bufs == null)  bufs = new ArrayList<>(1);
1107                 bufs.add(buf);
1108                 int len2 = buf.length;
1109                 len2 = Math.max(len2, excess);
1110                 len2 = Math.max(len2, totalCount / 4);
1111                 buf = newMemberBuffer(Math.min(BUF_MAX, len2));
1112             }
1113             ArrayList<MemberName> result = new ArrayList<>(totalCount);
1114             if (bufs != null) {
1115                 for (MemberName[] buf0 : bufs) {
1116                     Collections.addAll(result, buf0);
1117                 }
1118             }
1119             result.addAll(Arrays.asList(buf).subList(0, bufCount));
1120             // Signature matching is not the same as type matching, since
1121             // one signature might correspond to several types.
1122             // So if matchType is a Class or MethodType, refilter the results.
1123             if (matchType != null && matchType != matchSig) {
1124                 for (Iterator<MemberName> it = result.iterator(); it.hasNext();) {
1125                     MemberName m = it.next();
1126                     if (!matchType.equals(m.getType()))
1127                         it.remove();
1128                 }
1129             }
1130             return result;
1131         }
1132         /** Produce a resolved version of the given member.
1133          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1134          *  Access checking is performed on behalf of the given {@code lookupClass}.
1135          *  If lookup fails or access is not permitted, null is returned.
1136          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
1137          */
1138         private static MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass) {
1139             MemberName m = ref.clone();  // JVM will side-effect the ref
1140             assert(refKind == m.getReferenceKind());
1141             try {
1142                 m = MethodHandleNatives.resolve(m, lookupClass);
1143                 m.checkForTypeAlias();
1144                 m.resolution = null;
1145             } catch (LinkageError ex) {
1146                 // JVM reports that the "bytecode behavior" would get an error
1147                 assert(!m.isResolved());
1148                 m.resolution = ex;
1149                 return m;
1150             }
1151             assert(m.referenceKindIsConsistent());
1152             m.initResolved(true);
1153             assert(m.vminfoIsConsistent());
1154             // m = m.intern(); // do not intern -- caller should intern instead.
1155             return m;
1156         }
1157         /** Produce a resolved version of the given member.
1158          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1159          *  Access checking is performed on behalf of the given {@code lookupClass}.
1160          *  If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
1161          *  Otherwise the given member or its interned copy is returned, with modifier bits filled in.
1162          */
1163         public
1164         <NoSuchMemberException extends ReflectiveOperationException>
1165                 MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
1166                         Class<NoSuchMemberException> nsmClass)
1167                 throws IllegalAccessException, NoSuchMemberException {
1168             MemberName result = resolveOrNot(refKind, m, lookupClass);
1169 
1170             if (result.isResolved()) {
1171                 return result;
1172             } else { // not resolved, throw exception
1173                 ReflectiveOperationException ex = result.makeAccessException();
1174                 if (ex instanceof IllegalAccessException) {
1175                     throw (IllegalAccessException) ex;
1176                 }
1177                 throw nsmClass.cast(ex);
1178             }
1179         }
1180         /** Produce a resolved version of the given member.
1181          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1182          *  Access checking is performed on behalf of the given {@code lookupClass}.
1183          *  If lookup fails or access is not permitted, return null.
1184          *  Otherwise the given member or its interned copy is returned, with modifier bits filled in.
1185          */
1186         public
1187         MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) {
1188             MemberName result = resolveOrNot(refKind, m, lookupClass);
1189             return result.isResolved() ? result : null;
1190         }
1191 
1192         private static
1193         MemberName resolveOrNot(byte refKind, MemberName m, Class<?> lookupClass) {
1194             MemberName result = null;
1195             Class tx_class = m.clazz; // Guess a class for race detection.
1196             while (result == null) { // iterate till no race.
1197                 int txn_token = internTxnToken(tx_class);
1198 
1199                 MemberName result0 = resolve(refKind, m, lookupClass);
1200 
1201                 if (result0.isResolved()) {
1202                     if (result0.clazz != tx_class) { // Confirm/correct guess
1203                         Class prev_tx_class = tx_class;
1204                         int prev_txn_token = txn_token;
1205                         tx_class = result0.clazz;
1206                         txn_token = internTxnToken(tx_class);
1207                         // The guess may be good enough
1208                         if (txn_token != 0 ||
1209                             prev_txn_token != internTxnToken(prev_tx_class)) {
1210                             // Resolved class is different and at least one
1211                             // redef occurred, therefore repeat with
1212                             // proper class for race consistency checking.
1213                             continue;
1214                         }
1215                     }
1216                     result = result0.intern(txn_token);
1217                 } else { // Resolution failed, do not intern, return unresolved MemberName
1218                     return result0;
1219                 }
1220             }
1221             return result;
1222         }
1223 
1224         /** Return a list of all methods defined by the given class.
1225          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1226          *  Access checking is performed on behalf of the given {@code lookupClass}.
1227          *  Inaccessible members are not added to the last.
1228          */
1229         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1230                 Class<?> lookupClass) {
1231             return getMethods(defc, searchSupers, null, null, lookupClass);
1232         }
1233         /** Return a list of matching methods defined by the given class.
1234          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1235          *  Returned methods will match the name (if not null) and the type (if not null).
1236          *  Access checking is performed on behalf of the given {@code lookupClass}.
1237          *  Inaccessible members are not added to the last.
1238          */
1239         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1240                 String name, MethodType type, Class<?> lookupClass) {
1241             int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1242             return getMembers(defc, name, type, matchFlags, lookupClass);
1243         }
1244         /** Return a list of all constructors defined by the given class.
1245          *  Access checking is performed on behalf of the given {@code lookupClass}.
1246          *  Inaccessible members are not added to the last.
1247          */
1248         public List<MemberName> getConstructors(Class<?> defc, Class<?> lookupClass) {
1249             return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
1250         }
1251         /** Return a list of all fields defined by the given class.
1252          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1253          *  Access checking is performed on behalf of the given {@code lookupClass}.
1254          *  Inaccessible members are not added to the last.
1255          */
1256         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1257                 Class<?> lookupClass) {
1258             return getFields(defc, searchSupers, null, null, lookupClass);
1259         }
1260         /** Return a list of all fields defined by the given class.
1261          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1262          *  Returned fields will match the name (if not null) and the type (if not null).
1263          *  Access checking is performed on behalf of the given {@code lookupClass}.
1264          *  Inaccessible members are not added to the last.
1265          */
1266         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1267                 String name, Class<?> type, Class<?> lookupClass) {
1268             int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1269             return getMembers(defc, name, type, matchFlags, lookupClass);
1270         }
1271         /** Return a list of all nested types defined by the given class.
1272          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1273          *  Access checking is performed on behalf of the given {@code lookupClass}.
1274          *  Inaccessible members are not added to the last.
1275          */
1276         public List<MemberName> getNestedTypes(Class<?> defc, boolean searchSupers,
1277                 Class<?> lookupClass) {
1278             int matchFlags = IS_TYPE | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1279             return getMembers(defc, null, null, matchFlags, lookupClass);
1280         }
1281         private static MemberName[] newMemberBuffer(int length) {
1282             MemberName[] buf = new MemberName[length];
1283             // fill the buffer with dummy structs for the JVM to fill in
1284             for (int i = 0; i < length; i++)
1285                 buf[i] = new MemberName();
1286             return buf;
1287         }
1288     }
1289 
1290 
1291     /**
1292      * Lazily create {@link ClassData}.
1293      */
1294     private static ClassData classData(Class<?> klazz) {
1295         ClassData classData = (ClassData) jla.getClassData(klazz);
1296         if (classData == null) {
1297             classData = new ClassData();
1298             if (!jla.casClassData(klazz, null, classData)) {
1299                 classData = (ClassData) jla.getClassData(klazz);
1300             }
1301         }
1302         return classData;
1303     }
1304 
1305     /* package */ static MemberName internMemberName(Class<?> klazz, MemberName memberName, int redefinedCount) {
1306         return classData(klazz).intern(klazz, memberName, redefinedCount);
1307     }
1308 
1309     /**
1310      * ClassData
1311      */
1312     private static class ClassData {
1313         /**
1314          * This needs to be a simple data structure because we need to access
1315          * and update its elements from the JVM. This is a 'tail' pointer
1316          * to last element published to JVM. The chain of elements is
1317          * traversed using {@link MemberName#next} links until {@code null}
1318          * is reached.
1319          */
1320         private volatile MemberName publishedToVM;
1321 
1322         /**
1323          * A linear-scan hash table used for interning.
1324          * The length of the array is always a power of 2,
1325          * greater than (1.5 * size) and less or equal to (3 * size)
1326          */
1327         private volatile MemberName[] table;
1328         private int size;
1329 
1330         /**
1331          * The minimum capacity.
1332          * The value 2 corresponds to an expected maximum size of 1,
1333          * given a load factor of 2/3. MUST be a power of two.
1334          */
1335         private static final int MINIMUM_CAPACITY = 2;
1336 
1337         /**
1338          * The maximum capacity.
1339          * <p/>
1340          * In fact, the table can hold no more than MAXIMUM_CAPACITY-1 elements
1341          * because it has to have at least one slot == null
1342          * in order to avoid infinite loops in get() and putIfAbsent().
1343          */
1344         private static final int MAXIMUM_CAPACITY = 1 << 30;
1345 
1346         /**
1347          * Interns a member name in the member name table.
1348          * Returns null if a race with the jvm occurred.  Races are detected
1349          * by checking for changes in the class redefinition count that occur
1350          * before an intern is complete.
1351          *
1352          * @param klass          class whose redefinition count is checked.
1353          * @param memberName     member name to be interned
1354          * @param redefinedCount the value of classRedefinedCount() observed before
1355          *                       creation of the MemberName that is being interned.
1356          * @return null if a race occurred, otherwise the interned MemberName.
1357          */
1358         @SuppressWarnings({"unchecked", "rawtypes"})
1359         public MemberName intern(Class<?> klass, MemberName memberName, int redefinedCount) {
1360 
1361             // check without holding lock
1362             MemberName internedMemberName = get(memberName);
1363             if (internedMemberName != null) {
1364                 return internedMemberName;
1365             }
1366 
1367             // must hold lock now
1368             synchronized (this) {
1369                 // This has to be a never published MemberName.
1370                 assert memberName.next == null;
1371 
1372                 // First attempt publication to JVM, if that succeeds,
1373                 // then try to record in hash table.
1374                 memberName.next = publishedToVM;
1375                 publishedToVM = memberName;
1376                 if (redefinedCount != jla.getClassRedefinedCount(klass)) {
1377                     // Lost a race with JVM, back out publication and report failure.
1378                     publishedToVM = memberName.next;
1379                     // We can't set memberName.next to null here (without a write fence),
1380                     // because the write could bubble above the write to publishedToVM!
1381                     return null;
1382                 }
1383 
1384                 // Try to record in hash table.
1385                 internedMemberName = putIfAbsent(memberName);
1386                 if (internedMemberName != null) {
1387                     // Lost race with interning, back out JVM publication
1388                     // and return already interned element.
1389                     publishedToVM = memberName.next;
1390                     // We can't set memberName.next to null here (without a write fence),
1391                     // because the write could bubble above the write to publishedToVM!
1392                     return internedMemberName;
1393                 }
1394 
1395                 // Successfully recorded memberName, return it.
1396                 return memberName;
1397             }
1398         }
1399 
1400         /**
1401          * Lookup for an interned element. This method can be called without
1402          * any external synchronization.
1403          *
1404          * @param lookupElement the lookup object.
1405          * @return interned element if there is one or null if there is none.
1406          */
1407         private MemberName get(MemberName lookupElement) {
1408             final MemberName[] tab = table; // volatile read
1409             if (tab == null) {
1410                 return null;
1411             }
1412             int i = hash(lookupElement, tab.length);
1413             while (true) {
1414                 MemberName element = getVolatile(tab, i);
1415                 if (element == null) {
1416                     return null;
1417                 }
1418                 if (element.equals(lookupElement)) {
1419                     return element;
1420                 }
1421                 i = nextKeyIndex(i, tab.length);
1422             }
1423         }
1424 
1425         /**
1426          * Inserts new element if there is no interned element equal to it
1427          * already present. This method must be called under exclusive lock.
1428          *
1429          * @param newElement new element to insert.
1430          * @return null if new element was inserted or old element if
1431          *         there was one (and no new element was inserted)
1432          */
1433         private MemberName putIfAbsent(MemberName newElement) {
1434             if (newElement == null) throw new NullPointerException();
1435 
1436             MemberName[] tab = table; // volatile read
1437 
1438             if (tab == null) {
1439                 // lazily create initial table
1440                 tab = new MemberName[MINIMUM_CAPACITY];
1441                 // still virgin
1442                 tab[hash(newElement, tab.length)] = newElement;
1443                 // publish initial table
1444                 table = tab;
1445                 size = 1;
1446                 return null;
1447             }
1448 
1449             while (true) {
1450 
1451                 int i = hash(newElement, tab.length);
1452 
1453                 for (MemberName element;
1454                      (element = tab[i]) != null;
1455                      i = nextKeyIndex(i, tab.length)) {
1456                     if (element.equals(newElement)) {
1457                         // return existing element
1458                         return element;
1459                     }
1460                 }
1461 
1462                 final int newSize = size + 1;
1463 
1464                 MemberName[] newTab;
1465                 if ((newTab = resize(tab, newSize)) != null) { // we needed to resize
1466                     // publish new table
1467                     table = tab = newTab;
1468                     // retry loop with new table
1469                 } else { // current tab.length is enough
1470                     // publish new element
1471                     setVolatile(tab, i, newElement);
1472                     size = newSize;
1473                     return null;
1474                 }
1475             }
1476         }
1477 
1478         // utility methods
1479 
1480         /**
1481          * Re-sizes the table if necessary to hold given number of elements.
1482          *
1483          * @return new table with elements copied to it if resizing was performed
1484          *         or null if no resizing is necessary because the table
1485          *         has enough room.
1486          */
1487         private static MemberName[] resize(MemberName[] oldTable, int newSize) {
1488             int oldLength = oldTable.length;
1489             int newLength = oldLength;
1490             // length should always be >= 3 * size / 2.
1491             while (newLength < newSize + (newSize >> 1) &&
1492                    newLength < MAXIMUM_CAPACITY) {
1493                 // next power of 2
1494                 newLength <<= 1;
1495             }
1496             if (oldLength == newLength) { // no resizing needed
1497                 if (newSize == MAXIMUM_CAPACITY)
1498                     throw new IllegalStateException("Capacity exhausted.");
1499                 // current length is enough
1500                 return null;
1501             }
1502 
1503             MemberName[] newTable = new MemberName[newLength];
1504 
1505             // copy elements to new table
1506             for (MemberName element : oldTable) {
1507                 if (element != null) {
1508                     int i = hash(element, newLength);
1509                     while (newTable[i] != null)
1510                         i = nextKeyIndex(i, newLength);
1511                     newTable[i] = element;
1512                 }
1513             }
1514 
1515             return newTable;
1516         }
1517 
1518         /**
1519          * Returns index for Object x.
1520          */
1521         private static int hash(Object x, int length) {
1522             int h = x.hashCode();
1523             return (h ^ (h >>> 16)) & (length - 1);
1524         }
1525 
1526         /**
1527          * Circularly traverses table of size length (which is a power of 2).
1528          */
1529         private static int nextKeyIndex(int i, int length) {
1530             return (i + 1) & (length - 1);
1531         }
1532 
1533         // Unsafe machinery
1534         private static final Unsafe UNSAFE = Unsafe.getUnsafe();
1535         private static final long MN_ARRAY_BASE;
1536         private static final int MN_ARRAY_INDEX_SHIFT;
1537 
1538         static {
1539             try {
1540                 MN_ARRAY_BASE = UNSAFE.arrayBaseOffset(
1541                     MemberName[].class
1542                 );
1543                 int scale = UNSAFE.arrayIndexScale(MemberName[].class);
1544                 if ((scale & (scale - 1)) != 0)
1545                     throw new Error("MemberName[] index scale not a power of two");
1546                 MN_ARRAY_INDEX_SHIFT = 31 - Integer.numberOfLeadingZeros(scale);
1547             } catch (Exception e) {
1548                 throw new Error(e);
1549             }
1550         }
1551 
1552         private static MemberName getVolatile(MemberName[] tab, int i) {
1553             return (MemberName) UNSAFE.getObjectVolatile(tab, arrayOffset(tab, i));
1554         }
1555 
1556         private static void setVolatile(MemberName[] tab, int i, MemberName element) {
1557             UNSAFE.putObjectVolatile(tab, arrayOffset(tab, i), element);
1558         }
1559 
1560         private static long arrayOffset(MemberName[] tab, int i) {
1561             if (i < 0 || i >= tab.length)
1562                 throw new ArrayIndexOutOfBoundsException(i);
1563             return ((long) i << MN_ARRAY_INDEX_SHIFT) + MN_ARRAY_BASE;
1564         }
1565     }
1566 }