예제 #1
0
 boolean resolveInPlace(MemberName m, boolean searchSupers, Class<?> lookupClass) {
   if (m.name == null || m.type == null) { // find unique non-overloaded name
     Class<?> defc = m.getDeclaringClass();
     List<MemberName> choices = null;
     if (m.isMethod())
       choices = getMethods(defc, searchSupers, m.name, (MethodType) m.type, lookupClass);
     else if (m.isConstructor()) choices = getConstructors(defc, lookupClass);
     else if (m.isField())
       choices = getFields(defc, searchSupers, m.name, (Class<?>) m.type, lookupClass);
     // System.out.println("resolving "+m+" to "+choices);
     if (choices == null || choices.size() != 1) return false;
     if (m.name == null) m.name = choices.get(0).name;
     if (m.type == null) m.type = choices.get(0).type;
   }
   MethodHandleNatives.resolve(m, lookupClass);
   if (m.isResolved()) return true;
   int matchFlags = m.flags | (searchSupers ? SEARCH_ALL_SUPERS : 0);
   String matchSig = m.getSignature();
   MemberName[] buf = {m};
   int n =
       MethodHandleNatives.getMembers(
           m.getDeclaringClass(), m.getName(), matchSig, matchFlags, lookupClass, 0, buf);
   if (n != 1) return false;
   return m.isResolved();
 }
예제 #2
0
 /*non-public*/ static boolean shouldBeInitialized(MemberName member) {
   switch (member.getReferenceKind()) {
     case REF_invokeStatic:
     case REF_getStatic:
     case REF_putStatic:
     case REF_newInvokeSpecial:
       break;
     default:
       // No need to initialize the class on this kind of member.
       return false;
   }
   Class<?> cls = member.getDeclaringClass();
   if (cls == ValueConversions.class || cls == MethodHandleImpl.class || cls == Invokers.class) {
     // These guys have lots of <clinit> DMH creation but we know
     // the MHs will not be used until the system is booted.
     return false;
   }
   if (VerifyAccess.isSamePackage(MethodHandle.class, cls)
       || VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
     // It is a system class.  It is probably in the process of
     // being initialized, but we will help it along just to be safe.
     if (UNSAFE.shouldBeInitialized(cls)) {
       UNSAFE.ensureClassInitialized(cls);
     }
     return false;
   }
   return UNSAFE.shouldBeInitialized(cls);
 }
예제 #3
0
 // Factory methods:
 static DirectMethodHandle make(byte refKind, Class<?> receiver, MemberName member) {
   MethodType mtype = member.getMethodOrFieldType();
   if (!member.isStatic()) {
     if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
       throw new InternalError(member.toString());
     mtype = mtype.insertParameterTypes(0, receiver);
   }
   if (!member.isField()) {
     if (refKind == REF_invokeSpecial) {
       member = member.asSpecial();
       LambdaForm lform = preparedLambdaForm(member);
       return new Special(mtype, lform, member);
     } else {
       LambdaForm lform = preparedLambdaForm(member);
       return new DirectMethodHandle(mtype, lform, member);
     }
   } else {
     LambdaForm lform = preparedFieldLambdaForm(member);
     if (member.isStatic()) {
       long offset = MethodHandleNatives.staticFieldOffset(member);
       Object base = MethodHandleNatives.staticFieldBase(member);
       return new StaticAccessor(mtype, lform, member, base, offset);
     } else {
       long offset = MethodHandleNatives.objectFieldOffset(member);
       assert (offset == (int) offset);
       return new Accessor(mtype, lform, member, (int) offset);
     }
   }
 }
예제 #4
0
 private static DirectMethodHandle makeAllocator(MemberName ctor) {
   assert (ctor.isConstructor() && ctor.getName().equals("<init>"));
   Class<?> instanceClass = ctor.getDeclaringClass();
   ctor = ctor.asConstructor();
   assert (ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
   MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
   LambdaForm lform = preparedLambdaForm(ctor);
   MemberName init = ctor.asSpecial();
   assert (init.getMethodType().returnType() == void.class);
   return new Constructor(mtype, lform, ctor, init, instanceClass);
 }
예제 #5
0
  // Constructors and factory methods in this class *must* be package scoped or private.
  private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
    super(mtype, form);
    if (!member.isResolved()) throw new InternalError();

    if (member.getDeclaringClass().isInterface() && member.isMethod() && !member.isAbstract()) {
      // Check for corner case: invokeinterface of Object method
      MemberName m =
          new MemberName(
              Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
      m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
      if (m != null && m.isPublic()) {
        assert (member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong
        member = m;
      }
    }

    this.member = member;
  }
예제 #6
0
 private static boolean checkInitialized(MemberName member) {
   Class<?> defc = member.getDeclaringClass();
   WeakReference<Thread> ref = EnsureInitialized.INSTANCE.get(defc);
   if (ref == null) {
     return true; // the final state
   }
   Thread clinitThread = ref.get();
   // Somebody may still be running defc.<clinit>.
   if (clinitThread == Thread.currentThread()) {
     // If anybody is running defc.<clinit>, it is this thread.
     if (UNSAFE.shouldBeInitialized(defc))
       // Yes, we are running it; keep the barrier for now.
       return false;
   } else {
     // We are in a random thread.  Block.
     UNSAFE.ensureClassInitialized(defc);
   }
   assert (!UNSAFE.shouldBeInitialized(defc));
   // put it into the final state
   EnsureInitialized.INSTANCE.remove(defc);
   return true;
 }
예제 #7
0
 private static void maybeCompile(LambdaForm lform, MemberName m) {
   if (lform.vmentry == null
       && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
     // Help along bootstrapping...
     lform.compileToBytecode();
 }
예제 #8
0
 static DirectMethodHandle make(MemberName member) {
   if (member.isConstructor()) return makeAllocator(member);
   return make(member.getDeclaringClass(), member);
 }