< prev index next >
src/share/vm/opto/graphKit.cpp
Print this page
*** 1685,1694 ****
--- 1685,1699 ----
//-------------------------array_element_address-------------------------
Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
const TypeInt* sizetype, Node* ctrl) {
uint shift = exact_log2(type2aelembytes(elembt));
+ ciKlass* arytype_klass = _gvn.type(ary)->is_aryptr()->klass();
+ if (arytype_klass->is_value_array_klass()) {
+ ciValueArrayKlass* vak = arytype_klass->as_value_array_klass();
+ shift = vak->log2_element_size();
+ }
uint header = arrayOopDesc::base_offset_in_bytes(elembt);
// short-circuit a common case (saves lots of confusing waste motion)
jint idx_con = find_int_con(idx, -1);
if (idx_con >= 0) {
*** 1705,1714 ****
--- 1710,1720 ----
//-------------------------load_array_element-------------------------
Node* GraphKit::load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype) {
const Type* elemtype = arytype->elem();
BasicType elembt = elemtype->array_element_basic_type();
+ assert(elembt != T_VALUETYPE, "value types are not supported by this method");
Node* adr = array_element_address(ary, idx, elembt, arytype->size());
Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered);
return ld;
}
*** 3515,3525 ****
return set_output_for_allocation(alloc, oop_type, deoptimize_on_exception);
}
//-------------------------------new_array-------------------------------------
! // helper for both newarray and anewarray
// The 'length' parameter is (obviously) the length of the array.
// See comments on new_instance for the meaning of the other arguments.
Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
Node* length, // number of array elements
int nargs, // number of arguments to push back for uncommon trap
--- 3521,3531 ----
return set_output_for_allocation(alloc, oop_type, deoptimize_on_exception);
}
//-------------------------------new_array-------------------------------------
! // helper for newarray, anewarray and vnewarray
// The 'length' parameter is (obviously) the length of the array.
// See comments on new_instance for the meaning of the other arguments.
Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
Node* length, // number of array elements
int nargs, // number of arguments to push back for uncommon trap
*** 3576,3586 ****
int hsize = Klass::layout_helper_header_size(layout_con);
int eshift = Klass::layout_helper_log2_element_size(layout_con);
BasicType etype = Klass::layout_helper_element_type(layout_con);
if ((round_mask & ~right_n_bits(eshift)) == 0)
round_mask = 0; // strength-reduce it if it goes away completely
! assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded");
assert(header_size_min <= hsize, "generic minimum is smallest");
header_size_min = hsize;
header_size = intcon(hsize + round_mask);
} else {
Node* hss = intcon(Klass::_lh_header_size_shift);
--- 3582,3593 ----
int hsize = Klass::layout_helper_header_size(layout_con);
int eshift = Klass::layout_helper_log2_element_size(layout_con);
BasicType etype = Klass::layout_helper_element_type(layout_con);
if ((round_mask & ~right_n_bits(eshift)) == 0)
round_mask = 0; // strength-reduce it if it goes away completely
! // TODO re-enabled assert
! // assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded");
assert(header_size_min <= hsize, "generic minimum is smallest");
header_size_min = hsize;
header_size = intcon(hsize + round_mask);
} else {
Node* hss = intcon(Klass::_lh_header_size_shift);
*** 3660,3670 ****
}
// Now generate allocation code
// The entire memory state is needed for slow path of the allocation
! // since GC and deoptimization can happened.
Node *mem = reset_memory();
set_all_memory(mem); // Create new memory state
if (initial_slow_test->is_Bool()) {
// Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
--- 3667,3677 ----
}
// Now generate allocation code
// The entire memory state is needed for slow path of the allocation
! // since GC and deoptimization can happen.
Node *mem = reset_memory();
set_all_memory(mem); // Create new memory state
if (initial_slow_test->is_Bool()) {
// Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
*** 3700,3712 ****
--- 3707,3799 ----
record_for_igvn(ccast);
replace_in_map(length, ccast);
}
}
+ const TypeAryPtr* ary_ptr = ary_type->isa_aryptr();
+ ciKlass* elem_klass = ary_ptr != NULL ? ary_ptr->klass()->as_array_klass()->element_klass() : NULL;
+ //if (layout_is_con && Klass::layout_helper_element_type(layout_con) == T_VALUETYPE) {
+ if (elem_klass != NULL && elem_klass->is_valuetype()) {
+ ciValueKlass* vk = elem_klass->as_value_klass();
+ if (vk->flatten_array()) {
+ // TODO
+ } else {
+ // TODO explain this and add asserts
+ initialize_value_type_array(javaoop, length, elem_klass->as_value_klass(), nargs);
+ InitializeNode* init = alloc->initialization();
+ init->set_complete_with_arraycopy();
+ }
+ }
+
return javaoop;
}
+ void GraphKit::initialize_value_type_array(Node* array, Node* length, ciValueKlass* vk, int nargs) {
+ // Check for zero length
+ Node* null_ctl = top();
+ null_check_common(length, T_INT, false, &null_ctl, false);
+ if (stopped()) {
+ set_control(null_ctl); // Always zero
+ return;
+ }
+
+ // Prepare for merging control and IO
+ RegionNode* res_ctl = new RegionNode(3);
+ res_ctl->init_req(1, null_ctl);
+ gvn().set_type(res_ctl, Type::CONTROL);
+ record_for_igvn(res_ctl);
+ Node* res_io = PhiNode::make(res_ctl, i_o(), Type::ABIO);
+ gvn().set_type(res_io, Type::ABIO);
+ record_for_igvn(res_io);
+
+ // TODO comment
+ SafePointNode* loop_map = NULL;
+ {
+ PreserveJVMState pjvms(this);
+ // Create default value type and store it to memory
+ Node* oop = ValueTypeNode::make_default(gvn(), vk);
+ oop = oop->as_ValueType()->store_to_memory(this);
+
+ length = SubI(length, intcon(1));
+ add_predicate(nargs);
+ RegionNode* loop = new RegionNode(3);
+ loop->init_req(1, control());
+ gvn().set_type(loop, Type::CONTROL);
+ record_for_igvn(loop);
+
+ Node* index = new PhiNode(loop, TypeInt::INT);
+ index->init_req(1, intcon(0));
+ gvn().set_type(index, TypeInt::INT);
+ record_for_igvn(index);
+
+ // TODO explain why we need to capture all memory
+ PhiNode* mem = new PhiNode(loop, Type::MEMORY, TypePtr::BOTTOM);
+ mem->init_req(1, reset_memory());
+ gvn().set_type(mem, Type::MEMORY);
+ record_for_igvn(mem);
+ set_control(loop);
+ set_all_memory(mem);
+ // Initialize array element
+ Node* adr = array_element_address(array, index, T_OBJECT);
+ const TypeOopPtr* elemtype = TypeValueTypePtr::make(TypePtr::NotNull, vk); // ary_type->is_aryptr()->elem()->make_oopptr();
+ Node* store = store_oop_to_array(control(), array, adr, TypeAryPtr::OOPS, oop, elemtype, T_OBJECT, MemNode::release);
+
+ IfNode* iff = create_and_map_if(control(), Bool(CmpI(index, length), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN);
+ loop->init_req(2, IfTrue(iff));
+ mem->init_req(2, merged_memory());
+ index->init_req(2, AddI(index, intcon(1)));
+
+ res_ctl->init_req(2, IfFalse(iff));
+ res_io->set_req(2, i_o());
+ loop_map = stop();
+ }
+ // Set merged control, IO and memory
+ set_control(res_ctl);
+ set_i_o(res_io);
+ merge_memory(loop_map->merged_memory(), res_ctl, 2);
+ }
+
// The following "Ideal_foo" functions are placed here because they recognize
// the graph shapes created by the functions immediately above.
//---------------------------Ideal_allocation----------------------------------
// Given an oop pointer or raw pointer, see if it feeds from an AllocateNode.
< prev index next >