< prev index next >

src/hotspot/share/classfile/fieldLayoutBuilder.cpp

Print this page
rev 59083 : DRAFT 8236522: NonTearable marker interface for inline classes to enforce atomicity

*** 537,547 **** _first_field_offset(-1), _exact_size_in_bytes(-1), _has_nonstatic_fields(false), _is_contended(is_contended), _is_value_type(is_value_type), ! _has_flattening_information(is_value_type) {} FieldGroup* FieldLayoutBuilder::get_or_create_contended_group(int g) { assert(g > 0, "must only be called for named contended groups"); FieldGroup* fg = NULL; for (int i = 0; i < _contended_groups.length(); i++) { --- 537,550 ---- _first_field_offset(-1), _exact_size_in_bytes(-1), _has_nonstatic_fields(false), _is_contended(is_contended), _is_value_type(is_value_type), ! _has_flattening_information(is_value_type), ! _has_nonatomic_values(false), ! _atomic_field_count(0) ! {} FieldGroup* FieldLayoutBuilder::get_or_create_contended_group(int g) { assert(g > 0, "must only be called for named contended groups"); FieldGroup* fg = NULL; for (int i = 0; i < _contended_groups.length(); i++) {
*** 577,586 **** --- 580,590 ---- FieldGroup* group = NULL; if (fs.access_flags().is_static()) { group = _static_fields; } else { _has_nonstatic_fields = true; + _atomic_field_count++; // we might decrement this if (fs.is_contended()) { int g = fs.contended_group(); if (g == 0) { group = new FieldGroup(true); _contended_groups.append(group);
*** 624,641 **** SystemDictionary::resolve_flattenable_field_or_fail(&fs, Handle(THREAD, _class_loader_data->class_loader()), _protection_domain, true, THREAD); assert(klass != NULL, "Sanity check"); ValueKlass* vk = ValueKlass::cast(klass); ! bool has_flattenable_size = (ValueFieldMaxFlatSize < 0) ! || (vk->size_helper() * HeapWordSize) <= ValueFieldMaxFlatSize; // volatile fields are currently never flattened, this could change in the future ! bool flattened = !fs.access_flags().is_volatile() && has_flattenable_size; ! if (flattened) { group->add_flattened_field(fs, vk); _nonstatic_oopmap_count += vk->nonstatic_oop_map_count(); fs.set_flattened(true); } else { _nonstatic_oopmap_count++; group->add_oop_field(fs); } } --- 628,654 ---- SystemDictionary::resolve_flattenable_field_or_fail(&fs, Handle(THREAD, _class_loader_data->class_loader()), _protection_domain, true, THREAD); assert(klass != NULL, "Sanity check"); ValueKlass* vk = ValueKlass::cast(klass); ! bool too_big_to_flatten = (ValueFieldMaxFlatSize >= 0 && ! (vk->size_helper() * HeapWordSize) > ValueFieldMaxFlatSize); ! bool too_atomic_to_flatten = vk->is_declared_atomic(); ! bool too_volatile_to_flatten = fs.access_flags().is_volatile(); ! if (vk->is_naturally_atomic()) { ! too_atomic_to_flatten = false; ! //too_volatile_to_flatten = false; //FIXME // volatile fields are currently never flattened, this could change in the future ! } ! if (!(too_big_to_flatten | too_atomic_to_flatten | too_volatile_to_flatten)) { group->add_flattened_field(fs, vk); _nonstatic_oopmap_count += vk->nonstatic_oop_map_count(); fs.set_flattened(true); + if (!vk->is_atomic()) { // flat and non-atomic: take note + _has_nonatomic_values = true; + _atomic_field_count--; // every other field is atomic but this one + } } else { _nonstatic_oopmap_count++; group->add_oop_field(fs); } }
*** 672,681 **** --- 685,695 ---- int field_alignment = 1; if (fs.access_flags().is_static()) { group = _static_fields; } else { _has_nonstatic_fields = true; + _atomic_field_count++; // we might decrement this group = _root_group; } assert(group != NULL, "invariant"); BasicType type = Signature::basic_type(fs.signature()); switch(type) {
*** 714,730 **** SystemDictionary::resolve_flattenable_field_or_fail(&fs, Handle(THREAD, _class_loader_data->class_loader()), _protection_domain, true, CHECK); assert(klass != NULL, "Sanity check"); ValueKlass* vk = ValueKlass::cast(klass); ! bool flattened = (ValueFieldMaxFlatSize < 0) ! || (vk->size_helper() * HeapWordSize) <= ValueFieldMaxFlatSize; ! if (flattened) { group->add_flattened_field(fs, vk); _nonstatic_oopmap_count += vk->nonstatic_oop_map_count(); field_alignment = vk->get_alignment(); fs.set_flattened(true); } else { _nonstatic_oopmap_count++; field_alignment = type2aelembytes(T_OBJECT); group->add_oop_field(fs); } --- 728,755 ---- SystemDictionary::resolve_flattenable_field_or_fail(&fs, Handle(THREAD, _class_loader_data->class_loader()), _protection_domain, true, CHECK); assert(klass != NULL, "Sanity check"); ValueKlass* vk = ValueKlass::cast(klass); ! bool too_big_to_flatten = (ValueFieldMaxFlatSize >= 0 && ! (vk->size_helper() * HeapWordSize) > ValueFieldMaxFlatSize); ! bool too_atomic_to_flatten = vk->is_declared_atomic(); ! bool too_volatile_to_flatten = fs.access_flags().is_volatile(); ! if (vk->is_naturally_atomic()) { ! too_atomic_to_flatten = false; ! //too_volatile_to_flatten = false; //FIXME ! // volatile fields are currently never flattened, this could change in the future ! } ! if (!(too_big_to_flatten | too_atomic_to_flatten | too_volatile_to_flatten)) { group->add_flattened_field(fs, vk); _nonstatic_oopmap_count += vk->nonstatic_oop_map_count(); field_alignment = vk->get_alignment(); fs.set_flattened(true); + if (!vk->is_atomic()) { // flat and non-atomic: take note + _has_nonatomic_values = true; + _atomic_field_count--; // every other field is atomic but this one + } } else { _nonstatic_oopmap_count++; field_alignment = type2aelembytes(T_OBJECT); group->add_oop_field(fs); }
*** 981,990 **** --- 1006,1028 ---- _info->_instance_size = align_object_size(instance_end / wordSize); _info->_static_field_size = static_fields_size; _info->_nonstatic_field_size = (nonstatic_field_end - instanceOopDesc::base_offset_in_bytes()) / heapOopSize; _info->_has_nonstatic_fields = _has_nonstatic_fields; + // A value type is naturally atomic if it has just one field, and + // that field is simple enough. + _info->_is_naturally_atomic = (_is_value_type && + (_atomic_field_count <= 1) && + !_has_nonatomic_values && + _contended_groups.is_empty()); + // This may be too restrictive, since if all the fields fit in 64 + // bits we could make the decision to align instances of this class + // to 64-bit boundaries, and load and store them as single words. + // And on machines which supported larger atomics we could similarly + // allow larger values to be atomic, if properly aligned. + + if (PrintFieldLayout) { ResourceMark rm; tty->print_cr("Layout of class %s", _classname->as_C_string()); tty->print_cr("Instance fields:"); _layout->print(tty, false, _super_klass);
< prev index next >