--- old/src/share/vm/opto/parse3.cpp 2017-06-08 15:52:05.969058534 +0200 +++ new/src/share/vm/opto/parse3.cpp 2017-06-08 15:52:05.885058537 +0200 @@ -546,25 +546,25 @@ // Obtain source type ValueTypeNode* vt = peek()->as_ValueType(); - const TypeValueType* source_type = gvn().type(vt)->isa_valuetype(); - guarantee(source_type != NULL && source_type->value_klass() != NULL && source_type->value_klass()->is_loaded(), - "vbox: Source class must be a value type and must be loaded"); - - ciInstanceKlass* target_vcc_klass = target_klass->as_instance_klass(); - guarantee(target_vcc_klass->derive_value_type() != NULL, "vbox: Target class must have a derived value type class linked"); - ciValueKlass* target_dvt_klass = target_vcc_klass->derive_value_type()->as_value_klass(); + const TypeValueType* src_type = gvn().type(vt)->isa_valuetype(); + guarantee(src_type != NULL, "vbox: Source type must not be null"); + ciValueKlass* src_vk = src_type->value_klass(); + guarantee(src_vk != NULL && src_vk->is_loaded() && src_vk->exact_klass(), + "vbox: Source class must be a value type and must be loaded and exact"); kill_dead_locals(); + ciInstanceKlass* target_vcc_klass = target_klass->as_instance_klass(); + ciInstanceKlass* target_dvt_klass = target_vcc_klass->derive_value_type(); + // TODO: Extend type check below if (and once) value type class hierarchies become available. // (incl. extension to support dynamic type checks). - guarantee(source_type->value_klass()->exact_klass(), "Value type classes are exact"); - if (!source_type->value_klass()->equals(target_dvt_klass)) { + if (!src_vk->equals(target_dvt_klass)) { builtin_throw(Deoptimization::Reason_class_check); guarantee(stopped(), "A ClassCastException must be always thrown on this path"); return; } - + guarantee(target_dvt_klass->is_valuetype(), "vbox: Target DVT must be a value type"); pop(); // Create new object @@ -596,7 +596,7 @@ bool will_link; ciKlass* target_klass = iter().get_klass(will_link); guarantee(will_link, "vunbox: Derived value type must be loaded"); - guarantee(target_klass->is_valuetype(), "vunbox: Target class must be a value type"); + guarantee(target_klass->is_instance_klass(), "vunbox: Target class must be an instance type"); // Obtain source type const TypeOopPtr* source_type = gvn().type(not_null_obj)->isa_oopptr(); @@ -604,19 +604,19 @@ source_type->klass()->is_instance_klass() && source_type->klass()->is_loaded(), "vunbox: Source class must be an instance type and must be loaded"); - ciValueKlass* target_dvt_klass = target_klass->as_value_klass(); - guarantee(target_dvt_klass->derive_value_type() != NULL, "vunbox: Target class must have a value-capable class linked"); - ciInstanceKlass* target_vcc_klass = target_dvt_klass->derive_value_type()->as_instance_klass(); + ciInstanceKlass* target_dvt_klass = target_klass->as_instance_klass(); + ciInstanceKlass* target_vcc_klass = target_dvt_klass->derive_value_type(); // Check if the class of the source is a subclass of the value-capable class // corresponding to the target. // TOOD: Implement profiling of vunbox bytecodes to enable type speculation. - if (!target_vcc_klass->is_subclass_of(source_type->klass())) { + if (target_vcc_klass == NULL || !source_type->klass()->is_subclass_of(target_vcc_klass)) { // It is obvious at compile-time that source and target are unrelated. builtin_throw(Deoptimization::Reason_class_check); guarantee(stopped(), "A ClassCastException must be always thrown on this path"); return; } + guarantee(target_dvt_klass->is_valuetype(), "vunbox: Target DVT must be a value type"); if (!target_vcc_klass->equals(source_type->klass()) || !source_type->klass_is_exact()) { Node* exact_obj = not_null_obj; @@ -634,7 +634,8 @@ pop(); // Create a value type node with the corresponding type - Node* vt = ValueTypeNode::make(gvn(), target_dvt_klass, map()->memory(), not_null_obj, not_null_obj, target_vcc_klass, target_dvt_klass->first_field_offset()); + ciValueKlass* vk = target_dvt_klass->as_value_klass(); + Node* vt = ValueTypeNode::make(gvn(), vk, map()->memory(), not_null_obj, not_null_obj, target_vcc_klass, vk->first_field_offset()); // Push the value type onto the stack push(vt);