Skip to content

8350462: MethodTypeForm.LF_INTERPRET can cache the MemberName instead #24468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions src/java.base/share/classes/java/lang/invoke/LambdaForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
16 changes: 15 additions & 1 deletion src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the LF_INTERPRET constant from this list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, removed it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the index 6 is left unused in the LF cache array - we can leave it empty and renumber the cache indices when we add a new entry to cache.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the explanation.

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down