RFR: 8367656: Refactor Constantpool's operand array into two [v5]
David Holmes
dholmes at openjdk.org
Fri Sep 19 02:48:27 UTC 2025
On Thu, 18 Sep 2025 07:41:31 GMT, Johan Sjölen <jsjolen at openjdk.org> wrote:
>> Hi,
>>
>> This is a refactoring of the way that we store the Bootstrap method attribute in the ConstantPool class. We used to have a single `Array<u2>` which was divided into a section of `u4` offsets and a section which was the actual data. In this refactoring we make this split more clear, by actually allocating an `Array<u4>` to store the offsets in and an `Array<u2>` to store the data in. These arrays are then put into a `BSMAttributeEntries` class, which allows us to separate out the API from that of the rest of the `ConstantPool`.
>>
>> We had multiple instances of the code knowing the layout of the operands array and using this to do 'clever' ways of copying and inserting data into it. See `ConstantPool::copy_operands` and `ConstantPool::resize_operands`. I felt like we could do things in a simpler way, so I added the `start_/end_extension` protocol and added the `InsertionIterator` for this. See `ClassFileParser::parse_classfile_bootstrap_methods_attribute` for how this works. I put several relevant definitions into the inline file in hopes of encouraging the compiler to optimize these appropriately.
>>
>> For the Java SA code, I had to add a `U4Array` class. I also had to fix the vmstructs definitions, etc.
>>
>> On the whole, while this code is a bit less terse, I think it's a good API improvement and the underlying implementation of splitting up the operands array is also an improvement.
>>
>> Testing: Oracle Tier1-Tier5 has been run succesfully multiple times. Before integration, I will merge with master and run these tiers again.
>
> Johan Sjölen has updated the pull request incrementally with one additional commit since the last revision:
>
> Fix rename
This looks good. I think it will be easier to understand for newcomers to the code.
One query: have you done any performance measurements for this change? I'm a little concerned that the insertion iterator and the internal array management is now more heavyweight than the old array management.
I don't understand the existing "operand" terminology and it seems even less appropriate now. It would be good to change this, but can be left for future RFE.
A number of nits, mainly indentation.
Thanks
src/hotspot/share/oops/constantPool.cpp line 1784:
> 1782: int k1 = from_cp->bootstrap_methods_attribute_index(from_i);
> 1783: int k2 = from_cp->bootstrap_name_and_type_ref_index_at(from_i);
> 1784: k1 += to_cp->bsm_entries().array_length(); // to_cp might already have operands
Here and below can we replace "operands" with something better? I didn't understand its use initially and now we don't have an operand array it seems even less informative.
src/hotspot/share/oops/constantPool.cpp line 2303:
> 2301: st->print("constant pool [%d]", length());
> 2302: if (has_preresolution()) st->print("/preresolution");
> 2303: if (!bsm_entries().is_empty()) st->print("/operands[%d]", bsm_entries().bootstrap_methods()->length());
Again is "operands" a meaningful description?
src/hotspot/share/oops/constantPool.cpp line 2358:
> 2356: InsertionIterator iter = start_extension(other.number_of_entries(), other.array_length(), loader_data, CHECK_(BSMAttributeEntries::InsertionIterator()));
> 2357: return iter;
> 2358: }
Suggestion:
BSMAttributeEntries::InsertionIterator
BSMAttributeEntries::start_extension(const BSMAttributeEntries& other, ClassLoaderData* loader_data, TRAPS) {
InsertionIterator iter = start_extension(other.number_of_entries(), other.array_length(),
loader_data, CHECK_(BSMAttributeEntries::InsertionIterator()));
return iter;
}
src/hotspot/share/oops/constantPool.cpp line 2362:
> 2360: BSMAttributeEntries::InsertionIterator
> 2361: BSMAttributeEntries::start_extension(int number_of_entries, int array_length,
> 2362: ClassLoaderData* loader_data, TRAPS) {
Suggestion:
ClassLoaderData* loader_data, TRAPS) {
Fix indent
src/hotspot/share/oops/constantPool.cpp line 2391:
> 2389: other.copy_into(iter, other.number_of_entries());
> 2390: end_extension(iter, loader_data, THREAD);
> 2391:
Suggestion:
src/hotspot/share/oops/constantPool.cpp line 2399:
> 2397: assert(iter._cur_array <= this->_bootstrap_methods->length(), "must be");
> 2398:
> 2399: // Did we fill up all of the available space? If so, do nothing
Suggestion:
// Did we fill up all of the available space? If so, do nothing.
src/hotspot/share/oops/constantPool.hpp line 665:
> 663: bool compare_bootstrap_entry_to(int bsms_attribute_index1, const constantPoolHandle& cp2,
> 664: int bsms_attribute_index2);
> 665: // Find a BSM entry in search_cp that matches the BSM at bsm_attribute_index
Suggestion:
// Find a BSM entry in search_cp that matches the BSM at bsm_attribute_index.
src/hotspot/share/oops/constantPool.hpp line 668:
> 666: // Return -1 if not found.
> 667: int find_matching_bsm_entry(int bsms_attribute_index, const constantPoolHandle& search_cp,
> 668: int offset_limit);
Suggestion:
int find_matching_bsm_entry(int bsms_attribute_index, const constantPoolHandle& search_cp,
int offset_limit);
Fix indent
src/hotspot/share/oops/constantPool.inline.hpp line 93:
> 91: inline BSMAttributeEntry* BSMAttributeEntries::InsertionIterator::reserve_new_entry(u2 bsmi, u2 argc) {
> 92: if (_cur_offset + 1 > insert_into->offsets()->length() ||
> 93: _cur_array + 1 + 1 + argc > insert_into->bootstrap_methods()->length()) {
The `+ 1 + 1 + argc` looks a little magical - can we factor it out and explain it e.g.
int next_array = _cur_array + 1 /* ??? */ + 1 /* ??? */ + argc;
...
_curr_array = next_array;
...
src/hotspot/share/prims/jvmtiRedefineClasses.cpp line 713:
> 711: // forward reference in *merge_cp_p or not a direct match
> 712: int found_i = scratch_cp->find_matching_bsm_entry(old_bs_i, *merge_cp_p,
> 713: max_offset_in_merge);
Suggestion:
int found_i = scratch_cp->find_matching_bsm_entry(old_bs_i, *merge_cp_p,
max_offset_in_merge);
Fix indent
src/hotspot/share/prims/jvmtiRedefineClasses.hpp line 451:
> 449: bool merge_constant_pools(const constantPoolHandle& old_cp,
> 450: const constantPoolHandle& scratch_cp, constantPoolHandle& merge_cp_p,
> 451: int& merge_cp_length_p, TRAPS);
Pre-existing but none of the line-wrapping indentation is correct in this section of the file.
-------------
PR Review: https://git.openjdk.org/jdk/pull/27198#pullrequestreview-3237461571
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361464715
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361479948
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361487875
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361489262
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361209369
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361210519
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361528513
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361225007
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361234056
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361542260
PR Review Comment: https://git.openjdk.org/jdk/pull/27198#discussion_r2361569102
More information about the serviceability-dev
mailing list