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