--- old/src/hotspot/share/ci/ciField.cpp 2019-03-11 14:25:20.530355786 +0100 +++ new/src/hotspot/share/ci/ciField.cpp 2019-03-11 14:25:20.318355789 +0100 @@ -68,7 +68,7 @@ // ------------------------------------------------------------------ // ciField::ciField ciField::ciField(ciInstanceKlass* klass, int index) : - _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { + _is_flattened(false), _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { ASSERT_IN_VM; CompilerThread *THREAD = CompilerThread::current(); @@ -91,7 +91,7 @@ // If the field is a pointer type, get the klass of the // field. - if (field_type == T_OBJECT || field_type == T_ARRAY) { + if (field_type == T_OBJECT || field_type == T_ARRAY || field_type == T_VALUETYPE) { bool ignore; // This is not really a class reference; the index always refers to the // field's type signature, as a symbol. Linkage checks do not apply. @@ -200,7 +200,7 @@ // If the field is a pointer type, get the klass of the // field. - if (field_type == T_OBJECT || field_type == T_ARRAY) { + if (field_type == T_OBJECT || field_type == T_ARRAY || field_type == T_VALUETYPE) { _type = NULL; // must call compute_type on first access } else { _type = ciType::make(field_type); @@ -213,6 +213,30 @@ "bootstrap classes must not create & cache unshared fields"); } +// Special copy constructor used to flatten value type fields by +// copying the fields of the value type to a new holder klass. +ciField::ciField(ciField* field, ciInstanceKlass* holder, int offset, bool is_final) { + assert(field->holder()->is_valuetype(), "should only be used for value type field flattening"); + // Set the is_final flag + jint final = is_final ? JVM_ACC_FINAL : ~JVM_ACC_FINAL; + AccessFlags flags(field->flags().as_int() & final); + _flags = ciFlags(flags); + _holder = holder; + _offset = offset; + // Copy remaining fields + _name = field->_name; + _signature = field->_signature; + _type = field->_type; + _is_constant = field->_is_constant; + _known_to_link_with_put = field->_known_to_link_with_put; + _known_to_link_with_get = field->_known_to_link_with_get; + _constant_value = field->_constant_value; + assert(!field->is_flattened(), "field must not be flattened"); + assert(!field->is_flattenable(), "field must not be flattenable"); + _is_flattened = false; + _is_flattenable = false; +} + static bool trust_final_non_static_fields(ciInstanceKlass* holder) { if (holder == NULL) return false; @@ -250,6 +274,8 @@ Klass* field_holder = fd->field_holder(); assert(field_holder != NULL, "null field_holder"); _holder = CURRENT_ENV->get_instance_klass(field_holder); + _is_flattened = fd->is_flattened(); + _is_flattenable = fd->is_flattenable(); // Check to see if the field is constant. Klass* k = _holder->get_Klass(); @@ -362,8 +388,8 @@ Bytecodes::Code bc) { VM_ENTRY_MARK; assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic || - bc == Bytecodes::_getfield || bc == Bytecodes::_putfield, - "unexpected bytecode"); + bc == Bytecodes::_getfield || bc == Bytecodes::_putfield || + bc == Bytecodes::_withfield, "unexpected bytecode"); if (_offset == -1) { // at creation we couldn't link to our holder so we need to