下面列出了java.lang.invoke.MutableCallSite#setTarget ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static void testNonBoundCallSite() throws Throwable {
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
// mcs.context == null
MethodHandle mh = mcs.dynamicInvoker();
execute(1, mh);
// mcs.context == cls1
Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("NonBound_1"), null);
MethodHandle mh1 = LOOKUP.findStatic(cls1, METHOD_NAME, TYPE);
execute(1, mh1);
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
execute(2, mh, mh1);
}
@SuppressWarnings("unused")
private static MethodHandle nativeCallSetup(MutableCallSite callsite, String name, ExecutionContext cx) {
RuntimeContext context = cx.getRuntimeContext();
MethodHandle target;
try {
MethodHandle mh = context.getNativeCallResolver().apply(name, callsite.type());
if (mh == null) {
throw new IllegalArgumentException();
}
target = adaptNativeMethodHandle(mh);
target = adaptMethodHandle(name, callsite.type(), target);
} catch (IllegalArgumentException e) {
target = invalidCallHandle(name, callsite.type());
}
callsite.setTarget(target);
return target;
}
private static MethodHandle setCallSiteTarget(MutableCallSite callsite, MethodHandle target, MethodHandle test,
MethodHandle generic) {
MethodHandle callSiteTarget;
if (target != null) {
target = target.asType(callsite.type());
if (test != null) {
MethodHandle fallback = createFallback(callsite, generic);
callSiteTarget = MethodHandles.guardWithTest(test, target, fallback);
} else {
callSiteTarget = target;
}
} else {
callSiteTarget = target = generic;
}
callsite.setTarget(callSiteTarget);
return target;
}
public static void testSharedCallSite() throws Throwable {
Class<?> cls1 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_1"), null);
Class<?> cls2 = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("CS_2"), null);
MethodHandle[] mhs = new MethodHandle[] {
LOOKUP.findStatic(cls1, METHOD_NAME, TYPE),
LOOKUP.findStatic(cls2, METHOD_NAME, TYPE)
};
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
execute(1, mhs);
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
execute(2, mhs);
}
/**
* Get the cached methodhandle. if the related methodhandle is not found in the inline cache, cache and return it.
*/
public static Object fromCache(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable {
FallbackSupplier fallbackSupplier = new FallbackSupplier(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments);
MethodHandleWrapper mhw =
doWithCallSite(
callSite, arguments,
(cs, receiver) ->
cs.getAndPut(
receiver.getClass().getName(),
c -> {
MethodHandleWrapper fbMhw = fallbackSupplier.get();
return fbMhw.isCanSetTarget() ? fbMhw : NULL_METHOD_HANDLE_WRAPPER;
}
)
);
if (NULL_METHOD_HANDLE_WRAPPER == mhw) {
mhw = fallbackSupplier.get();
}
if (mhw.isCanSetTarget() && (callSite.getTarget() != mhw.getTargetMethodHandle()) && (mhw.getLatestHitCount() > INDY_OPTIMIZE_THRESHOLD)) {
callSite.setTarget(mhw.getTargetMethodHandle());
if (LOG_ENABLED) LOG.info("call site target set, preparing outside invocation");
mhw.resetLatestHitCount();
}
return mhw.getCachedMethodHandle().invokeExact(arguments);
}
private void updateCallSite(boolean desired_state, MethodHandle tester, MutableCallSite c, MethodHandle mh, MutableCallSite[] cs) {
try {
if (((boolean)tester.invokeExact()) != desired_state) {
c.setTarget(mh);
MutableCallSite.syncAll(cs);
}
} catch (Throwable e) {
Misc.internalError(e);
}
}
public static void testGC(boolean clear, boolean precompile) throws Throwable {
String id = "_" + clear + "_" + precompile;
mcs = new MutableCallSite(LOOKUP.findStatic(T.class, "f1", TYPE));
Class<?>[] cls = new Class[] {
UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_1" + id), null),
UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_2" + id), null),
};
MethodHandle[] mhs = new MethodHandle[] {
LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE),
LOOKUP.findStatic(cls[1], METHOD_NAME, TYPE),
};
// mcs.context == cls[0]
int r = (int) mhs[0].invokeExact();
execute(1, mhs);
ref = new PhantomReference<>(cls[0], rq);
cls[0] = UNSAFE.defineAnonymousClass(CallSiteDepContextTest.class, getClassFile("GC_3" + id), null);
mhs[0] = LOOKUP.findStatic(cls[0], METHOD_NAME, TYPE);
do {
System.gc();
try {
Reference ref1 = rq.remove(100);
if (ref1 == ref) {
break;
}
} catch(InterruptedException e) { /* ignore */ }
} while (true);
if (clear) {
ref.clear();
System.gc(); // Ensure that the stale context is unloaded
}
if (precompile) {
execute(1, mhs);
}
mcs.setTarget(LOOKUP.findStatic(T.class, "f2", TYPE));
execute(2, mhs);
}
private static MutableCallSite createRuntimeCallSite(String name, MethodType type) {
MutableCallSite callsite = new MutableCallSite(type);
MethodHandle target = MethodHandles.insertArguments(nativeCallSetupMH, 0, callsite, name);
callsite.setTarget(MethodHandles.foldArguments(MethodHandles.exactInvoker(type), target));
return callsite;
}
private static MethodHandle switchToGeneric(MutableCallSite callsite, MethodHandle generic) {
callsite.setTarget(generic);
return generic;
}
/**
* Creates and returns a new MutableCallSite,
// * recording it in list of all callsites for this type, in a map by typename
// *
// * Done this way because
// * - can't be a classloader-wide list of call sites - some might not be associated with this type system
// * - can't be a typesystem-wide list of call sites - the JCas class might be used by multiple type systems
// * and the first one to load it would set this value.
// * - has to be pairs of feature name, call-site, in order to get the value to set, later
// * -- doesn't need to be a hashmap, can be an arraylist of entry
// * Type being loaded may not be known at this point.
* @param clazz the JCas class
* @param featName the short name of the feature
* @return the created callsite
*/
public final static MutableCallSite createCallSite(Class<? extends TOP> clazz, String featName) {
MutableCallSite callSite = new MutableCallSite(MethodType.methodType(int.class));
callSite.setTarget(MHC_MINUS_1); // for error checking
// ArrayList<Entry<String, MutableCallSite>> callSitesForType = FSClassRegistry.callSites_all_JCasClasses.computeIfAbsent(clazz, k -> new ArrayList<>());
// callSitesForType.add(new AbstractMap.SimpleEntry<String, MutableCallSite>(featName, callSite));
return callSite;
}