-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8357220: Introduce a BSMAttributeEntry struct #25298
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
Changes from all commits
e10d91a
13e2725
2a5c820
1c7484d
6d01db3
af3caa9
d891a3d
5d7e46e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1938,18 +1938,20 @@ int ConstantPool::find_matching_entry(int pattern_i, | |
| // Compare this constant pool's bootstrap specifier at idx1 to the constant pool | ||
| // cp2's bootstrap specifier at idx2. | ||
| bool ConstantPool::compare_operand_to(int idx1, const constantPoolHandle& cp2, int idx2) { | ||
| int k1 = operand_bootstrap_method_ref_index_at(idx1); | ||
| int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2); | ||
| BSMAttributeEntry* e1 = bsm_attribute_entry(idx1); | ||
| BSMAttributeEntry* e2 = cp2->bsm_attribute_entry(idx2); | ||
| 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 = operand_argument_count_at(idx1); | ||
| if (argc == cp2->operand_argument_count_at(idx2)) { | ||
| int argc = e1->argument_count(); | ||
| if (argc == e2->argument_count()) { | ||
| for (int j = 0; j < argc; j++) { | ||
| k1 = operand_argument_index_at(idx1, j); | ||
| k2 = cp2->operand_argument_index_at(idx2, j); | ||
| k1 = e1->argument_index(j); | ||
| k2 = e2->argument_index(j); | ||
| match = compare_entry_to(k1, cp2, k2); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that's a good simplification. |
||
| if (!match) { | ||
| return false; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -77,6 +77,43 @@ class CPKlassSlot { | |
| } | ||
| }; | ||
|
|
||
| class BSMAttributeEntry { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This? Wouldn't it be better to leave it where it is, but add a comment ahead of the structure? |
||
| friend class ConstantPool; | ||
| u2 _bootstrap_method_index; | ||
| u2 _argument_count; | ||
|
|
||
| // The argument indexes are stored right after the object, in a contiguous array. | ||
| // [ bsmi_0 argc_0 arg_00 arg_01 ... arg_0N bsmi_1 argc_1 arg_10 ... arg_1N ... ] | ||
| // So in order to find the argument array, jump over ourselves. | ||
| const u2* argument_indexes() const { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| return reinterpret_cast<const u2*>(this + 1); | ||
| } | ||
| u2* argument_indexes() { | ||
| return reinterpret_cast<u2*>(this + 1); | ||
| } | ||
| // These are overlays on top of the operands array. Do not construct. | ||
| BSMAttributeEntry() = delete; | ||
|
|
||
| public: | ||
| // Offsets for SA | ||
| enum { | ||
| _bsmi_offset = 0, | ||
| _argc_offset = 1, | ||
| _argv_offset = 2 | ||
| }; | ||
|
|
||
| int bootstrap_method_index() const { | ||
| return _bootstrap_method_index; | ||
| } | ||
| int argument_count() const { | ||
| return _argument_count; | ||
| } | ||
| int argument_index(int n) const { | ||
| assert(checked_cast<u2>(n) < _argument_count, "oob"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so, it's a |
||
| return argument_indexes()[n]; | ||
| } | ||
| }; | ||
|
|
||
| class ConstantPool : public Metadata { | ||
| friend class VMStructs; | ||
| friend class JVMCIVMStructs; | ||
|
|
@@ -519,10 +556,6 @@ class ConstantPool : public Metadata { | |
| assert(tag_at(cp_index).has_bootstrap(), "Corrupted constant pool"); | ||
| return extract_low_short_from_int(*int_at_addr(cp_index)); | ||
| } | ||
| int bootstrap_operand_base(int cp_index) { | ||
| int bsms_attribute_index = bootstrap_methods_attribute_index(cp_index); | ||
| return operand_offset_at(operands(), bsms_attribute_index); | ||
| } | ||
| // 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. | ||
| static int operand_offset_at(Array<u2>* operands, int bsms_attribute_index) { | ||
|
|
@@ -560,47 +593,26 @@ class ConstantPool : public Metadata { | |
| else | ||
| return operand_offset_at(operands, nextidx); | ||
| } | ||
| int bootstrap_operand_limit(int cp_index) { | ||
| int bsms_attribute_index = bootstrap_methods_attribute_index(cp_index); | ||
| return operand_limit_at(operands(), bsms_attribute_index); | ||
| } | ||
| #endif //ASSERT | ||
|
|
||
| // Layout of InvokeDynamic and Dynamic bootstrap method specifier | ||
| // data in second part of operands array. This encodes one record in | ||
| // the BootstrapMethods attribute. The whole specifier also includes | ||
| // the name and type information from the main constant pool entry. | ||
| enum { | ||
| _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm | ||
| _indy_argc_offset = 1, // u2 argc | ||
| _indy_argv_offset = 2 // u2 argv[argc] | ||
| }; | ||
|
|
||
|
Comment on lines
-573
to
-578
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @plummercj , this is where the enum constants come from. |
||
| // These functions are used in RedefineClasses for CP merge | ||
|
|
||
| int operand_offset_at(int bsms_attribute_index) { | ||
| assert(0 <= bsms_attribute_index && | ||
| bsms_attribute_index < operand_array_length(operands()), | ||
| "Corrupted CP operands"); | ||
| return operand_offset_at(operands(), bsms_attribute_index); | ||
| } | ||
| u2 operand_bootstrap_method_ref_index_at(int bsms_attribute_index) { | ||
| int offset = operand_offset_at(bsms_attribute_index); | ||
| return operands()->at(offset + _indy_bsm_offset); | ||
| } | ||
| u2 operand_argument_count_at(int bsms_attribute_index) { | ||
| int offset = operand_offset_at(bsms_attribute_index); | ||
| u2 argc = operands()->at(offset + _indy_argc_offset); | ||
| return argc; | ||
| } | ||
| u2 operand_argument_index_at(int bsms_attribute_index, int j) { | ||
|
|
||
| BSMAttributeEntry* bsm_attribute_entry(int bsms_attribute_index) { | ||
| int offset = operand_offset_at(bsms_attribute_index); | ||
| return operands()->at(offset + _indy_argv_offset + j); | ||
| return reinterpret_cast<BSMAttributeEntry*>(operands()->adr_at(offset)); | ||
| } | ||
|
|
||
| int operand_next_offset_at(int bsms_attribute_index) { | ||
| int offset = operand_offset_at(bsms_attribute_index) + _indy_argv_offset | ||
| + operand_argument_count_at(bsms_attribute_index); | ||
| return offset; | ||
| BSMAttributeEntry* bsme = bsm_attribute_entry(bsms_attribute_index); | ||
| u2* argv_start = bsme->argument_indexes(); | ||
| int offset = argv_start - operands()->data(); | ||
| return offset + bsme->argument_count(); | ||
| } | ||
| // Compare a bootstrap specifier data in the operands arrays | ||
| bool compare_operand_to(int bsms_attribute_index1, const constantPoolHandle& cp2, | ||
|
|
@@ -617,23 +629,19 @@ class ConstantPool : public Metadata { | |
|
|
||
| u2 bootstrap_method_ref_index_at(int cp_index) { | ||
| assert(tag_at(cp_index).has_bootstrap(), "Corrupted constant pool"); | ||
| int op_base = bootstrap_operand_base(cp_index); | ||
| return operands()->at(op_base + _indy_bsm_offset); | ||
| int bsmai = bootstrap_methods_attribute_index(cp_index); | ||
| return bsm_attribute_entry(bsmai)->bootstrap_method_index(); | ||
| } | ||
| u2 bootstrap_argument_count_at(int cp_index) { | ||
| assert(tag_at(cp_index).has_bootstrap(), "Corrupted constant pool"); | ||
| int op_base = bootstrap_operand_base(cp_index); | ||
| u2 argc = operands()->at(op_base + _indy_argc_offset); | ||
| DEBUG_ONLY(int end_offset = op_base + _indy_argv_offset + argc; | ||
| 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); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! |
||
| return bsm_attribute_entry(bsmai)->argument_count(); | ||
| } | ||
| u2 bootstrap_argument_index_at(int cp_index, int j) { | ||
| int op_base = bootstrap_operand_base(cp_index); | ||
| DEBUG_ONLY(int argc = operands()->at(op_base + _indy_argc_offset)); | ||
| assert((uint)j < (uint)argc, "oob"); | ||
| return operands()->at(op_base + _indy_argv_offset + j); | ||
| int bsmai = bootstrap_methods_attribute_index(cp_index); | ||
| BSMAttributeEntry* bsme = bsm_attribute_entry(bsmai); | ||
| assert((uint)j < (uint)bsme->argument_count(), "oob"); | ||
| return bsm_attribute_entry(bsmai)->argument_index(j); | ||
| } | ||
|
|
||
| // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, | ||
|
|
||
There was a problem hiding this comment.
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_indexparameter can be replaced with absmeparameter.But this does not look that important at the moment.