Skip to content

Commit 1c44a2b

Browse files
committed
simplify bootstrap method logic (first cut)
1 parent 13b3541 commit 1c44a2b

25 files changed

+667
-610
lines changed

src/hotspot/share/cds/aotConstantPoolResolver.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ bool AOTConstantPoolResolver::check_lambda_metafactory_signature(ConstantPool* c
392392
}
393393

394394
bool AOTConstantPoolResolver::check_lambda_metafactory_methodtype_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) {
395-
int mt_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i);
395+
int mt_index = cp->bsm_attribute_entry(bsms_attribute_index)->argument_index(arg_i);
396396
if (!cp->tag_at(mt_index).is_method_type()) {
397397
// malformed class?
398398
return false;
@@ -408,7 +408,7 @@ bool AOTConstantPoolResolver::check_lambda_metafactory_methodtype_arg(ConstantPo
408408
}
409409

410410
bool AOTConstantPoolResolver::check_lambda_metafactory_methodhandle_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) {
411-
int mh_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i);
411+
int mh_index = cp->bsm_attribute_entry(bsms_attribute_index)->argument_index(arg_i);
412412
if (!cp->tag_at(mh_index).is_method_handle()) {
413413
// malformed class?
414414
return false;
@@ -433,7 +433,8 @@ bool AOTConstantPoolResolver::is_indy_resolution_deterministic(ConstantPool* cp,
433433
return false;
434434
}
435435

436-
int bsm = cp->bootstrap_method_ref_index_at(cp_index);
436+
int bsms_attribute_index = cp->bootstrap_methods_attribute_index(cp_index);
437+
int bsm = cp->bsm_attribute_entry(bsms_attribute_index)->bootstrap_method_index();
437438
int bsm_ref = cp->method_handle_index_at(bsm);
438439
Symbol* bsm_name = cp->uncached_name_ref_at(bsm_ref);
439440
Symbol* bsm_signature = cp->uncached_signature_ref_at(bsm_ref);
@@ -513,8 +514,7 @@ bool AOTConstantPoolResolver::is_indy_resolution_deterministic(ConstantPool* cp,
513514
return false;
514515
}
515516

516-
int bsms_attribute_index = cp->bootstrap_methods_attribute_index(cp_index);
517-
int arg_count = cp->operand_argument_count_at(bsms_attribute_index);
517+
int arg_count = cp->bsm_attribute_entry(bsms_attribute_index)->argument_count();
518518
if (arg_count != 3) {
519519
// Malformed class?
520520
return false;

src/hotspot/share/cds/classListParser.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -570,23 +570,22 @@ void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int
570570
cii->add_item(pool->symbol_at(name_index)->as_C_string());
571571
int sig_index = pool->signature_ref_index_at(type_index);
572572
cii->add_item(pool->symbol_at(sig_index)->as_C_string());
573-
int argc = pool->bootstrap_argument_count_at(cp_index);
574-
if (argc > 0) {
575-
for (int arg_i = 0; arg_i < argc; arg_i++) {
576-
int arg = pool->bootstrap_argument_index_at(cp_index, arg_i);
577-
jbyte tag = pool->tag_at(arg).value();
578-
if (tag == JVM_CONSTANT_MethodType) {
579-
cii->add_item(pool->method_type_signature_at(arg)->as_C_string());
580-
} else if (tag == JVM_CONSTANT_MethodHandle) {
581-
cii->add_ref_kind(pool->method_handle_ref_kind_at(arg));
582-
int callee_index = pool->method_handle_klass_index_at(arg);
583-
Klass* callee = pool->klass_at(callee_index, CHECK);
584-
cii->add_item(callee->name()->as_C_string());
585-
cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string());
586-
cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string());
587-
} else {
588-
ShouldNotReachHere();
589-
}
573+
BSMAttributeEntry* bsme = pool->bootstrap_methods_attribute_entry(cp_index);
574+
int argc = bsme->argument_count();
575+
for (int arg_i = 0; arg_i < argc; arg_i++) {
576+
int arg = bsme->argument_index(arg_i);
577+
jbyte tag = pool->tag_at(arg).value();
578+
if (tag == JVM_CONSTANT_MethodType) {
579+
cii->add_item(pool->method_type_signature_at(arg)->as_C_string());
580+
} else if (tag == JVM_CONSTANT_MethodHandle) {
581+
cii->add_ref_kind(pool->method_handle_ref_kind_at(arg));
582+
int callee_index = pool->method_handle_klass_index_at(arg);
583+
Klass* callee = pool->klass_at(callee_index, CHECK);
584+
cii->add_item(callee->name()->as_C_string());
585+
cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string());
586+
cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string());
587+
} else {
588+
ShouldNotReachHere();
590589
}
591590
}
592591
}

