< prev index next >

src/java.base/share/classes/java/lang/invoke/CallSite.java

Print this page

        

*** 25,35 **** package java.lang.invoke; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; - import java.lang.reflect.Field; import sun.misc.Cleaner; /** * A {@code CallSite} is a holder for a variable {@link MethodHandle}, * which is called its {@code target}. --- 25,34 ----
*** 136,184 **** this.target = boundTarget; } /** * {@code CallSite} dependency context. ! * VM uses context class to store nmethod dependencies on the call site target. ! * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance. ! * Lazily initialized when CallSite instance is linked to some indy call site or VM needs ! * it to store dependencies. As a corollary, "null" context means there are no dependencies ! * registered yet. {@code Cleaner} is used in 2 roles: ! * (a) context class access for VM; ! * (b) stale context class cleanup. ! * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}). ! * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly ! * from {@code Reference.referent} field. */ ! private volatile Cleaner context = null; ! /** ! * Default context. ! * VM uses it to initialize non-linked CallSite context. ! */ ! private static class DefaultContext {} ! private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null); ! ! private static Cleaner makeContext(Class<?> referent, final CallSite holder) { ! return Cleaner.create(referent, ! new Runnable() { ! @Override public void run() { ! MethodHandleNatives.invalidateDependentNMethods(holder); } ! }); } ! /** Initialize context class used for nmethod dependency tracking */ ! /*package-private*/ ! void initContext(Class<?> newContext) { ! // If there are concurrent actions, exactly one succeeds. ! if (context == null) { ! UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this)); ! // No need to care about failed CAS attempt. ! // Since initContext is called from indy call site linkage in newContext class, there's no risk ! // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup ! // action in the wrong context). } } /** * Returns the type of this call site's target. --- 135,167 ---- this.target = boundTarget; } /** * {@code CallSite} dependency context. ! * JVM uses CallSite.context to store nmethod dependencies on the call site target. */ ! private final Context context = Context.make(this); ! static class Context implements Runnable { ! static { ! sun.reflect.Reflection.registerFieldsToFilter(Context.class, "dependencies"); } ! ! private final long dependencies = 0; // Used by JVM to store JVM_nmethodBucket* ! ! static Context make(CallSite cs) { ! final Context newContext = new Context(); ! // Cleaner is attached to CallSite instance and it clears native structures allocated for CallSite context. ! // Though the CallSite can become unreachable, its Context is retained by the Cleaner instance (which is ! // referenced from Cleaner class) until cleanup is performed. ! Cleaner.create(cs, newContext); ! return newContext; } ! @Override ! public void run() { ! MethodHandleNatives.clearCallSiteContext(this); } } /** * Returns the type of this call site's target.
< prev index next >