< prev index next >

src/share/vm/opto/graphKit.cpp

Print this page

        

*** 1656,1666 **** } //-------------------------array_element_address------------------------- Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, ! const TypeInt* sizetype) { uint shift = exact_log2(type2aelembytes(elembt)); 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); --- 1656,1666 ---- } //-------------------------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)); 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);
*** 1669,1679 **** return basic_plus_adr(ary, offset); } // must be correct type for alignment purposes Node* base = basic_plus_adr(ary, header); ! idx = Compile::conv_I2X_index(&_gvn, idx, sizetype); Node* scale = _gvn.transform( new LShiftXNode(idx, intcon(shift)) ); return basic_plus_adr(ary, base, scale); } //-------------------------load_array_element------------------------- --- 1669,1679 ---- return basic_plus_adr(ary, offset); } // must be correct type for alignment purposes Node* base = basic_plus_adr(ary, header); ! idx = Compile::conv_I2X_index(&_gvn, idx, sizetype, ctrl); Node* scale = _gvn.transform( new LShiftXNode(idx, intcon(shift)) ); return basic_plus_adr(ary, base, scale); } //-------------------------load_array_element-------------------------
*** 3505,3518 **** fast_size_limit <<= (LogBytesPerLong - log2_esize); } Node* initial_slow_cmp = _gvn.transform( new CmpUNode( length, intcon( fast_size_limit ) ) ); Node* initial_slow_test = _gvn.transform( new BoolNode( initial_slow_cmp, BoolTest::gt ) ); - if (initial_slow_test->is_Bool()) { - // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. - initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); - } // --- Size Computation --- // array_size = round_to_heap(array_header + (length << elem_shift)); // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes) // and round_to(x, y) == ((x + y-1) & ~(y-1)) --- 3505,3514 ----
*** 3554,3570 **** // Transition to native address size for all offset calculations: Node* lengthx = ConvI2X(length); Node* headerx = ConvI2X(header_size); #ifdef _LP64 ! { const TypeLong* tllen = _gvn.find_long_type(lengthx); ! if (tllen != NULL && tllen->_lo < 0) { // Add a manual constraint to a positive range. Cf. array_element_address. ! jlong size_max = arrayOopDesc::max_array_length(T_BYTE); ! if (size_max > tllen->_hi) size_max = tllen->_hi; ! const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); ! lengthx = _gvn.transform( new ConvI2LNode(length, tlcon)); } } #endif // Combine header size (plus rounding) and body size. Then round down. --- 3550,3588 ---- // Transition to native address size for all offset calculations: Node* lengthx = ConvI2X(length); Node* headerx = ConvI2X(header_size); #ifdef _LP64 ! { const TypeInt* tilen = _gvn.find_int_type(length); ! if (tilen != NULL && tilen->_lo < 0) { // Add a manual constraint to a positive range. Cf. array_element_address. ! jint size_max = fast_size_limit; ! if (size_max > tilen->_hi) size_max = tilen->_hi; ! const TypeInt* tlcon = TypeInt::make(0, size_max, Type::WidenMin); ! ! // Only do a narrow I2L conversion if the range check passed. ! IfNode* iff = new IfNode(control(), initial_slow_test, PROB_MIN, COUNT_UNKNOWN); ! _gvn.transform(iff); ! RegionNode* region = new RegionNode(3); ! _gvn.set_type(region, Type::CONTROL); ! lengthx = new PhiNode(region, TypeLong::LONG); ! _gvn.set_type(lengthx, TypeLong::LONG); ! ! // Range check passed. Use ConvI2L node with narrow type. ! Node* passed = IfFalse(iff); ! region->init_req(1, passed); ! // Make I2L conversion control dependent to prevent it from ! // floating above the range check during loop optimizations. ! lengthx->init_req(1, C->constrained_convI2L(&_gvn, length, tlcon, passed)); ! ! // Range check failed. Use ConvI2L with wide type because length may be invalid. ! region->init_req(2, IfTrue(iff)); ! lengthx->init_req(2, ConvI2X(length)); ! ! set_control(region); ! record_for_igvn(region); ! record_for_igvn(lengthx); } } #endif // Combine header size (plus rounding) and body size. Then round down.
*** 3591,3600 **** --- 3609,3623 ---- // 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. + initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); + } + // Create the AllocateArrayNode and its result projections AllocateArrayNode* alloc = new AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), control(), mem, i_o(), size, klass_node,
< prev index next >