Skip to content

Conversation

@jdksjolen
Copy link
Contributor

@jdksjolen jdksjolen commented May 19, 2025

Hi,

The constant pool currently has a lot of methods specific to extracting parts of the operands array. What this array actually is, is a sequence of bootstrap method attribute entries, where each entry has the following components:

struct BSMAE {
  u2 bootstrap_method_index;
  u2 argument_count;
  u2 arguments[argument_count];
}

We can removes some of these operands array specific methods, and instead allows you to extract BSMAttributeEntrys which you can then use to extract its piece wise components. This makes for a nicer interface, and a bit easier to come into as a reader of the code, as it more closely mirrors the JVMS.

Please consider!

Testing: Currently GHA, running tier1-tier3


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-8357220: Introduce a BSMAttributeEntry struct (Enhancement - P4)

Reviewers

Contributors

  • John R Rose <jrose@openjdk.org>

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 25298

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

Using diff file

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

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented May 19, 2025

👋 Welcome back jsjolen! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented May 19, 2025

@jdksjolen 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:

8357220: Introduce a BSMAttributeEntry struct

Co-authored-by: John R Rose <jrose@openjdk.org>
Reviewed-by: sspitsyn, coleenp, matsaave

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 563 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.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk
Copy link

openjdk bot commented May 19, 2025

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

  • hotspot
  • serviceability

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.

@openjdk openjdk bot added the serviceability serviceability-dev@openjdk.org label May 19, 2025
@jdksjolen
Copy link
Contributor Author

/contributor /contributor add @rose00

@openjdk openjdk bot added the hotspot hotspot-dev@openjdk.org label May 19, 2025
@openjdk
Copy link

openjdk bot commented May 19, 2025

@jdksjolen Syntax: /contributor (add|remove) [@user | openjdk-user | Full Name <email@address>]. For example:

  • /contributor add @openjdk-bot
  • /contributor add duke
  • /contributor add J. Duke <duke@openjdk.org>

User names can only be used for users in the census associated with this repository. For other contributors you need to supply the full name and email address.

@jdksjolen jdksjolen changed the title Introduce BSMAttributeEntry 8357220 May 19, 2025
@openjdk openjdk bot changed the title 8357220 8357220: Introduce a BSMAttributeEntry struct May 19, 2025
@jdksjolen
Copy link
Contributor Author

/contributor add @rose00

@openjdk
Copy link

openjdk bot commented May 19, 2025

@jdksjolen
Contributor John R Rose <jrose@openjdk.org> successfully added.

@jdksjolen jdksjolen marked this pull request as ready for review May 19, 2025 10:03
@openjdk openjdk bot added the rfr Pull request is ready for review label May 19, 2025
@mlbridge
Copy link

mlbridge bot commented May 19, 2025

Comment on lines 124 to 126
private static int INDY_BSM_OFFSET = 0;
private static int INDY_ARGC_OFFSET = 1;
private static int INDY_ARGV_OFFSET = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the SA code that references these fields still correct? It seems the references are from the ClassWriter, which we don't have very good test coverage for. Probably this is a bug that is not being detected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The references are still correct, as we haven't changed the struct layout. We're also not planning on doing so. I don't think that there is a bug here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok. It's just unusual to see constants like these that are needed by SA but serve no purpose in hotspot.

Copy link
Contributor

@coleenp coleenp May 29, 2025

Choose a reason for hiding this comment

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

It does seem like you want to mirror these constants from the vmStructs side like it was rather than defining them here in the SA. I see why you did this but maybe you can add the constants to BSMAttributeEntry and declare them constants using declare_constant(BSMAttributeEntry::_indy...).
In case you change them at some later time.

Comment on lines -573 to -578
enum {
_indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm
_indy_argc_offset = 1, // u2 argc
_indy_argv_offset = 2 // u2 argv[argc]
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@plummercj , this is where the enum constants come from.

Comment on lines 124 to 126
private static int INDY_BSM_OFFSET = 0;
private static int INDY_ARGC_OFFSET = 1;
private static int INDY_ARGV_OFFSET = 2;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The references are still correct, as we haven't changed the struct layout. We're also not planning on doing so. I don't think that there is a bug here.

Copy link
Member

@lfoltan lfoltan left a comment

Choose a reason for hiding this comment

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

Overall looks good, a couple of comments below.

}
};

