3119 FieldAllocationCount* fac, |
3119 FieldAllocationCount* fac, |
3120 ClassAnnotationCollector* parsed_annotations, |
3120 ClassAnnotationCollector* parsed_annotations, |
3121 FieldLayoutInfo* info, |
3121 FieldLayoutInfo* info, |
3122 TRAPS) { |
3122 TRAPS) { |
3123 |
3123 |
3124 // get the padding width from the option |
|
3125 // TODO: Ask VM about specific CPU we are running on |
|
3126 int pad_size = ContendedPaddingWidth; |
|
3127 |
|
3128 // Field size and offset computation |
3124 // Field size and offset computation |
3129 int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size(); |
3125 int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size(); |
3130 int next_static_oop_offset; |
3126 int next_static_oop_offset; |
3131 int next_static_double_offset; |
3127 int next_static_double_offset; |
3132 int next_static_word_offset; |
3128 int next_static_word_offset; |
3135 int next_nonstatic_oop_offset; |
3131 int next_nonstatic_oop_offset; |
3136 int next_nonstatic_double_offset; |
3132 int next_nonstatic_double_offset; |
3137 int next_nonstatic_word_offset; |
3133 int next_nonstatic_word_offset; |
3138 int next_nonstatic_short_offset; |
3134 int next_nonstatic_short_offset; |
3139 int next_nonstatic_byte_offset; |
3135 int next_nonstatic_byte_offset; |
3140 int next_nonstatic_type_offset; |
|
3141 int first_nonstatic_oop_offset; |
3136 int first_nonstatic_oop_offset; |
3142 int first_nonstatic_field_offset; |
|
3143 int next_nonstatic_field_offset; |
3137 int next_nonstatic_field_offset; |
3144 int next_nonstatic_padded_offset; |
3138 int next_nonstatic_padded_offset; |
3145 |
3139 |
3146 // Count the contended fields by type. |
3140 // Count the contended fields by type. |
|
3141 // |
|
3142 // We ignore static fields, because @Contended is not supported for them. |
|
3143 // The layout code below will also ignore the static fields. |
3147 int nonstatic_contended_count = 0; |
3144 int nonstatic_contended_count = 0; |
3148 FieldAllocationCount fac_contended; |
3145 FieldAllocationCount fac_contended; |
3149 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { |
3146 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { |
3150 FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); |
3147 FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); |
3151 if (fs.is_contended()) { |
3148 if (fs.is_contended()) { |
3173 next_static_short_offset = next_static_word_offset + |
3170 next_static_short_offset = next_static_word_offset + |
3174 ((fac->count[STATIC_WORD]) * BytesPerInt); |
3171 ((fac->count[STATIC_WORD]) * BytesPerInt); |
3175 next_static_byte_offset = next_static_short_offset + |
3172 next_static_byte_offset = next_static_short_offset + |
3176 ((fac->count[STATIC_SHORT]) * BytesPerShort); |
3173 ((fac->count[STATIC_SHORT]) * BytesPerShort); |
3177 |
3174 |
3178 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + |
3175 int nonstatic_fields_start = instanceOopDesc::base_offset_in_bytes() + |
3179 nonstatic_field_size * heapOopSize; |
3176 nonstatic_field_size * heapOopSize; |
3180 |
3177 |
3181 next_nonstatic_field_offset = first_nonstatic_field_offset; |
3178 next_nonstatic_field_offset = nonstatic_fields_start; |
3182 |
3179 |
3183 // class is contended, pad before all the fields |
3180 // Class is contended, pad before all the fields |
3184 if (parsed_annotations->is_contended()) { |
3181 if (parsed_annotations->is_contended()) { |
3185 next_nonstatic_field_offset += pad_size; |
3182 next_nonstatic_field_offset += ContendedPaddingWidth; |
3186 } |
3183 } |
3187 |
3184 |
|
3185 // Compute the non-contended fields count |
3188 unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; |
3186 unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; |
3189 unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; |
3187 unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; |
3190 unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; |
3188 unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; |
3191 unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; |
3189 unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; |
3192 unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; |
3190 unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; |
3240 _class_name == vmSymbols::java_lang_Long())) { |
3238 _class_name == vmSymbols::java_lang_Long())) { |
3241 allocation_style = 0; // Allocate oops first |
3239 allocation_style = 0; // Allocate oops first |
3242 compact_fields = false; // Don't compact fields |
3240 compact_fields = false; // Don't compact fields |
3243 } |
3241 } |
3244 |
3242 |
|
3243 // Rearrange fields for a given allocation style |
3245 if( allocation_style == 0 ) { |
3244 if( allocation_style == 0 ) { |
3246 // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields |
3245 // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields |
3247 next_nonstatic_oop_offset = next_nonstatic_field_offset; |
3246 next_nonstatic_oop_offset = next_nonstatic_field_offset; |
3248 next_nonstatic_double_offset = next_nonstatic_oop_offset + |
3247 next_nonstatic_double_offset = next_nonstatic_oop_offset + |
3249 (nonstatic_oop_count * heapOopSize); |
3248 (nonstatic_oop_count * heapOopSize); |
3280 int nonstatic_oop_space_offset; |
3279 int nonstatic_oop_space_offset; |
3281 int nonstatic_word_space_offset; |
3280 int nonstatic_word_space_offset; |
3282 int nonstatic_short_space_offset; |
3281 int nonstatic_short_space_offset; |
3283 int nonstatic_byte_space_offset; |
3282 int nonstatic_byte_space_offset; |
3284 |
3283 |
|
3284 // Try to squeeze some of the fields into the gaps due to |
|
3285 // long/double alignment. |
3285 if( nonstatic_double_count > 0 ) { |
3286 if( nonstatic_double_count > 0 ) { |
3286 int offset = next_nonstatic_double_offset; |
3287 int offset = next_nonstatic_double_offset; |
3287 next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); |
3288 next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); |
3288 if( compact_fields && offset != next_nonstatic_double_offset ) { |
3289 if( compact_fields && offset != next_nonstatic_double_offset ) { |
3289 // Allocate available fields into the gap before double field. |
3290 // Allocate available fields into the gap before double field. |
3453 // for each field. |
3454 // for each field. |
3454 if (contended_count > 0) { |
3455 if (contended_count > 0) { |
3455 |
3456 |
3456 // if there is at least one contended field, we need to have pre-padding for them |
3457 // if there is at least one contended field, we need to have pre-padding for them |
3457 if (nonstatic_contended_count > 0) { |
3458 if (nonstatic_contended_count > 0) { |
3458 next_nonstatic_padded_offset += pad_size; |
3459 next_nonstatic_padded_offset += ContendedPaddingWidth; |
3459 } |
3460 } |
3460 |
3461 |
3461 // collect all contended groups |
3462 // collect all contended groups |
3462 BitMap bm(_cp->size()); |
3463 BitMap bm(_cp->size()); |
3463 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { |
3464 for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) { |
3532 if (fs.contended_group() == 0) { |
3533 if (fs.contended_group() == 0) { |
3533 // Contended group defines the equivalence class over the fields: |
3534 // Contended group defines the equivalence class over the fields: |
3534 // the fields within the same contended group are not inter-padded. |
3535 // the fields within the same contended group are not inter-padded. |
3535 // The only exception is default group, which does not incur the |
3536 // The only exception is default group, which does not incur the |
3536 // equivalence, and so requires intra-padding. |
3537 // equivalence, and so requires intra-padding. |
3537 next_nonstatic_padded_offset += pad_size; |
3538 next_nonstatic_padded_offset += ContendedPaddingWidth; |
3538 } |
3539 } |
3539 |
3540 |
3540 fs.set_offset(real_offset); |
3541 fs.set_offset(real_offset); |
3541 } // for |
3542 } // for |
3542 |
3543 |
3544 // Note that this will effectively pad the last group in the back; |
3545 // Note that this will effectively pad the last group in the back; |
3545 // this is expected to alleviate memory contention effects for |
3546 // this is expected to alleviate memory contention effects for |
3546 // subclass fields and/or adjacent object. |
3547 // subclass fields and/or adjacent object. |
3547 // If this was the default group, the padding is already in place. |
3548 // If this was the default group, the padding is already in place. |
3548 if (current_group != 0) { |
3549 if (current_group != 0) { |
3549 next_nonstatic_padded_offset += pad_size; |
3550 next_nonstatic_padded_offset += ContendedPaddingWidth; |
3550 } |
3551 } |
3551 } |
3552 } |
3552 |
3553 |
3553 // handle static fields |
3554 // handle static fields |
3554 } |
3555 } |
3558 |
3559 |
3559 // Entire class is contended, pad in the back. |
3560 // Entire class is contended, pad in the back. |
3560 // This helps to alleviate memory contention effects for subclass fields |
3561 // This helps to alleviate memory contention effects for subclass fields |
3561 // and/or adjacent object. |
3562 // and/or adjacent object. |
3562 if (parsed_annotations->is_contended()) { |
3563 if (parsed_annotations->is_contended()) { |
3563 notaligned_offset += pad_size; |
3564 notaligned_offset += ContendedPaddingWidth; |
3564 } |
3565 } |
3565 |
3566 |
3566 int next_static_type_offset = align_size_up(next_static_byte_offset, wordSize); |
3567 int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize); |
3567 int static_field_size = (next_static_type_offset - |
3568 int instance_end = align_size_up(notaligned_offset, wordSize); |
3568 InstanceMirrorKlass::offset_of_static_fields()) / wordSize; |
3569 int static_fields_end = align_size_up(next_static_byte_offset, wordSize); |
3569 |
3570 |
3570 next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); |
3571 int static_field_size = (static_fields_end - |
3571 nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset |
3572 InstanceMirrorKlass::offset_of_static_fields()) / wordSize; |
3572 - first_nonstatic_field_offset)/heapOopSize); |
3573 nonstatic_field_size = nonstatic_field_size + |
3573 |
3574 (nonstatic_fields_end - nonstatic_fields_start) / heapOopSize; |
3574 next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); |
3575 |
3575 int instance_size = align_object_size(next_nonstatic_type_offset / wordSize); |
3576 int instance_size = align_object_size(instance_end / wordSize); |
3576 |
3577 |
3577 assert(instance_size == align_object_size(align_size_up( |
3578 assert(instance_size == align_object_size(align_size_up( |
3578 (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), |
3579 (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), |
3579 wordSize) / wordSize), "consistent layout helper value"); |
3580 wordSize) / wordSize), "consistent layout helper value"); |
3580 |
3581 |
3587 if (PrintFieldLayout) { |
3588 if (PrintFieldLayout) { |
3588 print_field_layout(_class_name, |
3589 print_field_layout(_class_name, |
3589 _fields, |
3590 _fields, |
3590 _cp, |
3591 _cp, |
3591 instance_size, |
3592 instance_size, |
3592 first_nonstatic_field_offset, |
3593 nonstatic_fields_start, |
3593 next_nonstatic_field_offset, |
3594 nonstatic_fields_end, |
3594 next_static_type_offset); |
3595 static_fields_end); |
3595 } |
3596 } |
3596 |
3597 |
3597 #endif |
3598 #endif |
3598 // Pass back information needed for InstanceKlass creation |
3599 // Pass back information needed for InstanceKlass creation |
3599 info->nonstatic_oop_offsets = nonstatic_oop_offsets; |
3600 info->nonstatic_oop_offsets = nonstatic_oop_offsets; |