comparison src/share/vm/classfile/classFileParser.cpp @ 10348:3970971c91e0

8015270: @Contended: fix multiple issues in the layout code Summary: field count handling fixed, has_nonstatic_fields invariant fixed, oop map overrun fixed; new asserts Reviewed-by: kvn, dcubed, coleenp
author shade
date Mon, 27 May 2013 12:49:08 -0700
parents 6bd680e9ea35
children f2110083203d
comparison
equal deleted inserted replaced
10347:6c138b9851fb 10348:3970971c91e0
3150 if (!fs.access_flags().is_static()) { 3150 if (!fs.access_flags().is_static()) {
3151 nonstatic_contended_count++; 3151 nonstatic_contended_count++;
3152 } 3152 }
3153 } 3153 }
3154 } 3154 }
3155 int contended_count = nonstatic_contended_count;
3156 3155
3157 3156
3158 // Calculate the starting byte offsets 3157 // Calculate the starting byte offsets
3159 next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); 3158 next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
3160 next_static_double_offset = next_static_oop_offset + 3159 next_static_double_offset = next_static_oop_offset +
3175 int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() + 3174 int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() +
3176 nonstatic_field_size * heapOopSize; 3175 nonstatic_field_size * heapOopSize;
3177 3176
3178 next_nonstatic_field_offset = nonstatic_fields_start; 3177 next_nonstatic_field_offset = nonstatic_fields_start;
3179 3178
3179 bool is_contended_class = parsed_annotations->is_contended();
3180
3180 // Class is contended, pad before all the fields 3181 // Class is contended, pad before all the fields
3181 if (parsed_annotations->is_contended()) { 3182 if (is_contended_class) {
3182 next_nonstatic_field_offset += ContendedPaddingWidth; 3183 next_nonstatic_field_offset += ContendedPaddingWidth;
3183 } 3184 }
3184 3185
3185 // Compute the non-contended fields count 3186 // Compute the non-contended fields count.
3187 // The packing code below relies on these counts to determine if some field
3188 // can be squeezed into the alignment gap. Contended fields are obviously
3189 // exempt from that.
3186 unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; 3190 unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
3187 unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; 3191 unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
3188 unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; 3192 unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
3189 unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; 3193 unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
3190 unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; 3194 unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
3191 3195
3196 // Total non-static fields count, including every contended field
3197 unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
3198 fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
3199 fac->count[NONSTATIC_OOP];
3200
3192 bool super_has_nonstatic_fields = 3201 bool super_has_nonstatic_fields =
3193 (_super_klass() != NULL && _super_klass->has_nonstatic_fields()); 3202 (_super_klass() != NULL && _super_klass->has_nonstatic_fields());
3194 bool has_nonstatic_fields = super_has_nonstatic_fields || 3203 bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0);
3195 ((nonstatic_double_count + nonstatic_word_count +
3196 nonstatic_short_count + nonstatic_byte_count +
3197 nonstatic_oop_count) != 0);
3198 3204
3199 3205
3200 // Prepare list of oops for oop map generation. 3206 // Prepare list of oops for oop map generation.
3207 //
3208 // "offset" and "count" lists are describing the set of contiguous oop
3209 // regions. offset[i] is the start of the i-th region, which then has
3210 // count[i] oops following. Before we know how many regions are required,
3211 // we pessimistically allocate the maps to fit all the oops into the
3212 // distinct regions.
3213 //
3214 // TODO: We add +1 to always allocate non-zero resource arrays; we need
3215 // to figure out if we still need to do this.
3201 int* nonstatic_oop_offsets; 3216 int* nonstatic_oop_offsets;
3202 unsigned int* nonstatic_oop_counts; 3217 unsigned int* nonstatic_oop_counts;
3203 unsigned int nonstatic_oop_map_count = 0; 3218 unsigned int nonstatic_oop_map_count = 0;
3219 unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1;
3204 3220
3205 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( 3221 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
3206 THREAD, int, nonstatic_oop_count + 1); 3222 THREAD, int, max_nonstatic_oop_maps);
3207 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( 3223 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
3208 THREAD, unsigned int, nonstatic_oop_count + 1); 3224 THREAD, unsigned int, max_nonstatic_oop_maps);
3209 3225
3210 first_nonstatic_oop_offset = 0; // will be set for first oop field 3226 first_nonstatic_oop_offset = 0; // will be set for first oop field
3211 3227
3212 bool compact_fields = CompactFields; 3228 bool compact_fields = CompactFields;
3213 int allocation_style = FieldsAllocationStyle; 3229 int allocation_style = FieldsAllocationStyle;
3390 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] == 3406 nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
3391 real_offset - 3407 real_offset -
3392 int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) * 3408 int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
3393 heapOopSize ) { 3409 heapOopSize ) {
3394 // Extend current oop map 3410 // Extend current oop map
3411 assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
3395 nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1; 3412 nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
3396 } else { 3413 } else {
3397 // Create new oop map 3414 // Create new oop map
3415 assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
3398 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; 3416 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
3399 nonstatic_oop_counts [nonstatic_oop_map_count] = 1; 3417 nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
3400 nonstatic_oop_map_count += 1; 3418 nonstatic_oop_map_count += 1;
3401 if( first_nonstatic_oop_offset == 0 ) { // Undefined 3419 if( first_nonstatic_oop_offset == 0 ) { // Undefined
3402 first_nonstatic_oop_offset = real_offset; 3420 first_nonstatic_oop_offset = real_offset;
3450 // In the absence of alignment information, we end up with pessimistically separating 3468 // In the absence of alignment information, we end up with pessimistically separating
3451 // the fields with full-width padding. 3469 // the fields with full-width padding.
3452 // 3470 //
3453 // Additionally, this should not break alignment for the fields, so we round the alignment up 3471 // Additionally, this should not break alignment for the fields, so we round the alignment up
3454 // for each field. 3472 // for each field.
3455 if (contended_count > 0) { 3473 if (nonstatic_contended_count > 0) {
3456 3474
3457 // if there is at least one contended field, we need to have pre-padding for them 3475 // if there is at least one contended field, we need to have pre-padding for them
3458 if (nonstatic_contended_count > 0) { 3476 next_nonstatic_padded_offset += ContendedPaddingWidth;
3459 next_nonstatic_padded_offset += ContendedPaddingWidth;
3460 }
3461 3477
3462 // collect all contended groups 3478 // collect all contended groups
3463 BitMap bm(_cp->size()); 3479 BitMap bm(_cp->size());
3464 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { 3480 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) {
3465 // skip already laid out fields 3481 // skip already laid out fields
3516 next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize); 3532 next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize);
3517 real_offset = next_nonstatic_padded_offset; 3533 real_offset = next_nonstatic_padded_offset;
3518 next_nonstatic_padded_offset += heapOopSize; 3534 next_nonstatic_padded_offset += heapOopSize;
3519 3535
3520 // Create new oop map 3536 // Create new oop map
3537 assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
3521 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; 3538 nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
3522 nonstatic_oop_counts [nonstatic_oop_map_count] = 1; 3539 nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
3523 nonstatic_oop_map_count += 1; 3540 nonstatic_oop_map_count += 1;
3524 if( first_nonstatic_oop_offset == 0 ) { // Undefined 3541 if( first_nonstatic_oop_offset == 0 ) { // Undefined
3525 first_nonstatic_oop_offset = real_offset; 3542 first_nonstatic_oop_offset = real_offset;
3552 } 3569 }
3553 3570
3554 // handle static fields 3571 // handle static fields
3555 } 3572 }
3556 3573
3557 // Size of instances
3558 int notaligned_offset = next_nonstatic_padded_offset;
3559
3560 // Entire class is contended, pad in the back. 3574 // Entire class is contended, pad in the back.
3561 // This helps to alleviate memory contention effects for subclass fields 3575 // This helps to alleviate memory contention effects for subclass fields
3562 // and/or adjacent object. 3576 // and/or adjacent object.
3563 if (parsed_annotations->is_contended()) { 3577 if (is_contended_class) {
3564 notaligned_offset += ContendedPaddingWidth; 3578 next_nonstatic_padded_offset += ContendedPaddingWidth;
3565 } 3579 }
3566 3580
3567 int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize); 3581 int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
3568 int instance_end = align_size_up(notaligned_offset, wordSize); 3582
3583 int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize);
3584 int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize);
3569 int static_fields_end = align_size_up(next_static_byte_offset, wordSize); 3585 int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
3570 3586
3571 int static_field_size = (static_fields_end - 3587 int static_field_size = (static_fields_end -
3572 InstanceMirrorKlass::offset_of_static_fields()) / wordSize; 3588 InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
3573 nonstatic_field_size = nonstatic_field_size + 3589 nonstatic_field_size = nonstatic_field_size +
3576 int instance_size = align_object_size(instance_end / wordSize); 3592 int instance_size = align_object_size(instance_end / wordSize);
3577 3593
3578 assert(instance_size == align_object_size(align_size_up( 3594 assert(instance_size == align_object_size(align_size_up(
3579 (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), 3595 (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
3580 wordSize) / wordSize), "consistent layout helper value"); 3596 wordSize) / wordSize), "consistent layout helper value");
3597
3598 // Invariant: nonstatic_field end/start should only change if there are
3599 // nonstatic fields in the class, or if the class is contended. We compare
3600 // against the non-aligned value, so that end alignment will not fail the
3601 // assert without actually having the fields.
3602 assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) ||
3603 is_contended_class ||
3604 (nonstatic_fields_count > 0), "double-check nonstatic start/end");
3581 3605
3582 // Number of non-static oop map blocks allocated at end of klass. 3606 // Number of non-static oop map blocks allocated at end of klass.
3583 const unsigned int total_oop_map_count = 3607 const unsigned int total_oop_map_count =
3584 compute_oop_map_count(_super_klass, nonstatic_oop_map_count, 3608 compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
3585 first_nonstatic_oop_offset); 3609 first_nonstatic_oop_offset);