src/hotspot/share/ci/ciEnv.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,8 @@ ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
821821
// Patch the call site to the nmethod entry point of the static compiled lambda form.
822822
// As with other two-component call sites, both values must be independently verified.
823823
assert(index < cpool->cache()->resolved_indy_entries_length(), "impossible");
824-
Method* adapter = cpool->resolved_indy_entry_at(index)->method();
824+
ResolvedIndyEntry* rie = cpool->resolved_indy_entry_at(index);
825+
Method* adapter = rie->method();
825826
// Resolved if the adapter is non null.
826827
if (adapter != nullptr) {
827828
return get_method(adapter);
@@ -830,7 +831,7 @@ ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
830831
// Fake a method that is equivalent to a declared method.
831832
ciInstanceKlass* holder = get_instance_klass(vmClasses::MethodHandle_klass());
832833
ciSymbol* name = ciSymbols::invokeBasic_name();
833-
ciSymbol* signature = get_symbol(cpool->signature_ref_at(index, bc));
834+
ciSymbol* signature = get_symbol(rie->signature(cpool()));
834835
return get_unloaded_method(holder, name, signature, accessor);
835836
} else {
836837
const int holder_index = cpool->klass_ref_index_at(index, bc);

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,7 +2104,6 @@ void ClassFileParser::copy_method_annotations(ConstMethod* cm,
21042104
}
21052105
}
21062106

