comparison src/share/vm/opto/memnode.cpp @ 17818:75ad4240c15c

8036667: "assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con()) failed: offset is a constant" with FoldStableValues on Reviewed-by: kvn
author vlivanov
date Fri, 28 Mar 2014 10:04:07 -0700
parents 752ba2e5f6d0
children 3636afd5ec1a
comparison
equal deleted inserted replaced
17815:23262dd70c13 17818:75ad4240c15c
1591 return NULL; 1591 return NULL;
1592 } 1592 }
1593 1593
1594 // Try to constant-fold a stable array element. 1594 // Try to constant-fold a stable array element.
1595 static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) { 1595 static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) {
1596 assert(ary->const_oop(), "array should be constant");
1596 assert(ary->is_stable(), "array should be stable"); 1597 assert(ary->is_stable(), "array should be stable");
1597 1598
1598 if (ary->const_oop() != NULL) { 1599 // Decode the results of GraphKit::array_element_address.
1599 // Decode the results of GraphKit::array_element_address. 1600 ciArray* aobj = ary->const_oop()->as_array();
1600 ciArray* aobj = ary->const_oop()->as_array(); 1601 ciConstant con = aobj->element_value_by_offset(off);
1601 ciConstant con = aobj->element_value_by_offset(off); 1602
1602 1603 if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) {
1603 if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) { 1604 const Type* con_type = Type::make_from_constant(con);
1604 const Type* con_type = Type::make_from_constant(con); 1605 if (con_type != NULL) {
1605 if (con_type != NULL) { 1606 if (con_type->isa_aryptr()) {
1606 if (con_type->isa_aryptr()) { 1607 // Join with the array element type, in case it is also stable.
1607 // Join with the array element type, in case it is also stable. 1608 int dim = ary->stable_dimension();
1608 int dim = ary->stable_dimension(); 1609 con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
1609 con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1); 1610 }
1610 } 1611 if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
1611 if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) { 1612 con_type = con_type->make_narrowoop();
1612 con_type = con_type->make_narrowoop(); 1613 }
1613 }
1614 #ifndef PRODUCT 1614 #ifndef PRODUCT
1615 if (TraceIterativeGVN) { 1615 if (TraceIterativeGVN) {
1616 tty->print("FoldStableValues: array element [off=%d]: con_type=", off); 1616 tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
1617 con_type->dump(); tty->cr(); 1617 con_type->dump(); tty->cr();
1618 } 1618 }
1619 #endif //PRODUCT 1619 #endif //PRODUCT
1620 return con_type; 1620 return con_type;
1621 } 1621 }
1622 } 1622 }
1623 }
1624
1625 return NULL; 1623 return NULL;
1626 } 1624 }
1627 1625
1628 //------------------------------Value----------------------------------------- 1626 //------------------------------Value-----------------------------------------
1629 const Type *LoadNode::Value( PhaseTransform *phase ) const { 1627 const Type *LoadNode::Value( PhaseTransform *phase ) const {
1639 Compile* C = phase->C; 1637 Compile* C = phase->C;
1640 1638
1641 // Try to guess loaded type from pointer type 1639 // Try to guess loaded type from pointer type
1642 if (tp->isa_aryptr()) { 1640 if (tp->isa_aryptr()) {
1643 const TypeAryPtr* ary = tp->is_aryptr(); 1641 const TypeAryPtr* ary = tp->is_aryptr();
1644 const Type *t = ary->elem(); 1642 const Type* t = ary->elem();
1645 1643
1646 // Determine whether the reference is beyond the header or not, by comparing 1644 // Determine whether the reference is beyond the header or not, by comparing
1647 // the offset against the offset of the start of the array's data. 1645 // the offset against the offset of the start of the array's data.
1648 // Different array types begin at slightly different offsets (12 vs. 16). 1646 // Different array types begin at slightly different offsets (12 vs. 16).
1649 // We choose T_BYTE as an example base type that is least restrictive 1647 // We choose T_BYTE as an example base type that is least restrictive
1651 // possible base offset. 1649 // possible base offset.
1652 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); 1650 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE);
1653 const bool off_beyond_header = ((uint)off >= (uint)min_base_off); 1651 const bool off_beyond_header = ((uint)off >= (uint)min_base_off);
1654 1652
1655 // Try to constant-fold a stable array element. 1653 // Try to constant-fold a stable array element.
1656 if (FoldStableValues && ary->is_stable()) { 1654 if (FoldStableValues && ary->is_stable() && ary->const_oop() != NULL) {
1657 // Make sure the reference is not into the header 1655 // Make sure the reference is not into the header and the offset is constant
1658 if (off_beyond_header && off != Type::OffsetBot) { 1656 if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) {
1659 assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant");
1660 const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); 1657 const Type* con_type = fold_stable_ary_elem(ary, off, memory_type());
1661 if (con_type != NULL) { 1658 if (con_type != NULL) {
1662 return con_type; 1659 return con_type;
1663 } 1660 }
1664 } 1661 }