# HG changeset patch # User vlivanov # Date 1431602487 -10800 # Thu May 14 14:21:27 2015 +0300 # Node ID 553c7d3ad94ff4af8e4df72373e7cf429517fc31 # Parent 3546406dac227981ca39fb4fe39260f0c0713af7 imported patch call_site_deps.03 diff --git a/src/java.base/share/classes/java/lang/invoke/CallSite.java b/src/java.base/share/classes/java/lang/invoke/CallSite.java --- a/src/java.base/share/classes/java/lang/invoke/CallSite.java +++ b/src/java.base/share/classes/java/lang/invoke/CallSite.java @@ -27,7 +27,7 @@ import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; -import java.lang.reflect.Field; + import sun.misc.Cleaner; /** @@ -139,44 +139,22 @@ /** * {@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; + private final Context context = Context.make(this); - /** - * 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); + static class Context { + //private long dep; + //@Injected JVM_nmethodBucket* dep; - 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). + static Context make(CallSite cs) { + final Context newContext = new Context(); + Cleaner.create(cs, new Runnable() { + @Override + public void run() { + MethodHandleNatives.clearCallSiteContext(newContext); + } + }); + return newContext; } } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -62,7 +62,7 @@ static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target); /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */ - static native void invalidateDependentNMethods(CallSite site); + static native void clearCallSiteContext(CallSite.Context context); private static native void registerNatives(); static { @@ -235,7 +235,6 @@ return Invokers.linkToTargetMethod(type); } else { appendixResult[0] = callSite; - callSite.initContext(caller); return Invokers.linkToCallSiteMethod(type); } } # HG changeset patch # User vlivanov # Date 1431605832 -10800 # Thu May 14 15:17:12 2015 +0300 # Node ID 1170f5c35c641b0ff5a8725eac07d802208cd051 # Parent 553c7d3ad94ff4af8e4df72373e7cf429517fc31 [mq]: call_site_deps.03.01 diff --git a/src/java.base/share/classes/java/lang/invoke/CallSite.java b/src/java.base/share/classes/java/lang/invoke/CallSite.java --- a/src/java.base/share/classes/java/lang/invoke/CallSite.java +++ b/src/java.base/share/classes/java/lang/invoke/CallSite.java @@ -27,7 +27,6 @@ import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; - import sun.misc.Cleaner; /** @@ -138,24 +137,30 @@ /** * {@code CallSite} dependency context. - * VM uses context class to store nmethod dependencies on the call site target. + * JVM uses CallSite.context to store nmethod dependencies on the call site target. */ private final Context context = Context.make(this); - static class Context { - //private long dep; - //@Injected JVM_nmethodBucket* dep; + 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.create(cs, new Runnable() { - @Override - public void run() { - MethodHandleNatives.clearCallSiteContext(newContext); - } - }); + // 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); + } } /**