< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

*** 63,93 **** // 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 Node* vt = ValueTypeNode::make_from_flattened(this, elemtype->value_klass(), ary, adr); push(vt); return; } else if (elemptr != NULL && elemptr->is_valuetypeptr() && !elemptr->maybe_null()) { // Load from non-flattened but flattenable value type array (elements can never be null) bt = T_VALUETYPE; } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() && !ary_t->klass_is_exact() && (!elemptr->is_valuetypeptr() || elemptr->value_klass()->flatten_array())) { // 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* tag = load_lh_array_tag(kls); 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); Node* ld = access_load_at(ary, adr, adr_type, elemptr, bt, ! IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD); ideal.sync_kit(this); ideal.set(res, ld); } ideal.else_(); { // flattened sync_kit(ideal); --- 63,95 ---- // Handle value type arrays const TypeOopPtr* elemptr = elemtype->make_oopptr(); const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr(); if (elemtype->isa_valuetype() != NULL) { + C->set_flattened_accesses(); // Load from flattened value type array Node* vt = ValueTypeNode::make_from_flattened(this, elemtype->value_klass(), ary, adr); push(vt); return; } else if (elemptr != NULL && elemptr->is_valuetypeptr() && !elemptr->maybe_null()) { // Load from non-flattened but flattenable value type array (elements can never be null) bt = T_VALUETYPE; } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() && !ary_t->klass_is_exact() && (!elemptr->is_valuetypeptr() || elemptr->value_klass()->flatten_array())) { // Cannot statically determine if array is flattened, emit runtime check + Node* ctl = control(); IdealKit ideal(this); IdealVariable res(ideal); ideal.declarations_done(); Node* kls = load_object_klass(ary); Node* tag = load_lh_array_tag(kls); 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); Node* ld = access_load_at(ary, adr, adr_type, elemptr, bt, ! IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD, ctl); ideal.sync_kit(this); ideal.set(res, ld); } ideal.else_(); { // flattened sync_kit(ideal);
*** 100,109 **** --- 102,112 ---- const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr(); Node* cast = _gvn.transform(new CheckCastPPNode(control(), ary, arytype)); adr = array_element_address(cast, idx, T_VALUETYPE, ary_t->size(), control()); Node* vt = ValueTypeNode::make_from_flattened(this, vk, cast, adr)->allocate(this, false, false)->get_oop(); ideal.set(res, vt); + ideal.sync_kit(this); } else { // Element type is unknown, emit runtime call assert(!ary_t->klass_is_exact(), "should not have exact type here"); 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));
*** 114,123 **** --- 117,132 ---- dec_sp(2); AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); assert(alloc->maybe_set_complete(&_gvn), ""); alloc->initialization()->set_complete_with_arraycopy(); + + // This membar keeps this access to an unknown flattened array + // correctly ordered with other unknown and known flattened + // array accesses. + insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES)); + BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); // Unknown value type might contain reference fields if (!bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, BarrierSetC2::Parsing)) { int base_off = sizeof(instanceOopDesc); Node* dst_base = basic_plus_adr(alloc_obj, base_off);
*** 142,156 **** "load_unknown_value", ary, idx, alloc_obj); sync_kit(ideal); } ! insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress)); ideal.set(res, alloc_obj); } - ideal.sync_kit(this); } ideal.end_if(); sync_kit(ideal); push_node(bt, _gvn.transform(ideal.value(res))); return; } --- 151,178 ---- "load_unknown_value", ary, idx, alloc_obj); sync_kit(ideal); } ! // This makes sure no other thread sees a partially initialized buffered value ! insert_mem_bar_volatile(Op_MemBarStoreStore, Compile::AliasIdxRaw, alloc->proj_out_or_null(AllocateNode::RawAddress)); ! ! // Same as MemBarCPUOrder above: keep this unknown flattened ! // array access correctly ordered with other flattened array ! // access ! insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES)); ! ! // Prevent any use of the newly allocated value before it is ! // fully initialized ! alloc_obj = new CastPPNode(alloc_obj, _gvn.type(alloc_obj), true); ! alloc_obj->set_req(0, control()); ! alloc_obj = _gvn.transform(alloc_obj); ! ! ideal.sync_kit(this); ideal.set(res, alloc_obj); } } ideal.end_if(); sync_kit(ideal); push_node(bt, _gvn.transform(ideal.value(res))); return; }
*** 193,202 **** --- 215,225 ---- 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) { + C->set_flattened_accesses(); // Store to flattened value type array if (!cast_val->is_ValueType()) { inc_sp(3); cast_val = null_check(cast_val); if (stopped()) return;
*** 267,280 **** --- 290,319 ---- val->as_ValueType()->store_flattened(this, ary, adr); ideal.sync_kit(this); } else if (!ideal.ctrl()->is_top()) { // Element type is unknown, emit runtime call assert(!ary_t->klass_is_exact(), "should not have exact type here"); + sync_kit(ideal); + + // This membar keeps this access to an unknown flattened + // array correctly ordered with other unknown and known + // flattened array accesses. + insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES)); + 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); + + sync_kit(ideal); + // Same as MemBarCPUOrder above: keep this unknown + // flattened array access correctly ordered with other + // flattened array access + insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES)); + ideal.sync_kit(this); + } } ideal.end_if(); sync_kit(ideal); return; } else {
< prev index next >