< prev index next >
src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Print this page
@@ -24,10 +24,11 @@
*/
package java.lang.invoke;
+import java.lang.ref.WeakReference;
import java.util.*;
import static java.lang.invoke.MethodHandleStatics.*;
/**
@@ -430,12 +431,11 @@
@interface PolymorphicSignature { }
private final MethodType type;
/*private*/ final LambdaForm form;
// form is not private so that invokers can easily fetch it
- /*private*/ MethodHandle asTypeCache;
- // asTypeCache is not private so that invokers can easily fetch it
+ private WeakReference<MethodHandle> asTypeCache;
/*non-public*/ byte customizationCount;
// customizationCount should be accessible from invokers
/**
* Reports the type of this method handle.
@@ -743,37 +743,40 @@
* necessary return value conversions
* @throws NullPointerException if {@code newType} is a null reference
* @throws WrongMethodTypeException if the conversion cannot be made
* @see MethodHandles#explicitCastArguments
*/
- public MethodHandle asType(MethodType newType) {
+ public final MethodHandle asType(MethodType newType) {
// Fast path alternative to a heavyweight {@code asType} call.
// Return 'this' if the conversion will be a no-op.
if (newType == type) {
return this;
}
// Return 'this.asTypeCache' if the conversion is already memoized.
- MethodHandle atc = asTypeCached(newType);
- if (atc != null) {
- return atc;
+ MethodHandle at = asTypeCached(newType);
+ if (at != null) {
+ return at;
}
- return asTypeUncached(newType);
+ at = asTypeUncached(newType);
+ asTypeCache = new WeakReference<>(at);
+ return at;
}
private MethodHandle asTypeCached(MethodType newType) {
- MethodHandle atc = asTypeCache;
- if (atc != null && newType == atc.type) {
+ MethodHandle atc;
+ if (asTypeCache != null && (atc = asTypeCache.get()) != null &&
+ newType == atc.type) {
return atc;
}
return null;
}
/** Override this to change asType behavior. */
/*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
if (!type.isConvertibleTo(newType))
throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
- return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, true);
+ return MethodHandleImpl.makePairwiseConvert(this, newType, true);
}
/**
* Makes an <em>array-spreading</em> method handle, which accepts a trailing array argument
* and spreads its elements as positional arguments.
< prev index next >