< prev index next > src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
Print this page
import sun.invoke.util.Wrapper;
import java.lang.ref.SoftReference;
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+ import static java.lang.invoke.MethodHandleStatics.NO_SOFT_CACHE;
/**
* Shared information for a group of method types, which differ
* only by reference types, and therefore share a common erasure
* and wrapping.
final short primitiveCount;
final MethodType erasedType; // the canonical erasure
final MethodType basicType; // the canonical erasure, with primitives simplified
// Cached adapter information:
! final SoftReference<MethodHandle>[] methodHandles;
// Indexes into methodHandles:
static final int
MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
MH_NF_INV = 1, // cached helper for LF.NamedFunction
MH_UNINIT_CS = 2, // uninitialized call site
MH_LIMIT = 3;
// Cached lambda form information, for basic types only:
! final SoftReference<LambdaForm>[] lambdaForms;
// Indexes into lambdaForms:
static final int
LF_INVVIRTUAL = 0, // DMH invokeVirtual
LF_INVSTATIC = 1,
final short primitiveCount;
final MethodType erasedType; // the canonical erasure
final MethodType basicType; // the canonical erasure, with primitives simplified
// Cached adapter information:
! private final Object[] methodHandles;
// Indexes into methodHandles:
static final int
MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
MH_NF_INV = 1, // cached helper for LF.NamedFunction
MH_UNINIT_CS = 2, // uninitialized call site
MH_LIMIT = 3;
// Cached lambda form information, for basic types only:
! private final Object[] lambdaForms;
// Indexes into lambdaForms:
static final int
LF_INVVIRTUAL = 0, // DMH invokeVirtual
LF_INVSTATIC = 1,
*/
public MethodType basicType() {
return basicType;
}
public MethodHandle cachedMethodHandle(int which) {
! SoftReference<MethodHandle> entry = methodHandles[which];
! return (entry != null) ? entry.get() : null;
}
public synchronized MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
// Simulate a CAS, to avoid racy duplication of results.
! SoftReference<MethodHandle> entry = methodHandles[which];
! if (entry != null) {
! MethodHandle prev = entry.get();
! if (prev != null) {
! return prev;
! }
}
- methodHandles[which] = new SoftReference<>(mh);
return mh;
}
public LambdaForm cachedLambdaForm(int which) {
! SoftReference<LambdaForm> entry = lambdaForms[which];
! return (entry != null) ? entry.get() : null;
}
public synchronized LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
// Simulate a CAS, to avoid racy duplication of results.
! SoftReference<LambdaForm> entry = lambdaForms[which];
! if (entry != null) {
! LambdaForm prev = entry.get();
! if (prev != null) {
! return prev;
! }
}
- lambdaForms[which] = new SoftReference<>(form);
return form;
}
/**
* Build an MTF for a given type, which must have all references erased to Object.
*/
public MethodType basicType() {
return basicType;
}
+ @SuppressWarnings({"rawtypes", "unchecked"})
public MethodHandle cachedMethodHandle(int which) {
! Object entry = methodHandles[which];
! if (entry == null) {
+ return null;
+ } else if (entry instanceof MethodHandle) {
+ return (MethodHandle) entry;
+ } else {
+ return ((SoftReference<MethodHandle>)entry).get();
+ }
}
public synchronized MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
// Simulate a CAS, to avoid racy duplication of results.
! MethodHandle prev = cachedMethodHandle(which);
! if (prev != null) {
! return prev;
! }
! if (NO_SOFT_CACHE) {
! methodHandles[which] = mh;
+ } else {
+ methodHandles[which] = new SoftReference<>(mh);
}
return mh;
}
+ @SuppressWarnings({"rawtypes", "unchecked"})
public LambdaForm cachedLambdaForm(int which) {
! Object entry = lambdaForms[which];
! if (entry == null) {
+ return null;
+ } else if (entry instanceof LambdaForm) {
+ return (LambdaForm) entry;
+ } else {
+ return ((SoftReference<LambdaForm>)entry).get();
+ }
}
public synchronized LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
// Simulate a CAS, to avoid racy duplication of results.
! LambdaForm prev = cachedLambdaForm(which);
! if (prev != null) {
! return prev;
! }
! if (NO_SOFT_CACHE) {
! lambdaForms[which] = form;
+ } else {
+ lambdaForms[which] = new SoftReference<>(form);
}
return form;
}
/**
* Build an MTF for a given type, which must have all references erased to Object.
if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
this.primitiveCount = primitiveCount;
this.parameterSlotCount = (short)pslotCount;
! this.lambdaForms = new SoftReference[LF_LIMIT];
! this.methodHandles = new SoftReference[MH_LIMIT];
} else {
this.basicType = MethodType.methodType(basicReturnType, basicPtypes, true);
// fill in rest of data from the basic type:
MethodTypeForm that = this.basicType.form();
assert(this != that);
if (pslotCount >= 256) throw newIllegalArgumentException("too many arguments");
this.primitiveCount = primitiveCount;
this.parameterSlotCount = (short)pslotCount;
! this.lambdaForms = new Object[LF_LIMIT];
! this.methodHandles = new Object[MH_LIMIT];
} else {
this.basicType = MethodType.methodType(basicReturnType, basicPtypes, true);
// fill in rest of data from the basic type:
MethodTypeForm that = this.basicType.form();
assert(this != that);
< prev index next >