Skip to content

Conversation

@teshull
Copy link
Contributor

@teshull teshull commented May 23, 2025

This PR adds support for directly retrieving both all invokedynamic and all condy BootstrapMethodInvocations from a ConstantPool via the new method List<BootstrapMethodInvocation> lookupBootstrapMethodInvocations(boolean invokeDynamic).

In addition, two methods are added to the BootstrapMethodInvocations:

  1. void resolve()
  2. JavaConstant lookup()

The combination of these two features allows one to directly interact with all BSM information of a given ConstantPool without having to iterate through all of the Classfile's methods to find all invokedynamic bytecodes and/or iterate through all Constant Pool entries.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8357660: [JVMCI] Add support for retrieving all BootstrapMethodInvocations directly from ConstantPool (Enhancement - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/25420/head:pull/25420
$ git checkout pull/25420

Update a local copy of the PR:
$ git checkout pull/25420
$ git pull https://git.openjdk.org/jdk.git pull/25420/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 25420

View PR using the GUI difftool:
$ git pr show -t 25420

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/25420.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label May 23, 2025
@bridgekeeper
Copy link

bridgekeeper bot commented May 23, 2025

Hi @teshull, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user teshull" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@openjdk
Copy link

openjdk bot commented May 23, 2025

@teshull This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8357660: [JVMCI] Add support for retrieving all BootstrapMethodInvocations directly from ConstantPool

Reviewed-by: dnsimon, yzheng

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 12 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@dougxc, @mur47x111) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk
Copy link

openjdk bot commented May 23, 2025

@teshull The following labels will be automatically applied to this pull request:

  • graal
  • hotspot-compiler

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@teshull
Copy link
Contributor Author

teshull commented May 23, 2025

/covered

@bridgekeeper bridgekeeper bot added the oca-verify Needs verification of OCA signatory status label May 23, 2025
@bridgekeeper
Copy link

bridgekeeper bot commented May 23, 2025

Thank you! Please allow for a few business days to verify that your employer has signed the OCA. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

@dougxc
Copy link
Member

dougxc commented May 24, 2025

Please add some tests for the new methods to test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java.

@teshull
Copy link
Contributor Author

teshull commented May 26, 2025

@dougxc I integrated testing for the new methods into TestDynamicConstant.java now

* constant pool contains no invokedynamic BootstrapMethodInvocations, then null
* is returned.
*/
BootstrapMethodInvocation[] lookupAllIndyBootstrapMethodInvocations();
Copy link
Member

Choose a reason for hiding this comment

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

