< 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,11 +537,14 @@
_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_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,10 +580,11 @@
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,18 +628,27 @@
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;
+ 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
- bool flattened = !fs.access_flags().is_volatile() && has_flattenable_size;
- if (flattened) {
+ }
+ 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,10 +685,11 @@
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,17 +728,28 @@
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) {
+ 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,10 +1006,23 @@
_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 >