< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

*** 61,89 **** Node* idx = pop(); Node* ary = pop(); // Handle value type arrays const TypeOopPtr* elemptr = elemtype->make_oopptr(); if (elemtype->isa_valuetype() != NULL) { // Load from flattened value type array ciValueKlass* vk = elemtype->is_valuetype()->value_klass(); ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr); push(vt); return; } else if (elemptr != NULL && elemptr->is_valuetypeptr()) { // Load from non-flattened value type array (elements can never be null) bt = T_VALUETYPE; assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null"); ! } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type()) { // Cannot statically determine if array is flattened, emit runtime check ! gen_flattened_array_guard(ary, 2); } if (elemtype == TypeInt::BOOL) { bt = T_BOOLEAN; } else if (bt == T_OBJECT) { ! elemtype = _gvn.type(ary)->is_aryptr()->elem()->make_oopptr(); } const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt, IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD); --- 61,155 ---- Node* idx = pop(); Node* ary = pop(); // Handle value type arrays const TypeOopPtr* elemptr = elemtype->make_oopptr(); + const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr(); if (elemtype->isa_valuetype() != NULL) { // Load from flattened value type array ciValueKlass* vk = elemtype->is_valuetype()->value_klass(); ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr); push(vt); return; } else if (elemptr != NULL && elemptr->is_valuetypeptr()) { // Load from non-flattened value type array (elements can never be null) bt = T_VALUETYPE; assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null"); ! } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() && ! !ary_t->klass_is_exact()) { // Cannot statically determine if array is flattened, emit runtime check ! IdealKit ideal(this); ! IdealVariable res(ideal); ! ideal.declarations_done(); ! Node* kls = load_object_klass(ary); ! Node* lhp = basic_plus_adr(kls, in_bytes(Klass::layout_helper_offset())); ! Node* layout_val = make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered); ! Node* tag = _gvn.transform(new RShiftINode(layout_val, intcon(Klass::_lh_array_tag_shift))); ! ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); { ! // non flattened ! sync_kit(ideal); ! const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); ! elemtype = ary_t->elem()->make_oopptr(); ! Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt, ! IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD); ! ideal.sync_kit(this); ! ideal.set(res, ld); ! } ideal.else_(); { ! // flattened ! sync_kit(ideal); ! Node* k_adr = basic_plus_adr(kls, in_bytes(ArrayKlass::element_klass_offset())); ! Node* elem_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS)); ! Node* obj_size = NULL; ! kill_dead_locals(); ! inc_sp(2); ! Node* alloc_obj = new_instance(elem_klass, NULL, &obj_size, /*deoptimize_on_exception=*/true); ! dec_sp(2); ! ! AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); ! assert(alloc->maybe_set_complete(&_gvn), ""); ! alloc->initialization()->set_complete_with_arraycopy(); ! BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); ! // Unknown value type so might have reference fields ! if (!bs->array_copy_requires_gc_barriers(T_OBJECT)) { ! int base_off = sizeof(instanceOopDesc); ! Node* dst_base = basic_plus_adr(alloc_obj, base_off); ! Node* countx = obj_size; ! countx = _gvn.transform(new SubXNode(countx, MakeConX(base_off))); ! countx = _gvn.transform(new URShiftXNode(countx, intcon(LogBytesPerLong))); ! ! assert(Klass::_lh_log2_element_size_shift == 0, "use shift in place"); ! Node* elem_shift = layout_val; ! uint header = arrayOopDesc::base_offset_in_bytes(T_VALUETYPE); ! Node* base = basic_plus_adr(ary, header); ! idx = Compile::conv_I2X_index(&_gvn, idx, TypeInt::POS, control()); ! Node* scale = _gvn.transform(new LShiftXNode(idx, elem_shift)); ! Node* adr = basic_plus_adr(ary, base, scale); ! ! access_clone(control(), adr, dst_base, countx, false); ! } else { ! ideal.sync_kit(this); ! ideal.make_leaf_call(OptoRuntime::load_unknown_value_Type(), ! CAST_FROM_FN_PTR(address, OptoRuntime::load_unknown_value), ! "load_unknown_value", ! ary, idx, alloc_obj); ! sync_kit(ideal); ! } ! ! insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress)); ! ! ideal.sync_kit(this); ! ideal.set(res, alloc_obj); ! } ideal.end_if(); ! sync_kit(ideal); ! push_node(bt, ideal.value(res)); ! return; } if (elemtype == TypeInt::BOOL) { bt = T_BOOLEAN; } else if (bt == T_OBJECT) { ! elemtype = ary_t->elem()->make_oopptr(); } const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt, IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
*** 109,160 **** } Node* val = pop_node(bt); // Value to store Node* idx = pop(); // Index in the array Node* ary = pop(); // The array itself if (bt == T_OBJECT) { const TypeOopPtr* elemptr = elemtype->make_oopptr(); if (elemtype->isa_valuetype() != NULL) { // Store to flattened value type array cast_val->as_ValueType()->store_flattened(this, ary, adr); return; } else if (elemptr->is_valuetypeptr()) { // Store to non-flattened value type array ! } else if (ValueArrayFlatten && elemptr->can_be_value_type() && val->is_ValueType()) { IdealKit ideal(this); Node* kls = load_object_klass(ary); Node* lhp = basic_plus_adr(kls, in_bytes(Klass::layout_helper_offset())); Node* layout_val = make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered); layout_val = _gvn.transform(new RShiftINode(layout_val, intcon(Klass::_lh_array_tag_shift))); ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); { // non flattened sync_kit(ideal); const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); ! elemtype = _gvn.type(ary)->is_aryptr()->elem()->make_oopptr(); access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY); ideal.sync_kit(this); } ideal.else_(); { // flattened - sync_kit(ideal); // Object/interface array must be flattened, cast it const TypeValueType* vt = _gvn.type(val)->is_valuetype(); ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass()); const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr(); ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype)); adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control()); val->as_ValueType()->store_flattened(this, ary, adr); ideal.sync_kit(this); } ideal.end_if(); sync_kit(ideal); return; } } if (elemtype == TypeInt::BOOL) { bt = T_BOOLEAN; } else if (bt == T_OBJECT) { ! elemtype = _gvn.type(ary)->is_aryptr()->elem()->make_oopptr(); } const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY); --- 175,271 ---- } Node* val = pop_node(bt); // Value to store Node* idx = pop(); // Index in the array Node* ary = pop(); // The array itself + const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr(); if (bt == T_OBJECT) { const TypeOopPtr* elemptr = elemtype->make_oopptr(); + const Type* val_t = _gvn.type(val); if (elemtype->isa_valuetype() != NULL) { // Store to flattened value type array + if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) { + // Can not store null into a value type array + inc_sp(3); + uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); + return; + } cast_val->as_ValueType()->store_flattened(this, ary, adr); return; } else if (elemptr->is_valuetypeptr()) { // Store to non-flattened value type array ! if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) { ! // Can not store null into a value type array ! inc_sp(3); ! uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); ! return; ! } ! } else if (elemptr->can_be_value_type() && !ary_t->klass_is_exact() && ! (val->is_ValueType() || val_t == TypePtr::NULL_PTR || val_t->is_oopptr()->can_be_value_type())) { ! if (ValueArrayFlatten) { IdealKit ideal(this); Node* kls = load_object_klass(ary); Node* lhp = basic_plus_adr(kls, in_bytes(Klass::layout_helper_offset())); Node* layout_val = make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered); layout_val = _gvn.transform(new RShiftINode(layout_val, intcon(Klass::_lh_array_tag_shift))); ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); { // non flattened sync_kit(ideal); + if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) { + Node* null_ctl = top(); + Node* not_null_oop = null_check_oop(val, &null_ctl); + { + assert(null_ctl != top(), "expected to possibly be null") ; + PreserveJVMState pjvms(this); + set_control(null_ctl); + inc_sp(3); + uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none); + } + } + const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); ! elemtype = ary_t->elem()->make_oopptr(); access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY); ideal.sync_kit(this); } ideal.else_(); { // flattened // Object/interface array must be flattened, cast it + if (val->is_ValueType()) { + sync_kit(ideal); const TypeValueType* vt = _gvn.type(val)->is_valuetype(); ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass()); const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr(); ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype)); adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control()); val->as_ValueType()->store_flattened(this, ary, adr); ideal.sync_kit(this); + } else { + if (TypePtr::NULL_PTR->higher_equal(val_t)) { + sync_kit(ideal); + gen_value_type_array_guard(ary, val, NULL, 3); + ideal.sync_kit(this); + } + ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(), + CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value), + "store_unknown_value", + val, ary, idx); + } } ideal.end_if(); sync_kit(ideal); return; + } else { + if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) { + gen_value_type_array_guard(ary, val, NULL, 3); + } + } } } if (elemtype == TypeInt::BOOL) { bt = T_BOOLEAN; } else if (bt == T_OBJECT) { ! elemtype = ary_t->elem()->make_oopptr(); } const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt); access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
< prev index next >