示例#1
0
 static {
   // The Holder class will contain pre-generated DirectMethodHandles resolved
   // speculatively using MemberName.getFactory().resolveOrNull. However, that
   // doesn't initialize the class, which subtly breaks inlining etc. By forcing
   // initialization of the Holder class we avoid these issues.
   UNSAFE.ensureClassInitialized(Holder.class);
 }
示例#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
 @Override
 protected WeakReference<Thread> computeValue(Class<?> type) {
   UNSAFE.ensureClassInitialized(type);
   if (UNSAFE.shouldBeInitialized(type))
     // If the previous call didn't block, this can happen.
     // We are executing inside <clinit>.
     return new WeakReference<>(Thread.currentThread());
   return null;
 }
示例#4
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;
 }