--- old/src/share/vm/opto/parseHelper.cpp 2017-06-16 14:34:20.681928421 +0200 +++ new/src/share/vm/opto/parseHelper.cpp 2017-06-16 14:34:20.317928438 +0200 @@ -27,6 +27,7 @@ #include "classfile/systemDictionary.hpp" #include "compiler/compileLog.hpp" #include "oops/objArrayKlass.hpp" +#include "oops/valueArrayKlass.hpp" #include "opto/addnode.hpp" #include "opto/memnode.hpp" #include "opto/mulnode.hpp" @@ -139,7 +140,7 @@ //------------------------------array_store_check------------------------------ // pull array from stack and check that the store is valid -void Parse::array_store_check() { +void Parse::array_store_check(bool target_is_valuetypearray) { // Shorthand access to array store elements without popping them. Node *obj = peek(0); @@ -223,7 +224,8 @@ // Come here for polymorphic array klasses // Extract the array element class - int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset()); + int element_klass_offset = in_bytes(ArrayKlass::element_klass_offset()); + Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset); // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true, // we must set a control edge from the IfTrue node created by the uncommon_trap above to the @@ -231,9 +233,22 @@ Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL, immutable_memory(), p2, tak)); - // Check (the hard way) and throw if not a subklass. - // Result is ignored, we just need the CFG effects. - gen_checkcast(obj, a_e_klass); + if (target_is_valuetypearray) { + ciKlass* target_elem_klass = gvn().type(a_e_klass)->is_klassptr()->klass(); + ciKlass* source_klass = gvn().type(obj)->is_valuetype()->value_klass(); + if (!target_elem_klass->equals(source_klass)) { + Node* slow_ctl = type_check(a_e_klass, TypeKlassPtr::make(source_klass), 1.0); + { + PreserveJVMState pjvms(this); + set_control(slow_ctl); + builtin_throw(Deoptimization::Reason_class_check); + } + } + } else { + // Check (the hard way) and throw if not a subklass. + // Result is ignored, we just need the CFG effects. + gen_checkcast(obj, a_e_klass); + } }