diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java index 1c782e1cbc57e..7ba66a473fea2 100644 --- a/src/java.base/share/classes/java/lang/invoke/LambdaForm.java +++ b/src/java.base/share/classes/java/lang/invoke/LambdaForm.java @@ -371,14 +371,6 @@ static LambdaForm create(int arity, Name[] names, boolean forceInline, Kind kind return create(arity, names, DEFAULT_RESULT, forceInline, DEFAULT_CUSTOMIZED, kind); } - private static LambdaForm createBlankForType(MethodType mt) { - // Make a dummy blank lambda form. - // It is used as a template for managing the invocation of similar forms that are non-empty. - // Called only from getPreparedForm. - LambdaForm form = new LambdaForm(0, 0, DEFAULT_FORCE_INLINE, DEFAULT_CUSTOMIZED, new Name[0], Kind.GENERIC); - return form; - } - private static int fixResult(int result, Name[] names) { if (result == LAST_RESULT) result = names.length - 1; // might still be void @@ -785,14 +777,15 @@ public void prepare() { return; } MethodType mtype = methodType(); - LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET); - if (prep == null) { + MethodTypeForm form = mtype.form(); + + MemberName entry = form.cachedInterpretEntry(); + if (entry == null) { assert (isValidSignature(basicTypeSignature())); - prep = LambdaForm.createBlankForType(mtype); - prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype); - prep = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep); + entry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype); + entry = form.setCachedInterpretEntry(entry); } - this.vmentry = prep.vmentry; + this.vmentry = entry; // TO DO: Maybe add invokeGeneric, invokeWithArguments } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java index c344cd034c703..8bbc4dd5f727a 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java @@ -64,6 +64,8 @@ final class MethodTypeForm { // Cached lambda form information, for basic types only: private final Object[] lambdaForms; + private SoftReference<MemberName> interpretEntry; + // Indexes into lambdaForms: static final int LF_INVVIRTUAL = 0, // DMH invokeVirtual @@ -72,7 +74,6 @@ final class MethodTypeForm { LF_NEWINVSPECIAL = 3, LF_INVINTERFACE = 4, LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier - LF_INTERPRET = 6, // LF interpreter LF_REBIND = 7, // BoundMethodHandle LF_DELEGATE = 8, // DelegatingMethodHandle LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline @@ -162,6 +163,19 @@ public synchronized LambdaForm setCachedLambdaForm(int which, LambdaForm form) { return form; } + public MemberName cachedInterpretEntry() { + return (interpretEntry == null) ? null : interpretEntry.get(); + } + + public synchronized MemberName setCachedInterpretEntry(MemberName mn) { + MemberName prev = cachedInterpretEntry(); + if (prev != null) { + return prev; + } + this.interpretEntry = new SoftReference<>(mn); + return mn; + } + /** * Build an MTF for a given type, which must have all references erased to Object. * This MTF will stand for that type and all un-erased variations.