Mercurial > hg > truffle
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); |