< 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 >