class BSMAttributeEntry {
Copy link
Member

Choose a reason for hiding this comment

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

Please consider moving the description comment from lines #569-#572 ahead of this structure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This?

  // The first part of the operands array consists of an index into the second part.
  // Extract a 32-bit index value from the first part.

Wouldn't it be better to leave it where it is, but add a comment ahead of the structure?

u2* argument_indexes() {
return reinterpret_cast<u2*>(this + 1);
}

Copy link
Member

Choose a reason for hiding this comment

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

Remove blank lines at #92, #95, #103

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We typically keep a space before we change access modifier, let's keep that pattern in here. We can tighten up the rest of the code according to your suggestions, however.

}

int argument_index(int n) const {
assert(checked_cast<u2>(n) < _argument_count, "oob");
Copy link
Member

Choose a reason for hiding this comment

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

Should the assert contain a check that _argument_count is >= 0 as well?

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 don't think so, it's a u2 so that's just part of its type.

int next_offset = bootstrap_operand_limit(cp_index));
assert(end_offset == next_offset, "matched ending");
return argc;
int bsmai = bootstrap_methods_attribute_index(cp_index);
Copy link
Member

Choose a reason for hiding this comment

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

The "matched ending" assert was the only code that used bootstrap_operand_limit(), so that method could be removed as well. This comment applies to bootstrap_operand_base() as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice!

private static int INDY_BSM_OFFSET;
private static int INDY_ARGC_OFFSET;
private static int INDY_ARGV_OFFSET;
private static int INDY_BSM_OFFSET = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Please update the copyright of this file.

Copy link
Contributor Author

@jdksjolen jdksjolen left a comment

Choose a reason for hiding this comment

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

Thank you for the review Lois! I've addressed most of your comments, but I didn't add any documentation for the BSMAttributeEntry (yet).

u2* argument_indexes() {
return reinterpret_cast<u2*>(this + 1);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We typically keep a space before we change access modifier, let's keep that pattern in here. We can tighten up the rest of the code according to your suggestions, however.

}

int argument_index(int n) const {
assert(checked_cast<u2>(n) < _argument_count, "oob");
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 don't think so, it's a u2 so that's just part of its type.

int next_offset = bootstrap_operand_limit(cp_index));
assert(end_offset == next_offset, "matched ending");
return argc;
int bsmai = bootstrap_methods_attribute_index(cp_index);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice!

}
};

class BSMAttributeEntry {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This?

