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