2107-
21082107
// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
21092108
// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
21102109
// Method* to save footprint, so we only know the size of the resulting Method* when the
@@ -3280,70 +3279,94 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(const ClassFil
32803279

32813280
cfs->guarantee_more(attribute_byte_length, CHECK);
32823281

3283-
const int attribute_array_length = cfs->get_u2_fast();
3282+
const u2 num_bootstrap_methods = cfs->get_u2_fast();
32843283

3285-
guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
3284+
guarantee_property(_max_bootstrap_specifier_index < num_bootstrap_methods,
32863285
"Short length on BootstrapMethods in class file %s",
32873286
CHECK);
32883287

3289-
32903288
// The attribute contains a counted array of counted tuples of shorts,
3291-
// represending bootstrap specifiers:
3292-
// length*{bootstrap_method_index, argument_count*{argument_index}}
3293-
const unsigned int operand_count = (attribute_byte_length - (unsigned)sizeof(u2)) / (unsigned)sizeof(u2);
3294-
// operand_count = number of shorts in attr, except for leading length
3295-
3296-
// The attribute is copied into a short[] array.
3297-
// The array begins with a series of short[2] pairs, one for each tuple.
3298-
const int index_size = (attribute_array_length * 2);
3299-
3300-
Array<u2>* const operands =
3301-
MetadataFactory::new_array<u2>(_loader_data, index_size + operand_count, CHECK);
3302-
3303-
// Eagerly assign operands so they will be deallocated with the constant
3304-
// pool if there is an error.
3305-
cp->set_operands(operands);
3306-
3307-
int operand_fill_index = index_size;
3289+
// representing bootstrap specifiers:
3290+
// length*{bootstrap_method_index, argument_count, argument_count*{argument_index}}
3291+
const u4 attribute_tail_length = attribute_byte_length - static_cast<u4>(sizeof(u2));
3292+
assert(attribute_tail_length % sizeof(u2) == 0, "");
3293+
Array<u4>* const offsets =
3294+
MetadataFactory::new_array<u4>(_loader_data, num_bootstrap_methods, CHECK);
3295+
Array<u2>* const entries = // u2 data holding all the BSM attribute entries
3296+
MetadataFactory::new_array<u2>(_loader_data, attribute_tail_length / sizeof(u2), CHECK);
3297+
3298+
// Eagerly assign arrays so they will be deallocated with
3299+
// the constant pool if there is an error.
3300+
cp->set_bsm_attribute_offsets(offsets);
3301+
cp->set_bsm_attribute_entries(entries);
3302+
3303+
int next_entry = 0;
33083304
const int cp_size = cp->length();
33093305

3310-
for (int n = 0; n < attribute_array_length; n++) {
3311-
// Store a 32-bit offset into the header of the operand array.
3312-
ConstantPool::operand_offset_at_put(operands, n, operand_fill_index);
3306+
for (int n = 0; n < num_bootstrap_methods; n++) {
3307+
// Store a 32-bit offset into the array of BSM entry offsets.
3308+
offsets->at_put(n, next_entry);
33133309

3314-
// Read a bootstrap specifier.
3310+
// Read a bootstrap method attribute entry.
33153311
cfs->guarantee_more(sizeof(u2) * 2, CHECK); // bsm, argc
3316-
const u2 bootstrap_method_index = cfs->get_u2_fast();
3317-
const u2 argument_count = cfs->get_u2_fast();
3312+
const u2 bootstrap_method_ref = cfs->get_u2_fast();
3313+
const u2 num_bootstrap_arguments = cfs->get_u2_fast();
33183314
guarantee_property(
3319-
valid_cp_range(bootstrap_method_index, cp_size) &&
3320-
cp->tag_at(bootstrap_method_index).is_method_handle(),
3315+
valid_cp_range(bootstrap_method_ref, cp_size) &&
3316+
cp->tag_at(bootstrap_method_ref).is_method_handle(),
33213317
"bootstrap_method_index %u has bad constant type in class file %s",
3322-
bootstrap_method_index,
3318+
bootstrap_method_ref,
33233319
CHECK);
33243320

3325-
guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(),
3321+
guarantee_property((next_entry + 2 + num_bootstrap_arguments) <= entries->length(),
33263322
"Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s",
33273323
CHECK);
33283324

3329-
operands->at_put(operand_fill_index++, bootstrap_method_index);
3330-
operands->at_put(operand_fill_index++, argument_count);
3325+
entries->at_put(next_entry, bootstrap_method_ref);
3326+
next_entry++;
3327+
entries->at_put(next_entry, num_bootstrap_arguments);
3328+
next_entry++;
33313329

3332-
cfs->guarantee_more(sizeof(u2) * argument_count, CHECK); // argv[argc]
3333-
for (int j = 0; j < argument_count; j++) {
3330+
cfs->guarantee_more(sizeof(u2) * num_bootstrap_arguments, CHECK); // argv[argc]
3331+
for (u2 j = 0; j < num_bootstrap_arguments; j++) {
33343332
const u2 argument_index = cfs->get_u2_fast();
33353333
guarantee_property(
33363334
valid_cp_range(argument_index, cp_size) &&
33373335
cp->tag_at(argument_index).is_loadable_constant(),
33383336
"argument_index %u has bad constant type in class file %s",
33393337
argument_index,
33403338
CHECK);
3341-
operands->at_put(operand_fill_index++, argument_index);
3339+
entries->at_put(next_entry, argument_index);
3340+
next_entry++;
33423341
}
33433342
}
33443343
guarantee_property(current_start + attribute_byte_length == cfs->current(),
33453344
"Bad length on BootstrapMethods in class file %s",
33463345
CHECK);
3346+
assert(next_entry == entries->length(), "");
3347+
3348+
#ifdef ASSERT
3349+
if (num_bootstrap_methods > 0) {
3350+
BSMAttributeEntry* bsme = cp->bsm_attribute_entry(0);
3351+
assert(bsme->bootstrap_method_index() == entries->at(0), "");
3352+
assert(bsme->argument_count() == entries->at(1), "");
3353+
int nexti = (num_bootstrap_methods == 1) ? entries->length() : offsets->at(1);
3354+
assert(nexti == 2 + bsme->argument_count(), "");
3355+
if (num_bootstrap_methods > 1) {
3356+
bsme = cp->bsm_attribute_entry(1);
3357+
assert(bsme->bootstrap_method_index() == entries->at(nexti+0), "");
3358+
assert(bsme->argument_count() == entries->at(nexti+1), "");
3359+
}
3360+
int lasti = offsets->at(offsets->length() - 1);
3361+
bsme = cp->bsm_attribute_entry(num_bootstrap_methods - 1);
3362+
assert(bsme->bootstrap_method_index() == entries->at(lasti+0), "");
3363+
assert(bsme->argument_count() == entries->at(lasti+1), "");
3364+
int lastu2 = entries->at(entries->length() - 1);
3365+
int lastac = bsme->argument_count();
3366+
int expect_lastu2 = (lastac == 0) ? 0 : bsme->argument_index(lastac-1);
3367+
assert(lastu2 == expect_lastu2, "");
3368+
}
3369+
#endif
33473370
}
33483371

33493372
void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cfs,

src/hotspot/share/classfile/verifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2808,9 +2808,9 @@ void ClassVerifier::verify_invoke_instructions(
28082808
default:
28092809
types = 1 << JVM_CONSTANT_Methodref;
28102810
}
2811-
verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this));
28122811

28132812
// Get method name and signature
2813+
verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this));
28142814
Symbol* method_name = cp->uncached_name_ref_at(index);
28152815
Symbol* method_sig = cp->uncached_signature_ref_at(index);
28162816

0 commit comments

Comments
 (0)