mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-13 12:38:07 +00:00
8357220: Introduce a BSMAttributeEntry struct
Co-authored-by: John R Rose <jrose@openjdk.org> Reviewed-by: sspitsyn, coleenp, matsaave
This commit is contained in:
parent
de34bb8e66
commit
3d35b408e1
@ -392,7 +392,7 @@ bool AOTConstantPoolResolver::check_lambda_metafactory_signature(ConstantPool* c
|
||||
}
|
||||
|
||||
bool AOTConstantPoolResolver::check_lambda_metafactory_methodtype_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) {
|
||||
int mt_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i);
|
||||
int mt_index = cp->bsm_attribute_entry(bsms_attribute_index)->argument_index(arg_i);
|
||||
if (!cp->tag_at(mt_index).is_method_type()) {
|
||||
// malformed class?
|
||||
return false;
|
||||
@ -408,7 +408,7 @@ bool AOTConstantPoolResolver::check_lambda_metafactory_methodtype_arg(ConstantPo
|
||||
}
|
||||
|
||||
bool AOTConstantPoolResolver::check_lambda_metafactory_methodhandle_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) {
|
||||
int mh_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i);
|
||||
int mh_index = cp->bsm_attribute_entry(bsms_attribute_index)->argument_index(arg_i);
|
||||
if (!cp->tag_at(mh_index).is_method_handle()) {
|
||||
// malformed class?
|
||||
return false;
|
||||
@ -514,7 +514,7 @@ bool AOTConstantPoolResolver::is_indy_resolution_deterministic(ConstantPool* cp,
|
||||
}
|
||||
|
||||
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();
|
||||
if (arg_count != 3) {
|
||||
// Malformed class?
|
||||
return false;
|
||||
|
||||
@ -1937,18 +1937,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);
|
||||
if (!match) {
|
||||
return false;
|
||||
|
||||
@ -77,6 +77,43 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class BSMAttributeEntry {
|
||||
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 {
|
||||
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");
|
||||
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]
|
||||
};
|
||||
|
||||
// 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) {
|
||||
|
||||
BSMAttributeEntry* bsm_attribute_entry(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) {
|
||||
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);
|
||||
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,
|
||||
|
||||
@ -396,7 +396,7 @@ void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
|
||||
// calculate length of attribute
|
||||
u4 length = sizeof(u2); // num_bootstrap_methods
|
||||
for (int n = 0; n < num_bootstrap_methods; n++) {
|
||||
u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
|
||||
u2 num_bootstrap_arguments = cpool()->bsm_attribute_entry(n)->argument_count();
|
||||
length += sizeof(u2); // bootstrap_method_ref
|
||||
length += sizeof(u2); // num_bootstrap_arguments
|
||||
length += (u4)sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
|
||||
@ -406,12 +406,12 @@ void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
|
||||
// write attribute
|
||||
write_u2(checked_cast<u2>(num_bootstrap_methods));
|
||||
for (int n = 0; n < num_bootstrap_methods; n++) {
|
||||
u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
|
||||
u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
|
||||
write_u2(bootstrap_method_ref);
|
||||
BSMAttributeEntry* bsme = cpool()->bsm_attribute_entry(n);
|
||||
u2 num_bootstrap_arguments = bsme->argument_count();
|
||||
write_u2(bsme->bootstrap_method_index());
|
||||
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 = bsme->argument_index(arg);
|
||||
write_u2(bootstrap_argument);
|
||||
}
|
||||
}
|
||||
|
||||
@ -659,10 +659,11 @@ u2 VM_RedefineClasses::find_or_append_indirect_entry(const constantPoolHandle& s
|
||||
// Append a bootstrap specifier into the merge_cp operands that is semantically equal
|
||||
// to the scratch_cp operands bootstrap specifier passed by the old_bs_i index.
|
||||
// Recursively append new merge_cp entries referenced by the new bootstrap specifier.
|
||||
void VM_RedefineClasses::append_operand(const constantPoolHandle& scratch_cp, int old_bs_i,
|
||||
void VM_RedefineClasses::append_operand(const constantPoolHandle& scratch_cp, const int old_bs_i,
|
||||
constantPoolHandle *merge_cp_p, int *merge_cp_length_p) {
|
||||
|
||||
u2 old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i);
|
||||
BSMAttributeEntry* old_bsme = scratch_cp->bsm_attribute_entry(old_bs_i);
|
||||
u2 old_ref_i = old_bsme->bootstrap_method_index();
|
||||
u2 new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p,
|
||||
merge_cp_length_p);
|
||||
if (new_ref_i != old_ref_i) {
|
||||
@ -676,14 +677,14 @@ void VM_RedefineClasses::append_operand(const constantPoolHandle& scratch_cp, in
|
||||
// However, the operand_offset_at(0) was set in the extend_operands() call.
|
||||
int new_base = (new_bs_i == 0) ? (*merge_cp_p)->operand_offset_at(0)
|
||||
: (*merge_cp_p)->operand_next_offset_at(new_bs_i - 1);
|
||||
u2 argc = scratch_cp->operand_argument_count_at(old_bs_i);
|
||||
u2 argc = old_bsme->argument_count();
|
||||
|
||||
ConstantPool::operand_offset_at_put(merge_ops, _operands_cur_length, new_base);
|
||||
merge_ops->at_put(new_base++, new_ref_i);
|
||||
merge_ops->at_put(new_base++, argc);
|
||||
|
||||
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 = old_bsme->argument_index(i);
|
||||
u2 new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p,
|
||||
merge_cp_length_p);
|
||||
merge_ops->at_put(new_base++, new_arg_ref_i);
|
||||
|
||||
@ -1483,13 +1483,13 @@
|
||||
\
|
||||
declare_constant(Symbol::max_symbol_length) \
|
||||
\
|
||||
/***********************************************/ \
|
||||
/* ConstantPool* layout enum for InvokeDynamic */ \
|
||||
/***********************************************/ \
|
||||
/******************************************************/ \
|
||||
/* BSMAttributeEntry* - layout enum for InvokeDynamic */ \
|
||||
/******************************************************/ \
|
||||
\
|
||||
declare_constant(ConstantPool::_indy_bsm_offset) \
|
||||
declare_constant(ConstantPool::_indy_argc_offset) \
|
||||
declare_constant(ConstantPool::_indy_argv_offset) \
|
||||
declare_constant(BSMAttributeEntry::_bsmi_offset) \
|
||||
declare_constant(BSMAttributeEntry::_argc_offset) \
|
||||
declare_constant(BSMAttributeEntry::_argv_offset) \
|
||||
\
|
||||
/***************************************/ \
|
||||
/* JavaThreadStatus enum */ \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -100,9 +100,9 @@ public class ConstantPool extends Metadata implements ClassConstants {
|
||||
headerSize = type.getSize();
|
||||
elementSize = 0;
|
||||
// fetch constants:
|
||||
INDY_BSM_OFFSET = db.lookupIntConstant("ConstantPool::_indy_bsm_offset").intValue();
|
||||
INDY_ARGC_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argc_offset").intValue();
|
||||
INDY_ARGV_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argv_offset").intValue();
|
||||
INDY_BSM_OFFSET = db.lookupIntConstant("BSMAttributeEntry::_bsmi_offset").intValue();
|
||||
INDY_ARGC_OFFSET = db.lookupIntConstant("BSMAttributeEntry::_argc_offset").intValue();
|
||||
INDY_ARGV_OFFSET = db.lookupIntConstant("BSMAttributeEntry::_argv_offset").intValue();
|
||||
}
|
||||
|
||||
public ConstantPool(Address addr) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user