4848#include " memory/universe.hpp"
4949#include " oops/annotations.hpp"
5050#include " oops/constantPool.inline.hpp"
51+ #include " oops/fieldInfo.hpp"
5152#include " oops/fieldStreams.inline.hpp"
5253#include " oops/instanceKlass.inline.hpp"
5354#include " oops/instanceMirrorKlass.hpp"
@@ -1471,7 +1472,6 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
14711472 assert (cp != nullptr , " invariant" );
14721473 assert (java_fields_count_ptr != nullptr , " invariant" );
14731474
1474- assert (nullptr == _fields, " invariant" );
14751475 assert (nullptr == _fields_annotations, " invariant" );
14761476 assert (nullptr == _fields_type_annotations, " invariant" );
14771477
@@ -1484,34 +1484,11 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
14841484 &num_injected);
14851485 const int total_fields = length + num_injected;
14861486
1487- // The field array starts with tuples of shorts
1488- // [access, name index, sig index, initial value index, byte offset].
1489- // A generic signature slot only exists for field with generic
1490- // signature attribute. And the access flag is set with
1491- // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic
1492- // signature slots are at the end of the field array and after all
1493- // other fields data.
1494- //
1495- // f1: [access, name index, sig index, initial value index, low_offset, high_offset]
1496- // f2: [access, name index, sig index, initial value index, low_offset, high_offset]
1497- // ...
1498- // fn: [access, name index, sig index, initial value index, low_offset, high_offset]
1499- // [generic signature index]
1500- // [generic signature index]
1501- // ...
1502- //
1503- // Allocate a temporary resource array for field data. For each field,
1504- // a slot is reserved in the temporary array for the generic signature
1505- // index. After parsing all fields, the data are copied to a permanent
1506- // array and any unused slots will be discarded.
1507- ResourceMark rm (THREAD);
1508- u2* const fa = NEW_RESOURCE_ARRAY_IN_THREAD (THREAD,
1509- u2,
1510- total_fields * (FieldInfo::field_slots + 1 ));
1487+ // Allocate a temporary resource array to collect field data.
1488+ // After parsing all fields, data are stored in a UNSIGNED5 compressed stream.
1489+ _temp_field_info = new GrowableArray<FieldInfo>(total_fields);
15111490
1512- // The generic signature slots start after all other fields' data.
1513- int generic_signature_slot = total_fields * FieldInfo::field_slots;
1514- int num_generic_signature = 0 ;
1491+ ResourceMark rm (THREAD);
15151492 for (int n = 0 ; n < length; n++) {
15161493 // access_flags, name_index, descriptor_index, attributes_count
15171494 cfs->guarantee_more (8 , CHECK);
@@ -1520,6 +1497,7 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
15201497 const jint flags = cfs->get_u2_fast () & JVM_RECOGNIZED_FIELD_MODIFIERS;
15211498 verify_legal_field_modifiers (flags, is_interface, CHECK);
15221499 access_flags.set_flags (flags);
1500+ FieldInfo::FieldFlags fieldFlags (0 );
15231501
15241502 const u2 name_index = cfs->get_u2_fast ();
15251503 check_property (valid_symbol_at (name_index),
@@ -1578,31 +1556,27 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
15781556 access_flags.set_is_synthetic ();
15791557 }
15801558 if (generic_signature_index != 0 ) {
1581- access_flags.set_field_has_generic_signature ();
1582- fa[generic_signature_slot] = generic_signature_index;
1583- generic_signature_slot ++;
1584- num_generic_signature ++;
1559+ fieldFlags.update_generic (true );
15851560 }
15861561 }
15871562
1588- FieldInfo* const field = FieldInfo::from_field_array (fa, n);
1589- field->initialize (access_flags.as_short (),
1590- name_index,
1591- signature_index,
1592- constantvalue_index);
15931563 const BasicType type = cp->basic_type_for_signature_at (signature_index);
15941564
15951565 // Update FieldAllocationCount for this kind of field
15961566 fac->update (is_static, type);
15971567
1598- // After field is initialized with type, we can augment it with aux info
1599- if (parsed_annotations.has_any_annotations ()) {
1600- parsed_annotations.apply_to (field);
1601- if (field->is_contended ()) {
1602- _has_contended_fields = true ;
1603- }
1568+ FieldInfo fi (access_flags, name_index, signature_index, constantvalue_index, fieldFlags);
1569+ fi.set_index (n);
1570+ if (fieldFlags.is_generic ()) {
1571+ fi.set_generic_signature_index (generic_signature_index);
16041572 }
1573+ parsed_annotations.apply_to (&fi);
1574+ if (fi.field_flags ().is_contended ()) {
1575+ _has_contended_fields = true ;
1576+ }
1577+ _temp_field_info->append (fi);
16051578 }
1579+ assert (_temp_field_info->length () == length, " Must be" );
16061580
16071581 int index = length;
16081582 if (num_injected != 0 ) {
@@ -1613,7 +1587,7 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
16131587 const Symbol* const signature = injected[n].signature ();
16141588 bool duplicate = false ;
16151589 for (int i = 0 ; i < length; i++) {
1616- const FieldInfo* const f = FieldInfo::from_field_array (fa, i);
1590+ const FieldInfo* const f = _temp_field_info-> adr_at ( i);
16171591 if (name == cp->symbol_at (f->name_index ()) &&
16181592 signature == cp->symbol_at (f->signature_index ())) {
16191593 // Symbol is desclared in Java so skip this one
@@ -1628,41 +1602,21 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
16281602 }
16291603
16301604 // Injected field
1631- FieldInfo* const field = FieldInfo::from_field_array (fa, index);
1632- field->initialize ((u2)JVM_ACC_FIELD_INTERNAL,
1633- (u2)(injected[n].name_index ),
1634- (u2)(injected[n].signature_index ),
1635- 0 );
1636-
1637- const BasicType type = Signature::basic_type (injected[n].signature ());
1605+ FieldInfo::FieldFlags fflags (0 );
1606+ fflags.update_injected (true );
1607+ AccessFlags aflags;
1608+ FieldInfo fi (aflags, (u2)(injected[n].name_index ), (u2)(injected[n].signature_index ), 0 , fflags);
1609+ fi.set_index (index);
1610+ _temp_field_info->append (fi);
16381611
16391612 // Update FieldAllocationCount for this kind of field
1613+ const BasicType type = Signature::basic_type (injected[n].signature ());
16401614 fac->update (false , type);
16411615 index++;
16421616 }
16431617 }
16441618
1645- assert (nullptr == _fields, " invariant" );
1646-
1647- _fields =
1648- MetadataFactory::new_array<u2>(_loader_data,
1649- index * FieldInfo::field_slots + num_generic_signature,
1650- CHECK);
1651- // Sometimes injected fields already exist in the Java source so
1652- // the fields array could be too long. In that case the
1653- // fields array is trimmed. Also unused slots that were reserved
1654- // for generic signature indexes are discarded.
1655- {
1656- int i = 0 ;
1657- for (; i < index * FieldInfo::field_slots; i++) {
1658- _fields->at_put (i, fa[i]);
1659- }
1660- for (int j = total_fields * FieldInfo::field_slots;
1661- j < generic_signature_slot; j++) {
1662- _fields->at_put (i++, fa[j]);
1663- }
1664- assert (_fields->length () == i, " " );
1665- }
1619+ assert (_temp_field_info->length () == index, " Must be" );
16661620
16671621 if (_need_verify && length > 1 ) {
16681622 // Check duplicated fields
@@ -1675,9 +1629,9 @@ void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
16751629 const Symbol* sig = nullptr ;
16761630 {
16771631 debug_only (NoSafepointVerifier nsv;)
1678- for (AllFieldStream fs (_fields, cp); !fs. done (); fs. next () ) {
1679- name = fs. name ();
1680- sig = fs. signature ();
1632+ for (int i = 0 ; i < _temp_field_info-> length (); i++ ) {
1633+ name = _temp_field_info-> adr_at (i)-> name (_cp );
1634+ sig = _temp_field_info-> adr_at (i)-> signature (_cp );
16811635 // If no duplicates, add name/signature in hashtable names_and_sigs.
16821636 if (!put_after_lookup (name, sig, names_and_sigs)) {
16831637 dup = true ;
@@ -2055,9 +2009,10 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
20552009
20562010void ClassFileParser::FieldAnnotationCollector::apply_to (FieldInfo* f) {
20572011 if (is_contended ())
2012+ // Setting the contended group also sets the contended bit in field flags
20582013 f->set_contended_group (contended_group ());
20592014 if (is_stable ())
2060- f->set_stable (true );
2015+ ( f->field_flags_addr ())-> update_stable (true );
20612016}
20622017
20632018ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector () {
@@ -3969,7 +3924,8 @@ void ClassFileParser::apply_parsed_class_metadata(
39693924
39703925 _cp->set_pool_holder (this_klass);
39713926 this_klass->set_constants (_cp);
3972- this_klass->set_fields (_fields, java_fields_count);
3927+ this_klass->set_fieldinfo_stream (_fieldinfo_stream);
3928+ this_klass->set_fields_status (_fields_status);
39733929 this_klass->set_methods (_methods);
39743930 this_klass->set_inner_classes (_inner_classes);
39753931 this_klass->set_nest_members (_nest_members);
@@ -5316,7 +5272,8 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
53165272
53175273 // note that is not safe to use the fields in the parser from this point on
53185274 assert (nullptr == _cp, " invariant" );
5319- assert (nullptr == _fields, " invariant" );
5275+ assert (nullptr == _fieldinfo_stream, " invariant" );
5276+ assert (nullptr == _fields_status, " invariant" );
53205277 assert (nullptr == _methods, " invariant" );
53215278 assert (nullptr == _inner_classes, " invariant" );
53225279 assert (nullptr == _nest_members, " invariant" );
@@ -5548,7 +5505,8 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
55485505 _orig_cp_size(0 ),
55495506 _super_klass(),
55505507 _cp(nullptr ),
5551- _fields(nullptr ),
5508+ _fieldinfo_stream(nullptr ),
5509+ _fields_status(nullptr ),
55525510 _methods(nullptr ),
55535511 _inner_classes(nullptr ),
55545512 _nest_members(nullptr ),
@@ -5567,6 +5525,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
55675525 _parsed_annotations(nullptr ),
55685526 _fac(nullptr ),
55695527 _field_info(nullptr ),
5528+ _temp_field_info(nullptr ),
55705529 _method_ordering(nullptr ),
55715530 _all_mirandas(nullptr ),
55725531 _vtable_size(0 ),
@@ -5638,7 +5597,8 @@ void ClassFileParser::clear_class_metadata() {
56385597 // metadata created before the instance klass is created. Must be
56395598 // deallocated if classfile parsing returns an error.
56405599 _cp = nullptr ;
5641- _fields = nullptr ;
5600+ _fieldinfo_stream = nullptr ;
5601+ _fields_status = nullptr ;
56425602 _methods = nullptr ;
56435603 _inner_classes = nullptr ;
56445604 _nest_members = nullptr ;
@@ -5656,8 +5616,13 @@ ClassFileParser::~ClassFileParser() {
56565616 if (_cp != nullptr ) {
56575617 MetadataFactory::free_metadata (_loader_data, _cp);
56585618 }
5659- if (_fields != nullptr ) {
5660- MetadataFactory::free_array<u2>(_loader_data, _fields);
5619+
5620+ if (_fieldinfo_stream != nullptr ) {
5621+ MetadataFactory::free_array<u1>(_loader_data, _fieldinfo_stream);
5622+ }
5623+
5624+ if (_fields_status != nullptr ) {
5625+ MetadataFactory::free_array<FieldStatus>(_loader_data, _fields_status);
56615626 }
56625627
56635628 if (_methods != nullptr ) {
@@ -5894,7 +5859,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
58945859 &_java_fields_count,
58955860 CHECK);
58965861
5897- assert (_fields != nullptr , " invariant" );
5862+ assert (_temp_field_info != nullptr , " invariant" );
58985863
58995864 // Methods
59005865 parse_methods (stream,
@@ -6050,9 +6015,17 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st
60506015 assert (_parsed_annotations != nullptr , " invariant" );
60516016
60526017 _field_info = new FieldLayoutInfo ();
6053- FieldLayoutBuilder lb (class_name (), super_klass (), _cp, _fields,
6018+ FieldLayoutBuilder lb (class_name (), super_klass (), _cp, /* _fields*/ _temp_field_info ,
60546019 _parsed_annotations->is_contended (), _field_info);
60556020 lb.build_layout ();
6021+
6022+ int injected_fields_count = _temp_field_info->length () - _java_fields_count;
6023+ _fieldinfo_stream =
6024+ FieldInfoStream::create_FieldInfoStream (_temp_field_info, _java_fields_count,
6025+ injected_fields_count, loader_data (), CHECK);
6026+ _fields_status =
6027+ MetadataFactory::new_array<FieldStatus>(_loader_data, _temp_field_info->length (),
6028+ FieldStatus (0 ), CHECK);
60566029}
60576030
60586031void ClassFileParser::set_klass (InstanceKlass* klass) {
0 commit comments