< prev index next >
hotspot/src/share/vm/classfile/classFileParser.cpp
Print this page
@@ -1467,10 +1467,32 @@
assert(count[atype] < 0xFFFF, "More than 65535 fields");
count[atype]++;
}
return atype;
}
+
+ // Attempt to redistribute NONSTATIC_VALUETYPE alloc type
+ FieldAllocationType redistribute_value(bool oops, int value_size) {
+ FieldAllocationType atype = NONSTATIC_VALUETYPE;
+ switch (value_size) {
+ case 1:
+ atype = NONSTATIC_BYTE;
+ break;
+ case 2:
+ atype = NONSTATIC_SHORT;
+ break;
+ case 4:
+ atype = (oops) ? NONSTATIC_OOP : NONSTATIC_WORD;
+ break;
+ default:
+ assert(is_size_aligned(value_size, BytesPerLong), "Unaligned value %d", value_size);
+ return atype;
+ }
+ count[atype]++;
+ count[NONSTATIC_VALUETYPE]--; // Leave only large variable sized behind
+ return atype;
+ }
};
// Side-effects: populates the _fields, _fields_annotations,
// _fields_type_annotations fields
void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
@@ -3810,11 +3832,11 @@
}
}
// Layout fields and fill in FieldLayoutInfo. Could use more refactoring!
void ClassFileParser::layout_fields(ConstantPool* cp,
- const FieldAllocationCount* fac,
+ FieldAllocationCount* fac,
const ClassAnnotationCollector* parsed_annotations,
FieldLayoutInfo* info,
TRAPS) {
assert(cp != NULL, "invariant");
@@ -3833,18 +3855,44 @@
//
// We ignore static fields, because @Contended is not supported for them.
// The layout code below will also ignore the static fields.
int nonstatic_contended_count = 0;
FieldAllocationCount fac_contended;
+
+ // Redistribute value types if possible, gather their klasses, oopmap count...
+ unsigned int value_type_oop_map_count = 0;
+ int large_value_count = 0;
+ ValueKlass** nonstatic_value_type_klasses =
+ NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, ValueKlass*, fac->count[NONSTATIC_VALUETYPE]);
+
for (AllFieldStream fs(_fields, cp); !fs.done(); fs.next()) {
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
if (fs.is_contended()) {
fac_contended.count[atype]++;
if (!fs.access_flags().is_static()) {
nonstatic_contended_count++;
}
}
+ else if (atype == NONSTATIC_VALUETYPE) {
+ Symbol* signature = fs.signature();
+ Klass* klass = SystemDictionary::resolve_or_fail(signature,
+ Handle(THREAD, _loader_data->class_loader()),
+ _protection_domain, true, CHECK);
+ assert(klass != NULL && klass->access_flags().is_value_type(), "Sanity check");
+ ValueKlass* vklass = ValueKlass::cast(klass);
+ if (vklass->contains_oops()) {
+ value_type_oop_map_count += vklass->nonstatic_oop_map_count();
+ }
+ int raw_value_size = vklass->raw_value_byte_size();
+ FieldAllocationType atype = fac->redistribute_value(vklass->contains_oops(), raw_value_size);
+ if (atype == NONSTATIC_VALUETYPE) {
+ // Failed to slot in with the others, allocate large values last jlong align for safe copy
+ nonstatic_value_type_klasses[large_value_count++] = vklass;
+ } else {
+ fs.coerce_allocation_type(NONSTATIC_VALUETYPE, (int) atype);
+ }
+ }
}
// Calculate the starting byte offsets
int next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
@@ -3901,47 +3949,11 @@
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
-
- int static_value_type_count = 0;
- int nonstatic_value_type_count = 0;
- int* nonstatic_value_type_indexes = NULL;
- Klass** nonstatic_value_type_klasses = NULL;
- unsigned int value_type_oop_map_count = 0;
-
- int max_nonstatic_value_type = fac->count[NONSTATIC_VALUETYPE] + 1;
-
- nonstatic_value_type_indexes = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, int,
- max_nonstatic_value_type);
- for (int i = 0; i < max_nonstatic_value_type; i++) {
- nonstatic_value_type_indexes[i] = -1;
- }
- nonstatic_value_type_klasses = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, Klass*,
- max_nonstatic_value_type);
-
- for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) {
- if (fs.allocation_type() == STATIC_VALUETYPE) {
- static_value_type_count++;
- } else if (fs.allocation_type() == NONSTATIC_VALUETYPE) {
- Symbol* signature = fs.signature();
- Klass* klass = SystemDictionary::resolve_or_fail(signature,
- Handle(THREAD, _loader_data->class_loader()),
- _protection_domain, true, CHECK);
- assert(klass != NULL, "Sanity check");
- assert(klass->access_flags().is_value_type(), "Value type expected");
- nonstatic_value_type_indexes[nonstatic_value_type_count] = fs.index();
- nonstatic_value_type_klasses[nonstatic_value_type_count] = klass;
- nonstatic_value_type_count++;
-
- ValueKlass* vklass = ValueKlass::cast(klass);
- if (vklass->contains_oops()) {
- value_type_oop_map_count += vklass->nonstatic_oop_map_count();
- }
- }
- }
+ unsigned int nonstatic_value_type_count = fac->count[NONSTATIC_VALUETYPE];
// Total non-static fields count, including every contended field
unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
fac->count[NONSTATIC_OOP] + fac->count[NONSTATIC_VALUETYPE];
@@ -4151,29 +4163,24 @@
real_offset = next_static_double_offset;
next_static_double_offset += BytesPerLong;
break;
case NONSTATIC_VALUETYPE:
{
- Klass* klass = nonstatic_value_type_klasses[next_value_type_index];
- assert(klass != NULL, "Klass should have been loaded and resolved earlier");
- assert(klass->access_flags().is_value_type(),"Must be a value type");
- ValueKlass* vklass = ValueKlass::cast(klass);
real_offset = next_nonstatic_valuetype_offset;
- next_nonstatic_valuetype_offset += (vklass->size_helper()) * wordSize - vklass->first_field_offset();
- // aligning next value type on a 64 bits boundary
- next_nonstatic_valuetype_offset = align_size_up(next_nonstatic_valuetype_offset, BytesPerLong);
- next_value_type_index += 1;
+ assert(next_value_type_index < large_value_count, "Incorrect number of value alloc types");
+ ValueKlass* vklass = nonstatic_value_type_klasses[next_value_type_index++];
if (vklass->contains_oops()) { // add flatten oop maps
int diff = real_offset - vklass->first_field_offset();
const OopMapBlock* map = vklass->start_of_nonstatic_oop_maps();
const OopMapBlock* const last_map = map + vklass->nonstatic_oop_map_count();
while (map < last_map) {
nonstatic_oop_maps->add(map->offset() + diff, map->count());
map++;
}
}
+ next_nonstatic_valuetype_offset += vklass->raw_value_byte_size();
}
break;
case NONSTATIC_OOP:
if( nonstatic_oop_space_count > 0 ) {
real_offset = nonstatic_oop_space_offset;
@@ -4340,11 +4347,11 @@
assert(!is_value_type() && !is_derive_value_type(), "@Contended not supported for value types yet");
next_nonstatic_padded_offset += ContendedPaddingWidth;
}
int notaligned_nonstatic_fields_end;
- if (nonstatic_value_type_count != 0) {
+ if (has_nonstatic_value_fields) {
notaligned_nonstatic_fields_end = next_nonstatic_valuetype_offset;
} else {
notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
}
< prev index next >