  // The first part of the operands array consists of an index into the second part.
  // Extract a 32-bit index value from the first part.

Wouldn't it be better to leave it where it is, but add a comment ahead of the structure?

Copy link
Contributor

@coleenp coleenp left a comment

Choose a reason for hiding this comment

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

I think this looks like a nice improvement but I thought operands was going to turn into two arrays? Also there's probably a better name than 'operands' maybe bsm_operands?

Comment on lines 124 to 126
private static int INDY_BSM_OFFSET = 0;
private static int INDY_ARGC_OFFSET = 1;
private static int INDY_ARGV_OFFSET = 2;
Copy link
Contributor

@coleenp coleenp May 29, 2025

Choose a reason for hiding this comment

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

It does seem like you want to mirror these constants from the vmStructs side like it was rather than defining them here in the SA. I see why you did this but maybe you can add the constants to BSMAttributeEntry and declare them constants using declare_constant(BSMAttributeEntry::_indy...).
In case you change them at some later time.

@jdksjolen
Copy link
Contributor Author

Hi,

I think this looks like a nice improvement but I thought operands was going to turn into two arrays? Also there's probably a better name than 'operands' maybe bsm_operands?

Yeah, I hope to do that in a future PR.

Re: SA mirror constants. OK, I can do that, that makes sense.

Copy link
Contributor

@coleenp coleenp left a comment

Choose a reason for hiding this comment

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

This looks good. Looking forward to future improvements in this code. Thank you!

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

@matias9927 matias9927 left a comment

Choose a reason for hiding this comment

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

Changes look good, thanks for doing this!

u2 _bootstrap_method_index;
u2 _argument_count;

const u2* argument_indexes() const {
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with Lois that some comments here would be useful. I think the original comment can stay where it is and you can add some extra details here.

Copy link
Contributor

@sspitsyn sspitsyn left a comment

Choose a reason for hiding this comment

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

It is nice update and refactoring in general.

k2 = cp2->operand_argument_index_at(idx2, j);
k1 = bsm_attribute_entry(idx1)->argument_index(j);
k2 = cp2->bsm_attribute_entry(idx2)->argument_index(j);
match = compare_entry_to(k1, cp2, k2);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd suggest to define two locals to simplify the code as below:

  BSMAttributeEntry* e1 = bsm_attribute_entry(idx1);
  BSMAttributeEntry& e2 = cp2->bsm_attribute_entry(idx12);
 
  int k1 = e1->bootstrap_method_index();
  int k2 = e2->bootstrap_method_index();
  bool match = compare_entry_to(k1, cp2, k2);

  if (!match) {
    return false;
  }
  int argc = e1->argument_count();
  if (argc == e2->argument_count()) {
    for (int j = 0; j < argc; j++) {
      k1 = e1->argument_index(j);
      k2 = e2->argument_index(j);
      match = compare_entry_to(k1, cp2, k2);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's a good simplification.

#include "interpreter/bytecodeStream.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.hpp"
#include "oops/constantPool.inline.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

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

The line 28 is not needed as we already have line 29.


for (int i = 0; i < argc; i++) {
u2 old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i);
u2 old_arg_ref_i = scratch_cp->bsm_attribute_entry(old_bs_i)->argument_index(i);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Could you, consider below for a code simplification? :

  BSMAttributeEntry* old_bsme = scratch_cp->bsm_attribute_entry(old_bs_i);
. . .
665  u2 old_ref_i = old_bsme->bootstrap_method_index();
. . .
679  u2 argc = old_bsme->argument_count();
. . .
686    u2 old_arg_ref_i = old_bsme->argument_index(i);

@jdksjolen
Copy link
Contributor Author

Thank you for the reviews! I applied your comments, will await GHA before integration (also need a re-approval).

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Jun 18, 2025
BSMAttributeEntry* e1 = bsm_attribute_entry(idx1);
BSMAttributeEntry* e2 = bsm_attribute_entry(idx2);
int k1 = e1->bootstrap_method_index();
int k2 = cp2->e2->bootstrap_method_index();
Copy link
Contributor

@sspitsyn sspitsyn Jun 18, 2025

Choose a reason for hiding this comment

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

I'm kind of confused, this does not look right. It is event not going to be compiled.
It is supposed to be as below:

BSMAttributeEntry* e2 = cp2->bsm_attribute_entry(idx2);
. . .
int k2 = e2->bootstrap_method_index();
. . .
    if (argc == e2->argument_count()) {
. . .
    k2 = e2->argument_index(j);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gah, I accidentally made a mistake with the refactoring. Of course, when I pushed I thought "this change is so simple, no need to check it before pushing" :-). Let me fix that (and compile it myself this time)

Copy link
Contributor

Choose a reason for hiding this comment

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

It's okay unless you have not integrated the update. :)
Submitting at least 3 first mach5 tiers before integration will keep you out of potential trouble.

Copy link
Contributor

@sspitsyn sspitsyn left a comment

Choose a reason for hiding this comment

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

Thank you for the update. The fix looks good.
I've posted one more nit though.

write_u2(num_bootstrap_arguments);
for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
u2 bootstrap_argument = cpool()->bsm_attribute_entry(n)->argument_index(arg);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: This line can also use the bsme local: u2 bootstrap_argument = bsme->argument_index(arg);
Sorry, I missed this before.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jun 19, 2025
@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Jun 19, 2025

int bsms_attribute_index = cp->bootstrap_methods_attribute_index(cp_index);
int arg_count = cp->operand_argument_count_at(bsms_attribute_index);
int arg_count = cp->bsm_attribute_entry(bsms_attribute_index)->argument_count();
Copy link
Contributor

Choose a reason for hiding this comment

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

Your fix made it possible to do a bit more simplifications.
For instance, each bsms_attribute_index parameter can be replaced with a bsme parameter.
But this does not look that important at the moment.

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

/integrate

Thank you all for the reviews!

@openjdk
Copy link

openjdk bot commented Jun 23, 2025

Going to push as commit 3d35b40.
Since your change was applied there have been 584 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 23, 2025
@openjdk openjdk bot closed this Jun 23, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jun 23, 2025
@openjdk
Copy link

openjdk bot commented Jun 23, 2025

@jdksjolen Pushed as commit 3d35b40.

💡 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

Labels

hotspot hotspot-dev@openjdk.org integrated Pull request has been integrated serviceability serviceability-dev@openjdk.org

Development

Successfully merging this pull request may close these issues.

6 participants