--- old/src/share/vm/runtime/deoptimization.cpp 2017-02-13 17:39:04.295392437 +0100 +++ new/src/share/vm/runtime/deoptimization.cpp 2017-02-13 17:39:04.231392440 +0100 @@ -39,6 +39,8 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" +#include "oops/valueArrayKlass.hpp" +#include "oops/valueArrayOop.hpp" #include "oops/valueKlass.hpp" #include "oops/verifyOopClosure.hpp" #include "prims/jvmtiThreadState.hpp" @@ -805,6 +807,10 @@ if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k()); obj = ik->allocate_instance(THREAD); + } else if (k->is_valueArray_klass()) { + ValueArrayKlass* ak = ValueArrayKlass::cast(k()); + // Value type array must be zeroed because not all memory is reassigned + obj = ak->allocate(sv->field_size(), true, THREAD); } else if (k->is_typeArray_klass()) { TypeArrayKlass* ak = TypeArrayKlass::cast(k()); assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); @@ -1059,6 +1065,20 @@ return svIndex; } +// restore fields of an eliminated value type array +void Deoptimization::reassign_value_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, valueArrayOop obj, ValueArrayKlass* vak, TRAPS) { + ValueKlass* vk = vak->element_klass(); + assert(vk->flatten_array(), "should only be used for flattened value type arrays"); + // Adjust offset to omit oop header + int base_offset = arrayOopDesc::base_offset_in_bytes(T_VALUETYPE) - ValueKlass::cast(vk)->first_field_offset(); + // Initialize all elements of the flattened value type array + for (int i = 0; i < sv->field_size(); i++) { + ScopeValue* val = sv->field_at(i); + int offset = base_offset + (i << Klass::layout_helper_log2_element_size(vak->layout_helper())); + reassign_fields_by_klass(vk, fr, reg_map, val->as_ObjectValue(), 0, (oop)obj, false /* skip_internal */, offset, CHECK); + } +} + // restore fields of all eliminated objects and arrays void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects, bool realloc_failures, bool skip_internal, TRAPS) { for (int i = 0; i < objects->length(); i++) { @@ -1076,6 +1096,9 @@ if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k()); reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal, 0, CHECK); + } else if (k->is_valueArray_klass()) { + ValueArrayKlass* vak = ValueArrayKlass::cast(k()); + reassign_value_array_elements(fr, reg_map, sv, (valueArrayOop) obj(), vak, CHECK); } else if (k->is_typeArray_klass()) { TypeArrayKlass* ak = TypeArrayKlass::cast(k()); reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());