Why not make this return all BootstrapMethodInvocations? The caller can then filter out the indy ones with isInvokeDynamic. Also, please return a List<BootstrapMethodInvocation> instead of an array - we should never return arrays from JVMCI (see #23159 as an example of addressing existing API). Lastly, return List.of() instead of null.

Copy link
Contributor Author

@teshull teshull May 27, 2025

Choose a reason for hiding this comment

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

Changed to return a list.

Why not make this return all BootstrapMethodInvocations

  1. Within HotSpot it is very easy to pick off all indy BootstrapMethodInvocations via the ConstantPoolCache
  2. Each invokedynamic bytecode location has a unique BootstrapMethodInvocation instance, but they may share the same constant pool entry, so it's not trivial to find all BootstrapMethodInvocations. One would have to iterate both all method bytecodes and constant pool slots, and do some additional filtering.

Copy link
Member

Choose a reason for hiding this comment

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

How about List<BootstrapMethodInvocation> lookupBootstrapMethodInvocations(boolean indy)? That is, it either gets the indy or the condy BSM invocations. I can imagine SVM wanting the latter at some point right?

BTW, I noticed that the javadoc for ConstantPool.lookupBootstrapMethodInvocation is somewhat incorrect. Please check and apply these corrections in this PR:

diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java
index 2273b256f03..3519af4bcbb 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java
@@ -199,12 +199,12 @@ interface BootstrapMethodInvocation {
      * in the constant pool.
      *
      * @param index if {@code opcode} is -1,  {@code index} is a constant pool index. Otherwise {@code opcode}
-     *              must be {@code Bytecodes.INVOKEDYNAMIC}, and {@code index} must be the operand of that
-     *              opcode in the bytecode stream (i.e., a {@code rawIndex}).
-     * @param opcode must be {@code Bytecodes.INVOKEDYNAMIC}, or -1 if
+     *              must be {@code Bytecodes.INVOKEDYNAMIC} or {@code CONSTANT_Dynamic_info}, and {@code index}
+     *              must be the operand of that opcode in the bytecode stream (i.e., a {@code rawIndex}).
+     * @param opcode must be {@code Bytecodes.INVOKEDYNAMIC}, {@code CONSTANT_Dynamic_info}, or -1 if
      *            {@code index} was not decoded from a bytecode stream
      * @return the bootstrap method invocation details or {@code null} if the entry specified by {@code index}
-     *         is not a {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info}
+     *         is not a {@code CONSTANT_Dynamic_info} or {@code CONSTANT_InvokeDynamic_info}
      * @jvms 4.7.23 The {@code BootstrapMethods} Attribute
      */
     default BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int opcode) {

Copy link
Contributor Author

@teshull teshull May 27, 2025

Choose a reason for hiding this comment

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

I prototyped the option List<BootstrapMethodInvocation> lookupBootstrapMethodInvocations(boolean indy) here: master...teshull:jdk:jvmci_bootstrap_alternative

As part of this I also prototyped generic BSM resolution / lookup logic

From the SVM perspective, retrieving condys via this new support isn't a big win. It's easy enough already to walk the ConstantPool. However, for symmetry purposes, it is reasonable to have this method (along with the resolve / lookup). What's your preference: this new version or the original?

Copy link
Member

Choose a reason for hiding this comment

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

I like the symmetry of the new version. Also, I think you can simplify things by replacing use of flatMap here with filter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the javadoc misplaced @ in {@code}. However, the opcode doc changes look wrong to me; the opcode must be -1 or INVOKEDYNAMIC (

int cpi = opcode == -1 ? index : indyIndexConstantPoolIndex(index, opcode);
)

Copy link
Member

Choose a reason for hiding this comment

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

yeah, looks like you're right. I was basing my assumption on case "Dynamic" in:

    @Override
    public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int opcode) {
        int cpi = opcode == -1 ? index : indyIndexConstantPoolIndex(index, opcode);
        final JvmConstant tag = getTagAt(cpi);
        switch (tag.name) {
            case "InvokeDynamic":
            case "Dynamic":

I guess it's possible for an INVOKEDYNAMIC to resolve it's cpi to a CONSTANT_Dynamic entry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think INVOKEDYNAMIC should always point to a CONSTANT_InvokeDynamic entry

}

/**
* Returns the BootstrapMethodInvocation instances for all invokedynamic
Copy link
Member

Choose a reason for hiding this comment

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

Point out that the returned list is unmodifiable (like the API for Stream.toList() does).

@teshull
Copy link
Contributor Author

teshull commented May 29, 2025

@dougxc I cleaned up the PR to now have the symmetric lookup option and updated the tests

teshull and others added 2 commits May 29, 2025 21:20
Co-authored-by: Douglas Simon <[email protected]>
Co-authored-by: Douglas Simon <[email protected]>
} else {
return IntStream.range(1, length()).filter(cpi -> {
return IntStream.range(1, length())
.filter(this::isDynamicEntry)
Copy link
Member

Choose a reason for hiding this comment

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

Looks like you forgot to add the definition of isDynamicEntry that I suggested:

    private boolean isDynamicEntry(int cpi) {
        JvmConstant tagAt = getTagAt(cpi);
        return tagAt != null && tagAt.name.equals("Dynamic");
    }

Copy link
Contributor Author

@teshull teshull May 29, 2025

Choose a reason for hiding this comment

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

Yes, I applied the suggested change via github, and am just validating it works now (which of course it doesn't). I'll fix it

@dougxc
Copy link
Member

dougxc commented May 30, 2025

I also updated the title of https://bugs.openjdk.org/browse/JDK-8357660 to Not Be All Capitalized so you'll need to fix the title of this PR.
Also, please update both titles and descriptions further to reflect the final changes (i.e. lookupBootstrapMethodInvocations instead of lookupIndyBootstrapMethodInvocations).

private final String name;
private final JavaConstant type;
private final List<JavaConstant> staticArguments;
private final int index;
Copy link
Member

Choose a reason for hiding this comment

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

index -> cpiOrIndyIndex

@bridgekeeper bridgekeeper bot removed oca Needs verification of OCA signatory status oca-verify Needs verification of OCA signatory status labels May 30, 2025
@openjdk openjdk bot added the rfr Pull request is ready for review label May 30, 2025
@mlbridge
Copy link

mlbridge bot commented May 30, 2025

Webrevs

@teshull teshull changed the title 8357660: [JVMCI] Add Support for Retrieving All Indy BootstrapMethodInvocations directly from the ConstantPool 8357660: [JVMCI] Add support for retrieving all BootstrapMethodInvocations directly from ConstantPool Jun 2, 2025
Copy link
Member

@dougxc dougxc left a comment

Choose a reason for hiding this comment

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

Looks good to me.

Please enable GitHub Actions on your JDK fork.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jun 2, 2025
Copy link
Contributor

@mur47x111 mur47x111 left a comment

Choose a reason for hiding this comment

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

LGTM

@teshull
Copy link
Contributor Author

teshull commented Jun 4, 2025

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Jun 4, 2025
@openjdk
Copy link

openjdk bot commented Jun 4, 2025

@teshull
Your change (at version c7f5c1a) is now ready to be sponsored by a Committer.

@dougxc
Copy link
Member

dougxc commented Jun 4, 2025

/sponsor

@openjdk
Copy link

openjdk bot commented Jun 4, 2025

Going to push as commit 0352477.
Since your change was applied there have been 12 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Jun 4, 2025
@openjdk openjdk bot closed this Jun 4, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review sponsor Pull request is ready to be sponsored labels Jun 4, 2025
@openjdk
Copy link

openjdk bot commented Jun 4, 2025

@dougxc @teshull Pushed as commit 0352477.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants