1.1 --- a/src/share/vm/classfile/classFileParser.cpp Fri Jan 11 09:53:24 2013 -0800 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Jan 14 15:17:47 2013 +0100 1.3 @@ -970,6 +970,12 @@ 1.4 runtime_visible_annotations_length = attribute_length; 1.5 runtime_visible_annotations = cfs->get_u1_buffer(); 1.6 assert(runtime_visible_annotations != NULL, "null visible annotations"); 1.7 + parse_annotations(loader_data, 1.8 + runtime_visible_annotations, 1.9 + runtime_visible_annotations_length, 1.10 + cp, 1.11 + parsed_annotations, 1.12 + CHECK); 1.13 cfs->skip_u1(runtime_visible_annotations_length, CHECK); 1.14 } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { 1.15 runtime_invisible_annotations_length = attribute_length; 1.16 @@ -1216,19 +1222,16 @@ 1.17 field->initialize(access_flags.as_short(), 1.18 name_index, 1.19 signature_index, 1.20 - constantvalue_index, 1.21 - 0); 1.22 + constantvalue_index); 1.23 + BasicType type = cp->basic_type_for_signature_at(signature_index); 1.24 + 1.25 + // Remember how many oops we encountered and compute allocation type 1.26 + FieldAllocationType atype = fac->update(is_static, type); 1.27 + field->set_allocation_type(atype); 1.28 + 1.29 + // After field is initialized with type, we can augment it with aux info 1.30 if (parsed_annotations.has_any_annotations()) 1.31 parsed_annotations.apply_to(field); 1.32 - 1.33 - BasicType type = cp->basic_type_for_signature_at(signature_index); 1.34 - 1.35 - // Remember how many oops we encountered and compute allocation type 1.36 - FieldAllocationType atype = fac->update(is_static, type); 1.37 - 1.38 - // The correct offset is computed later (all oop fields will be located together) 1.39 - // We temporarily store the allocation type in the offset field 1.40 - field->set_offset(atype); 1.41 } 1.42 1.43 int index = length; 1.44 @@ -1259,17 +1262,13 @@ 1.45 field->initialize(JVM_ACC_FIELD_INTERNAL, 1.46 injected[n].name_index, 1.47 injected[n].signature_index, 1.48 - 0, 1.49 0); 1.50 1.51 BasicType type = FieldType::basic_type(injected[n].signature()); 1.52 1.53 // Remember how many oops we encountered and compute allocation type 1.54 FieldAllocationType atype = fac->update(false, type); 1.55 - 1.56 - // The correct offset is computed later (all oop fields will be located together) 1.57 - // We temporarily store the allocation type in the offset field 1.58 - field->set_offset(atype); 1.59 + field->set_allocation_type(atype); 1.60 index++; 1.61 } 1.62 } 1.63 @@ -1735,7 +1734,8 @@ 1.64 } 1.65 1.66 // Sift through annotations, looking for those significant to the VM: 1.67 -void ClassFileParser::parse_annotations(u1* buffer, int limit, 1.68 +void ClassFileParser::parse_annotations(ClassLoaderData* loader_data, 1.69 + u1* buffer, int limit, 1.70 constantPoolHandle cp, 1.71 ClassFileParser::AnnotationCollector* coll, 1.72 TRAPS) { 1.73 @@ -1752,9 +1752,12 @@ 1.74 e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;' 1.75 e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME' 1.76 e_size = 11, // end of 'e' annotation 1.77 - c_tag_val = 'c', 1.78 - c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;' 1.79 + c_tag_val = 'c', // payload is type 1.80 + c_con_off = 7, // utf8 payload, such as 'I' 1.81 c_size = 9, // end of 'c' annotation 1.82 + s_tag_val = 's', // payload is String 1.83 + s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' 1.84 + s_size = 9, 1.85 min_size = 6 // smallest possible size (zero members) 1.86 }; 1.87 while ((--nann) >= 0 && (index-2 + min_size <= limit)) { 1.88 @@ -1773,57 +1776,65 @@ 1.89 } 1.90 1.91 // Here is where parsing particular annotations will take place. 1.92 - AnnotationCollector::ID id = coll->annotation_index(aname); 1.93 + AnnotationCollector::ID id = coll->annotation_index(loader_data, aname); 1.94 if (id == AnnotationCollector::_unknown) continue; 1.95 coll->set_annotation(id); 1.96 - // If there are no values, just set the bit and move on: 1.97 - if (count == 0) continue; 1.98 - 1.99 - // For the record, here is how annotation payloads can be collected. 1.100 - // Suppose we want to capture @Retention.value. Here is how: 1.101 - //if (id == AnnotationCollector::_class_Retention) { 1.102 - // Symbol* payload = NULL; 1.103 - // if (count == 1 1.104 - // && e_size == (index0 - index) // match size 1.105 - // && e_tag_val == *(abase + tag_off) 1.106 - // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off)) 1.107 - // == vmSymbols::RetentionPolicy_signature()) 1.108 - // && member == vmSymbols::value_name()) { 1.109 - // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off)); 1.110 - // } 1.111 - // check_property(payload != NULL, 1.112 - // "Invalid @Retention annotation at offset %u in class file %s", 1.113 - // index0, CHECK); 1.114 - // if (payload != NULL) { 1.115 - // payload->increment_refcount(); 1.116 - // coll->_class_RetentionPolicy = payload; 1.117 - // } 1.118 - //} 1.119 + 1.120 + if (id == AnnotationCollector::_sun_misc_Contended) { 1.121 + if (count == 1 1.122 + && s_size == (index - index0) // match size 1.123 + && s_tag_val == *(abase + tag_off) 1.124 + && member == vmSymbols::value_name()) { 1.125 + u2 group_index = Bytes::get_Java_u2(abase + s_con_off); 1.126 + coll->set_contended_group(group_index); 1.127 + } else { 1.128 + coll->set_contended_group(0); // default contended group 1.129 + } 1.130 + coll->set_contended(true); 1.131 + } else { 1.132 + coll->set_contended(false); 1.133 + } 1.134 } 1.135 } 1.136 1.137 -ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) { 1.138 +ClassFileParser::AnnotationCollector::ID 1.139 +ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data, 1.140 + Symbol* name) { 1.141 vmSymbols::SID sid = vmSymbols::find_sid(name); 1.142 + bool privileged = false; 1.143 + if (loader_data->is_the_null_class_loader_data()) { 1.144 + // Privileged code can use all annotations. Other code silently drops some. 1.145 + privileged = true; 1.146 + } 1.147 switch (sid) { 1.148 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): 1.149 if (_location != _in_method) break; // only allow for methods 1.150 + if (!privileged) break; // only allow in privileged code 1.151 return _method_ForceInline; 1.152 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): 1.153 if (_location != _in_method) break; // only allow for methods 1.154 + if (!privileged) break; // only allow in privileged code 1.155 return _method_DontInline; 1.156 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): 1.157 if (_location != _in_method) break; // only allow for methods 1.158 + if (!privileged) break; // only allow in privileged code 1.159 return _method_LambdaForm_Compiled; 1.160 case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): 1.161 if (_location != _in_method) break; // only allow for methods 1.162 + if (!privileged) break; // only allow in privileged code 1.163 return _method_LambdaForm_Hidden; 1.164 + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): 1.165 + if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes 1.166 + if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges 1.167 + return _sun_misc_Contended; 1.168 default: break; 1.169 } 1.170 return AnnotationCollector::_unknown; 1.171 } 1.172 1.173 void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { 1.174 - fatal("no field annotations yet"); 1.175 + if (is_contended()) 1.176 + f->set_contended_group(contended_group()); 1.177 } 1.178 1.179 void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) { 1.180 @@ -1838,7 +1849,7 @@ 1.181 } 1.182 1.183 void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) { 1.184 - fatal("no class annotations yet"); 1.185 + k->set_is_contended(is_contended()); 1.186 } 1.187 1.188 1.189 @@ -2181,7 +2192,8 @@ 1.190 runtime_visible_annotations_length = method_attribute_length; 1.191 runtime_visible_annotations = cfs->get_u1_buffer(); 1.192 assert(runtime_visible_annotations != NULL, "null visible annotations"); 1.193 - parse_annotations(runtime_visible_annotations, 1.194 + parse_annotations(loader_data, 1.195 + runtime_visible_annotations, 1.196 runtime_visible_annotations_length, cp, &parsed_annotations, 1.197 CHECK_(nullHandle)); 1.198 cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); 1.199 @@ -2886,7 +2898,8 @@ 1.200 runtime_visible_annotations_length = attribute_length; 1.201 runtime_visible_annotations = cfs->get_u1_buffer(); 1.202 assert(runtime_visible_annotations != NULL, "null visible annotations"); 1.203 - parse_annotations(runtime_visible_annotations, 1.204 + parse_annotations(loader_data, 1.205 + runtime_visible_annotations, 1.206 runtime_visible_annotations_length, 1.207 cp, 1.208 parsed_annotations, 1.209 @@ -3405,18 +3418,21 @@ 1.210 // Size of Java itable (in words) 1.211 itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces); 1.212 1.213 + // get the padding width from the option 1.214 + // TODO: Ask VM about specific CPU we are running on 1.215 + int pad_size = ContendedPaddingWidth; 1.216 + 1.217 // Field size and offset computation 1.218 int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size(); 1.219 #ifndef PRODUCT 1.220 int orig_nonstatic_field_size = 0; 1.221 #endif 1.222 - int static_field_size = 0; 1.223 int next_static_oop_offset; 1.224 int next_static_double_offset; 1.225 int next_static_word_offset; 1.226 int next_static_short_offset; 1.227 int next_static_byte_offset; 1.228 - int next_static_type_offset; 1.229 + int next_static_padded_offset; 1.230 int next_nonstatic_oop_offset; 1.231 int next_nonstatic_double_offset; 1.232 int next_nonstatic_word_offset; 1.233 @@ -3426,11 +3442,36 @@ 1.234 int first_nonstatic_oop_offset; 1.235 int first_nonstatic_field_offset; 1.236 int next_nonstatic_field_offset; 1.237 + int next_nonstatic_padded_offset; 1.238 + 1.239 + // Count the contended fields by type. 1.240 + int static_contended_count = 0; 1.241 + int nonstatic_contended_count = 0; 1.242 + FieldAllocationCount fac_contended; 1.243 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.244 + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); 1.245 + if (fs.is_contended()) { 1.246 + fac_contended.count[atype]++; 1.247 + if (fs.access_flags().is_static()) { 1.248 + static_contended_count++; 1.249 + } else { 1.250 + nonstatic_contended_count++; 1.251 + } 1.252 + } 1.253 + } 1.254 + int contended_count = static_contended_count + nonstatic_contended_count; 1.255 + 1.256 1.257 // Calculate the starting byte offsets 1.258 next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields(); 1.259 + 1.260 + // class is contended, pad before all the fields 1.261 + if (parsed_annotations.is_contended()) { 1.262 + next_static_oop_offset += pad_size; 1.263 + } 1.264 + 1.265 next_static_double_offset = next_static_oop_offset + 1.266 - (fac.count[STATIC_OOP] * heapOopSize); 1.267 + ((fac.count[STATIC_OOP] - fac_contended.count[STATIC_OOP]) * heapOopSize); 1.268 if ( fac.count[STATIC_DOUBLE] && 1.269 (Universe::field_type_should_be_aligned(T_DOUBLE) || 1.270 Universe::field_type_should_be_aligned(T_LONG)) ) { 1.271 @@ -3438,25 +3479,29 @@ 1.272 } 1.273 1.274 next_static_word_offset = next_static_double_offset + 1.275 - (fac.count[STATIC_DOUBLE] * BytesPerLong); 1.276 + ((fac.count[STATIC_DOUBLE] - fac_contended.count[STATIC_DOUBLE]) * BytesPerLong); 1.277 next_static_short_offset = next_static_word_offset + 1.278 - (fac.count[STATIC_WORD] * BytesPerInt); 1.279 + ((fac.count[STATIC_WORD] - fac_contended.count[STATIC_WORD]) * BytesPerInt); 1.280 next_static_byte_offset = next_static_short_offset + 1.281 - (fac.count[STATIC_SHORT] * BytesPerShort); 1.282 - next_static_type_offset = align_size_up((next_static_byte_offset + 1.283 - fac.count[STATIC_BYTE] ), wordSize ); 1.284 - static_field_size = (next_static_type_offset - 1.285 - next_static_oop_offset) / wordSize; 1.286 + ((fac.count[STATIC_SHORT] - fac_contended.count[STATIC_SHORT]) * BytesPerShort); 1.287 + next_static_padded_offset = next_static_byte_offset + 1.288 + ((fac.count[STATIC_BYTE] - fac_contended.count[STATIC_BYTE]) * 1); 1.289 1.290 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + 1.291 nonstatic_field_size * heapOopSize; 1.292 + 1.293 + // class is contended, pad before all the fields 1.294 + if (parsed_annotations.is_contended()) { 1.295 + first_nonstatic_field_offset += pad_size; 1.296 + } 1.297 + 1.298 next_nonstatic_field_offset = first_nonstatic_field_offset; 1.299 1.300 - unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE]; 1.301 - unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD]; 1.302 - unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT]; 1.303 - unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE]; 1.304 - unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP]; 1.305 + unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE]; 1.306 + unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD]; 1.307 + unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT]; 1.308 + unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE]; 1.309 + unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP]; 1.310 1.311 bool super_has_nonstatic_fields = 1.312 (super_klass() != NULL && super_klass->has_nonstatic_fields()); 1.313 @@ -3529,12 +3574,12 @@ 1.314 } 1.315 1.316 if( allocation_style == 0 ) { 1.317 - // Fields order: oops, longs/doubles, ints, shorts/chars, bytes 1.318 + // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields 1.319 next_nonstatic_oop_offset = next_nonstatic_field_offset; 1.320 next_nonstatic_double_offset = next_nonstatic_oop_offset + 1.321 (nonstatic_oop_count * heapOopSize); 1.322 } else if( allocation_style == 1 ) { 1.323 - // Fields order: longs/doubles, ints, shorts/chars, bytes, oops 1.324 + // Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields 1.325 next_nonstatic_double_offset = next_nonstatic_field_offset; 1.326 } else if( allocation_style == 2 ) { 1.327 // Fields allocation: oops fields in super and sub classes are together. 1.328 @@ -3613,27 +3658,33 @@ 1.329 (nonstatic_word_count * BytesPerInt); 1.330 next_nonstatic_byte_offset = next_nonstatic_short_offset + 1.331 (nonstatic_short_count * BytesPerShort); 1.332 - 1.333 - int notaligned_offset; 1.334 - if( allocation_style == 0 ) { 1.335 - notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count; 1.336 - } else { // allocation_style == 1 1.337 - next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count; 1.338 + next_nonstatic_padded_offset = next_nonstatic_byte_offset + 1.339 + nonstatic_byte_count; 1.340 + 1.341 + // let oops jump before padding with this allocation style 1.342 + if( allocation_style == 1 ) { 1.343 + next_nonstatic_oop_offset = next_nonstatic_padded_offset; 1.344 if( nonstatic_oop_count > 0 ) { 1.345 next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); 1.346 } 1.347 - notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); 1.348 + next_nonstatic_padded_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); 1.349 } 1.350 - next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); 1.351 - nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset 1.352 - - first_nonstatic_field_offset)/heapOopSize); 1.353 1.354 // Iterate over fields again and compute correct offsets. 1.355 // The field allocation type was temporarily stored in the offset slot. 1.356 // oop fields are located before non-oop fields (static and non-static). 1.357 for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.358 + 1.359 + // skip already laid out fields 1.360 + if (fs.is_offset_set()) continue; 1.361 + 1.362 + // contended fields are handled below 1.363 + if (fs.is_contended()) continue; 1.364 + 1.365 int real_offset; 1.366 - FieldAllocationType atype = (FieldAllocationType) fs.offset(); 1.367 + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); 1.368 + 1.369 + // pack the rest of the fields 1.370 switch (atype) { 1.371 case STATIC_OOP: 1.372 real_offset = next_static_oop_offset; 1.373 @@ -3722,13 +3773,225 @@ 1.374 fs.set_offset(real_offset); 1.375 } 1.376 1.377 + 1.378 + // Handle the contended cases. 1.379 + // 1.380 + // Each contended field should not intersect the cache line with another contended field. 1.381 + // In the absence of alignment information, we end up with pessimistically separating 1.382 + // the fields with full-width padding. 1.383 + // 1.384 + // Additionally, this should not break alignment for the fields, so we round the alignment up 1.385 + // for each field. 1.386 + if (contended_count > 0) { 1.387 + 1.388 + // if there is at least one contended field, we need to have pre-padding for them 1.389 + if (nonstatic_contended_count > 0) { 1.390 + next_nonstatic_padded_offset += pad_size; 1.391 + } 1.392 + 1.393 + // collect all contended groups 1.394 + BitMap bm(cp->size()); 1.395 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.396 + // skip already laid out fields 1.397 + if (fs.is_offset_set()) continue; 1.398 + 1.399 + if (fs.is_contended()) { 1.400 + bm.set_bit(fs.contended_group()); 1.401 + } 1.402 + } 1.403 + 1.404 + int current_group = -1; 1.405 + while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { 1.406 + 1.407 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.408 + 1.409 + // skip already laid out fields 1.410 + if (fs.is_offset_set()) continue; 1.411 + 1.412 + // skip non-contended fields and fields from different group 1.413 + if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; 1.414 + 1.415 + // handle statics below 1.416 + if (fs.access_flags().is_static()) continue; 1.417 + 1.418 + int real_offset; 1.419 + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); 1.420 + 1.421 + switch (atype) { 1.422 + case NONSTATIC_BYTE: 1.423 + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1); 1.424 + real_offset = next_nonstatic_padded_offset; 1.425 + next_nonstatic_padded_offset += 1; 1.426 + break; 1.427 + 1.428 + case NONSTATIC_SHORT: 1.429 + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort); 1.430 + real_offset = next_nonstatic_padded_offset; 1.431 + next_nonstatic_padded_offset += BytesPerShort; 1.432 + break; 1.433 + 1.434 + case NONSTATIC_WORD: 1.435 + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt); 1.436 + real_offset = next_nonstatic_padded_offset; 1.437 + next_nonstatic_padded_offset += BytesPerInt; 1.438 + break; 1.439 + 1.440 + case NONSTATIC_DOUBLE: 1.441 + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong); 1.442 + real_offset = next_nonstatic_padded_offset; 1.443 + next_nonstatic_padded_offset += BytesPerLong; 1.444 + break; 1.445 + 1.446 + case NONSTATIC_OOP: 1.447 + next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize); 1.448 + real_offset = next_nonstatic_padded_offset; 1.449 + next_nonstatic_padded_offset += heapOopSize; 1.450 + 1.451 + // Create new oop map 1.452 + nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset; 1.453 + nonstatic_oop_counts [nonstatic_oop_map_count] = 1; 1.454 + nonstatic_oop_map_count += 1; 1.455 + if( first_nonstatic_oop_offset == 0 ) { // Undefined 1.456 + first_nonstatic_oop_offset = real_offset; 1.457 + } 1.458 + break; 1.459 + 1.460 + default: 1.461 + ShouldNotReachHere(); 1.462 + } 1.463 + 1.464 + if (fs.contended_group() == 0) { 1.465 + // Contended group defines the equivalence class over the fields: 1.466 + // the fields within the same contended group are not inter-padded. 1.467 + // The only exception is default group, which does not incur the 1.468 + // equivalence, and so requires intra-padding. 1.469 + next_nonstatic_padded_offset += pad_size; 1.470 + } 1.471 + 1.472 + fs.set_offset(real_offset); 1.473 + } // for 1.474 + 1.475 + // Start laying out the next group. 1.476 + // Note that this will effectively pad the last group in the back; 1.477 + // this is expected to alleviate memory contention effects for 1.478 + // subclass fields and/or adjacent object. 1.479 + // If this was the default group, the padding is already in place. 1.480 + if (current_group != 0) { 1.481 + next_nonstatic_padded_offset += pad_size; 1.482 + } 1.483 + } 1.484 + 1.485 + // handle static fields 1.486 + 1.487 + // if there is at least one contended field, we need to have pre-padding for them 1.488 + if (static_contended_count > 0) { 1.489 + next_static_padded_offset += pad_size; 1.490 + } 1.491 + 1.492 + current_group = -1; 1.493 + while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) { 1.494 + 1.495 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.496 + 1.497 + // skip already laid out fields 1.498 + if (fs.is_offset_set()) continue; 1.499 + 1.500 + // skip non-contended fields and fields from different group 1.501 + if (!fs.is_contended() || (fs.contended_group() != current_group)) continue; 1.502 + 1.503 + // non-statics already handled above 1.504 + if (!fs.access_flags().is_static()) continue; 1.505 + 1.506 + int real_offset; 1.507 + FieldAllocationType atype = (FieldAllocationType) fs.allocation_type(); 1.508 + 1.509 + switch (atype) { 1.510 + 1.511 + case STATIC_BYTE: 1.512 + next_static_padded_offset = align_size_up(next_static_padded_offset, 1); 1.513 + real_offset = next_static_padded_offset; 1.514 + next_static_padded_offset += 1; 1.515 + break; 1.516 + 1.517 + case STATIC_SHORT: 1.518 + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerShort); 1.519 + real_offset = next_static_padded_offset; 1.520 + next_static_padded_offset += BytesPerShort; 1.521 + break; 1.522 + 1.523 + case STATIC_WORD: 1.524 + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerInt); 1.525 + real_offset = next_static_padded_offset; 1.526 + next_static_padded_offset += BytesPerInt; 1.527 + break; 1.528 + 1.529 + case STATIC_DOUBLE: 1.530 + next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerLong); 1.531 + real_offset = next_static_padded_offset; 1.532 + next_static_padded_offset += BytesPerLong; 1.533 + break; 1.534 + 1.535 + case STATIC_OOP: 1.536 + next_static_padded_offset = align_size_up(next_static_padded_offset, heapOopSize); 1.537 + real_offset = next_static_padded_offset; 1.538 + next_static_padded_offset += heapOopSize; 1.539 + break; 1.540 + 1.541 + default: 1.542 + ShouldNotReachHere(); 1.543 + } 1.544 + 1.545 + if (fs.contended_group() == 0) { 1.546 + // Contended group defines the equivalence class over the fields: 1.547 + // the fields within the same contended group are not inter-padded. 1.548 + // The only exception is default group, which does not incur the 1.549 + // equivalence, and so requires intra-padding. 1.550 + next_static_padded_offset += pad_size; 1.551 + } 1.552 + 1.553 + fs.set_offset(real_offset); 1.554 + } // for 1.555 + 1.556 + // Start laying out the next group. 1.557 + // Note that this will effectively pad the last group in the back; 1.558 + // this is expected to alleviate memory contention effects for 1.559 + // subclass fields and/or adjacent object. 1.560 + // If this was the default group, the padding is already in place. 1.561 + if (current_group != 0) { 1.562 + next_static_padded_offset += pad_size; 1.563 + } 1.564 + 1.565 + } 1.566 + 1.567 + } // handle contended 1.568 + 1.569 // Size of instances 1.570 int instance_size; 1.571 1.572 + int notaligned_offset = next_nonstatic_padded_offset; 1.573 + 1.574 + // Entire class is contended, pad in the back. 1.575 + // This helps to alleviate memory contention effects for subclass fields 1.576 + // and/or adjacent object. 1.577 + if (parsed_annotations.is_contended()) { 1.578 + notaligned_offset += pad_size; 1.579 + next_static_padded_offset += pad_size; 1.580 + } 1.581 + 1.582 + int next_static_type_offset = align_size_up(next_static_padded_offset, wordSize); 1.583 + int static_field_size = (next_static_type_offset - 1.584 + InstanceMirrorKlass::offset_of_static_fields()) / wordSize; 1.585 + 1.586 + next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize ); 1.587 + nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset 1.588 + - first_nonstatic_field_offset)/heapOopSize); 1.589 + 1.590 next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); 1.591 instance_size = align_object_size(next_nonstatic_type_offset / wordSize); 1.592 1.593 - assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value"); 1.594 + assert(instance_size == align_object_size(align_size_up( 1.595 + (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize + ((parsed_annotations.is_contended()) ? pad_size : 0)), 1.596 + wordSize) / wordSize), "consistent layout helper value"); 1.597 1.598 // Number of non-static oop map blocks allocated at end of klass. 1.599 const unsigned int total_oop_map_count = 1.600 @@ -4008,6 +4271,18 @@ 1.601 } 1.602 #endif 1.603 1.604 +#ifndef PRODUCT 1.605 + if (PrintFieldLayout) { 1.606 + print_field_layout(name, 1.607 + fields, 1.608 + cp, 1.609 + instance_size, 1.610 + first_nonstatic_field_offset, 1.611 + next_nonstatic_field_offset, 1.612 + next_static_type_offset); 1.613 + } 1.614 +#endif 1.615 + 1.616 // preserve result across HandleMark 1.617 preserve_this_klass = this_klass(); 1.618 } 1.619 @@ -4020,6 +4295,38 @@ 1.620 return this_klass; 1.621 } 1.622 1.623 +void ClassFileParser::print_field_layout(Symbol* name, 1.624 + Array<u2>* fields, 1.625 + constantPoolHandle cp, 1.626 + int instance_size, 1.627 + int instance_fields_start, 1.628 + int instance_fields_end, 1.629 + int static_fields_end) { 1.630 + tty->print("%s: field layout\n", name->as_klass_external_name()); 1.631 + tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---"); 1.632 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.633 + if (!fs.access_flags().is_static()) { 1.634 + tty->print(" @%3d \"%s\" %s\n", 1.635 + fs.offset(), 1.636 + fs.name()->as_klass_external_name(), 1.637 + fs.signature()->as_klass_external_name()); 1.638 + } 1.639 + } 1.640 + tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---"); 1.641 + tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---"); 1.642 + tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---"); 1.643 + for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { 1.644 + if (fs.access_flags().is_static()) { 1.645 + tty->print(" @%3d \"%s\" %s\n", 1.646 + fs.offset(), 1.647 + fs.name()->as_klass_external_name(), 1.648 + fs.signature()->as_klass_external_name()); 1.649 + } 1.650 + } 1.651 + tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---"); 1.652 + tty->print("\n"); 1.653 +} 1.654 + 1.655 unsigned int 1.656 ClassFileParser::compute_oop_map_count(instanceKlassHandle super, 1.657 unsigned int nonstatic_oop_map_count,