Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/graphKit.cpp @ 23799:535618ab1c04
6675699: need comprehensive fix for unconstrained ConvI2L with narrowed type
Summary: Emit CastII to make narrow ConvI2L dependent on the corresponding range check.
Reviewed-by: kvn, roland
author | thartmann |
---|---|
date | Wed, 27 Jan 2016 09:02:51 +0100 |
parents | c1c199dde5c9 |
children | f13e777eb255 |
comparison
equal
deleted
inserted
replaced
23571:16f7b676725a | 23799:535618ab1c04 |
---|---|
1643 } | 1643 } |
1644 | 1644 |
1645 | 1645 |
1646 //-------------------------array_element_address------------------------- | 1646 //-------------------------array_element_address------------------------- |
1647 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, | 1647 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, |
1648 const TypeInt* sizetype) { | 1648 const TypeInt* sizetype, Node* ctrl) { |
1649 uint shift = exact_log2(type2aelembytes(elembt)); | 1649 uint shift = exact_log2(type2aelembytes(elembt)); |
1650 uint header = arrayOopDesc::base_offset_in_bytes(elembt); | 1650 uint header = arrayOopDesc::base_offset_in_bytes(elembt); |
1651 | 1651 |
1652 // short-circuit a common case (saves lots of confusing waste motion) | 1652 // short-circuit a common case (saves lots of confusing waste motion) |
1653 jint idx_con = find_int_con(idx, -1); | 1653 jint idx_con = find_int_con(idx, -1); |
1668 // can often be excluded, if we annotate the ConvI2L node with | 1668 // can often be excluded, if we annotate the ConvI2L node with |
1669 // a type assertion that its value is known to be a small positive | 1669 // a type assertion that its value is known to be a small positive |
1670 // number. (The prior range check has ensured this.) | 1670 // number. (The prior range check has ensured this.) |
1671 // This assertion is used by ConvI2LNode::Ideal. | 1671 // This assertion is used by ConvI2LNode::Ideal. |
1672 int index_max = max_jint - 1; // array size is max_jint, index is one less | 1672 int index_max = max_jint - 1; // array size is max_jint, index is one less |
1673 if (sizetype != NULL) index_max = sizetype->_hi - 1; | 1673 if (sizetype != NULL) index_max = sizetype->_hi - 1; |
1674 const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax); | 1674 const TypeInt* iidxtype = TypeInt::make(0, index_max, Type::WidenMax); |
1675 idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) ); | 1675 idx = C->constrained_convI2L(&_gvn, idx, iidxtype, ctrl); |
1676 #endif | 1676 #endif |
1677 Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) ); | 1677 Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) ); |
1678 return basic_plus_adr(ary, base, scale); | 1678 return basic_plus_adr(ary, base, scale); |
1679 } | 1679 } |
1680 | 1680 |
3489 fast_size_limit <<= (LogBytesPerLong - log2_esize); | 3489 fast_size_limit <<= (LogBytesPerLong - log2_esize); |
3490 } | 3490 } |
3491 | 3491 |
3492 Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) ); | 3492 Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) ); |
3493 Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) ); | 3493 Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) ); |
3494 if (initial_slow_test->is_Bool()) { | |
3495 // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. | |
3496 initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); | |
3497 } | |
3498 | 3494 |
3499 // --- Size Computation --- | 3495 // --- Size Computation --- |
3500 // array_size = round_to_heap(array_header + (length << elem_shift)); | 3496 // array_size = round_to_heap(array_header + (length << elem_shift)); |
3501 // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes) | 3497 // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes) |
3502 // and round_to(x, y) == ((x + y-1) & ~(y-1)) | 3498 // and round_to(x, y) == ((x + y-1) & ~(y-1)) |
3538 | 3534 |
3539 // Transition to native address size for all offset calculations: | 3535 // Transition to native address size for all offset calculations: |
3540 Node* lengthx = ConvI2X(length); | 3536 Node* lengthx = ConvI2X(length); |
3541 Node* headerx = ConvI2X(header_size); | 3537 Node* headerx = ConvI2X(header_size); |
3542 #ifdef _LP64 | 3538 #ifdef _LP64 |
3543 { const TypeLong* tllen = _gvn.find_long_type(lengthx); | 3539 { const TypeInt* tilen = _gvn.find_int_type(length); |
3544 if (tllen != NULL && tllen->_lo < 0) { | 3540 if (tilen != NULL && tilen->_lo < 0) { |
3545 // Add a manual constraint to a positive range. Cf. array_element_address. | 3541 // Add a manual constraint to a positive range. Cf. array_element_address. |
3546 jlong size_max = arrayOopDesc::max_array_length(T_BYTE); | 3542 jlong size_max = fast_size_limit; |
3547 if (size_max > tllen->_hi) size_max = tllen->_hi; | 3543 if (size_max > tilen->_hi) size_max = tilen->_hi; |
3548 const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); | 3544 const TypeInt* tlcon = TypeInt::make(0, size_max, Type::WidenMin); |
3549 lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon)); | 3545 |
3546 // Only do a narrow I2L conversion if the range check passed. | |
3547 IfNode* iff = new (C) IfNode(control(), initial_slow_test, PROB_MIN, COUNT_UNKNOWN); | |
3548 _gvn.transform(iff); | |
3549 RegionNode* region = new (C) RegionNode(3); | |
3550 _gvn.set_type(region, Type::CONTROL); | |
3551 lengthx = new (C) PhiNode(region, TypeLong::LONG); | |
3552 _gvn.set_type(lengthx, TypeLong::LONG); | |
3553 | |
3554 // Range check passed. Use ConvI2L node with narrow type. | |
3555 Node* passed = IfFalse(iff); | |
3556 region->init_req(1, passed); | |
3557 // Make I2L conversion control dependent to prevent it from | |
3558 // floating above the range check during loop optimizations. | |
3559 lengthx->init_req(1, C->constrained_convI2L(&_gvn, length, tlcon, passed)); | |
3560 | |
3561 // Range check failed. Use ConvI2L with wide type because length may be invalid. | |
3562 region->init_req(2, IfTrue(iff)); | |
3563 lengthx->init_req(2, ConvI2X(length)); | |
3564 | |
3565 set_control(region); | |
3566 record_for_igvn(region); | |
3567 record_for_igvn(lengthx); | |
3550 } | 3568 } |
3551 } | 3569 } |
3552 #endif | 3570 #endif |
3553 | 3571 |
3554 // Combine header size (plus rounding) and body size. Then round down. | 3572 // Combine header size (plus rounding) and body size. Then round down. |
3574 | 3592 |
3575 // The entire memory state is needed for slow path of the allocation | 3593 // The entire memory state is needed for slow path of the allocation |
3576 // since GC and deoptimization can happened. | 3594 // since GC and deoptimization can happened. |
3577 Node *mem = reset_memory(); | 3595 Node *mem = reset_memory(); |
3578 set_all_memory(mem); // Create new memory state | 3596 set_all_memory(mem); // Create new memory state |
3597 | |
3598 if (initial_slow_test->is_Bool()) { | |
3599 // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick. | |
3600 initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); | |
3601 } | |
3579 | 3602 |
3580 // Create the AllocateArrayNode and its result projections | 3603 // Create the AllocateArrayNode and its result projections |
3581 AllocateArrayNode* alloc | 3604 AllocateArrayNode* alloc |
3582 = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), | 3605 = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), |
3583 control(), mem, i_o(), | 3606 control(), mem, i_o(), |