--- old/src/hotspot/share/opto/macroArrayCopy.cpp 2019-05-28 15:10:35.000000000 +0200 +++ new/src/hotspot/share/opto/macroArrayCopy.cpp 2019-05-28 15:10:29.000000000 +0200 @@ -1282,11 +1282,27 @@ if (top_src != NULL && top_src->klass() != NULL) { src_elem = top_src->klass()->as_array_klass()->element_type()->basic_type(); } - if (src_elem == T_ARRAY || (src_elem == T_VALUETYPE && top_src->klass()->is_obj_array_klass())) { + if (src_elem == T_ARRAY) { src_elem = T_OBJECT; + } else if (src_elem == T_VALUETYPE && top_src->klass()->is_obj_array_klass()) { + ciObjArrayKlass* array_klass = top_src->klass()->as_obj_array_klass(); + if (top_src->klass_is_exact()) { + src_elem = T_OBJECT; + } else { + assert(!array_klass->storage_properties().is_null_free(), "klass should be exact"); + src_elem = T_CONFLICT; // either flattened or not + } } - if (dest_elem == T_ARRAY || (dest_elem == T_VALUETYPE && top_dest->klass()->is_obj_array_klass())) { + if (dest_elem == T_ARRAY) { dest_elem = T_OBJECT; + } else if (dest_elem == T_VALUETYPE && top_dest->klass()->is_obj_array_klass()) { + ciObjArrayKlass* array_klass = top_dest->klass()->as_obj_array_klass(); + if (top_dest->klass_is_exact()) { + dest_elem = T_OBJECT; + } else { + assert(!array_klass->storage_properties().is_null_free(), "klass should be exact"); + dest_elem = T_CONFLICT; // either flattened or not + } } if (ac->is_arraycopy_validated() &&