src/java.base/share/classes/java/lang/invoke/LambdaForm.java
Print this page
@@ -122,11 +122,17 @@
@Stable final Name[] names;
final String debugName;
MemberName vmentry; // low-level behavior, or null if not yet prepared
private boolean isCompiled;
- Object transformCache; // managed by LambdaFormEditor
+ volatile Object transformCache; // managed by LambdaFormEditor
+
+ // non-null only if this is a derived LF that is cached in
+ // baseLambdaForm.transformCache. this is necessary so that base LF
+ // this LF was derived from is not GC-ed for as long as this LF is retained.
+ // no program logic is dependent on this field. just GC.
+ private final LambdaForm baseLambdaForm;
public static final int VOID_RESULT = -1, LAST_RESULT = -2;
enum BasicType {
L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types
@@ -239,13 +245,14 @@
assert !Arrays.asList(ARG_TYPES).contains(V_TYPE);
return true;
}
}
- LambdaForm(String debugName,
+ LambdaForm(LambdaForm baseLambdaForm, String debugName,
int arity, Name[] names, int result) {
assert(namesOK(arity, names));
+ this.baseLambdaForm = baseLambdaForm;
this.arity = arity;
this.result = fixResult(result, names);
this.names = names.clone();
this.debugName = fixDebugName(debugName);
int maxOutArity = normalize();
@@ -255,10 +262,15 @@
compileToBytecode();
}
}
LambdaForm(String debugName,
+ int arity, Name[] names, int result) {
+ this(null, debugName, arity, names, result);
+ }
+
+ LambdaForm(String debugName,
int arity, Name[] names) {
this(debugName,
arity, names, LAST_RESULT);
}
@@ -281,10 +293,11 @@
private LambdaForm(String sig) {
// Make a blank lambda form, which returns a constant zero or null.
// It is used as a template for managing the invocation of similar forms that are non-empty.
// Called only from getPreparedForm.
assert(isValidSignature(sig));
+ this.baseLambdaForm = null;
this.arity = signatureArity(sig);
this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity);
this.names = buildEmptyNames(arity, sig);
this.debugName = "LF.zero";
assert(nameRefsAreLegal());