795 load = new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo, control_dependency); |
795 load = new LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo, control_dependency); |
796 } else |
796 } else |
797 #endif |
797 #endif |
798 { |
798 { |
799 assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop"); |
799 assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop"); |
800 load = new LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo, control_dependency); |
800 load = new LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr(), mo, control_dependency); |
801 } |
801 } |
802 break; |
802 break; |
803 } |
803 } |
804 assert(load != NULL, "LoadNode should have been created"); |
804 assert(load != NULL, "LoadNode should have been created"); |
805 if (unaligned) { |
805 if (unaligned) { |
1619 |
1619 |
1620 // No match. |
1620 // No match. |
1621 return NULL; |
1621 return NULL; |
1622 } |
1622 } |
1623 |
1623 |
1624 static ciConstant check_mismatched_access(ciConstant con, BasicType loadbt, bool is_unsigned) { |
|
1625 BasicType conbt = con.basic_type(); |
|
1626 switch (conbt) { |
|
1627 case T_BOOLEAN: conbt = T_BYTE; break; |
|
1628 case T_ARRAY: conbt = T_OBJECT; break; |
|
1629 } |
|
1630 switch (loadbt) { |
|
1631 case T_BOOLEAN: loadbt = T_BYTE; break; |
|
1632 case T_NARROWOOP: loadbt = T_OBJECT; break; |
|
1633 case T_ARRAY: loadbt = T_OBJECT; break; |
|
1634 case T_ADDRESS: loadbt = T_OBJECT; break; |
|
1635 } |
|
1636 if (conbt == loadbt) { |
|
1637 if (is_unsigned && conbt == T_BYTE) { |
|
1638 // LoadB (T_BYTE) with a small mask (<=8-bit) is converted to LoadUB (T_BYTE). |
|
1639 return ciConstant(T_INT, con.as_int() & 0xFF); |
|
1640 } else { |
|
1641 return con; |
|
1642 } |
|
1643 } |
|
1644 if (conbt == T_SHORT && loadbt == T_CHAR) { |
|
1645 // LoadS (T_SHORT) with a small mask (<=16-bit) is converted to LoadUS (T_CHAR). |
|
1646 return ciConstant(T_INT, con.as_int() & 0xFFFF); |
|
1647 } |
|
1648 return ciConstant(); // T_ILLEGAL |
|
1649 } |
|
1650 |
|
1651 // Try to constant-fold a stable array element. |
|
1652 static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, bool is_unsigned_load, BasicType loadbt) { |
|
1653 assert(ary->const_oop(), "array should be constant"); |
|
1654 assert(ary->is_stable(), "array should be stable"); |
|
1655 |
|
1656 // Decode the results of GraphKit::array_element_address. |
|
1657 ciArray* aobj = ary->const_oop()->as_array(); |
|
1658 ciConstant element_value = aobj->element_value_by_offset(off); |
|
1659 if (element_value.basic_type() == T_ILLEGAL) { |
|
1660 return NULL; // wrong offset |
|
1661 } |
|
1662 ciConstant con = check_mismatched_access(element_value, loadbt, is_unsigned_load); |
|
1663 assert(con.basic_type() != T_ILLEGAL, "elembt=%s; loadbt=%s; unsigned=%d", |
|
1664 type2name(element_value.basic_type()), type2name(loadbt), is_unsigned_load); |
|
1665 |
|
1666 if (con.basic_type() != T_ILLEGAL && // not a mismatched access |
|
1667 !con.is_null_or_zero()) { // not a default value |
|
1668 const Type* con_type = Type::make_from_constant(con); |
|
1669 if (con_type != NULL) { |
|
1670 if (con_type->isa_aryptr()) { |
|
1671 // Join with the array element type, in case it is also stable. |
|
1672 int dim = ary->stable_dimension(); |
|
1673 con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1); |
|
1674 } |
|
1675 if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) { |
|
1676 con_type = con_type->make_narrowoop(); |
|
1677 } |
|
1678 #ifndef PRODUCT |
|
1679 if (TraceIterativeGVN) { |
|
1680 tty->print("FoldStableValues: array element [off=%d]: con_type=", off); |
|
1681 con_type->dump(); tty->cr(); |
|
1682 } |
|
1683 #endif //PRODUCT |
|
1684 return con_type; |
|
1685 } |
|
1686 } |
|
1687 return NULL; |
|
1688 } |
|
1689 |
|
1690 //------------------------------Value----------------------------------------- |
1624 //------------------------------Value----------------------------------------- |
1691 const Type* LoadNode::Value(PhaseGVN* phase) const { |
1625 const Type* LoadNode::Value(PhaseGVN* phase) const { |
1692 // Either input is TOP ==> the result is TOP |
1626 // Either input is TOP ==> the result is TOP |
1693 Node* mem = in(MemNode::Memory); |
1627 Node* mem = in(MemNode::Memory); |
1694 const Type *t1 = phase->type(mem); |
1628 const Type *t1 = phase->type(mem); |
1713 // possible base offset. |
1647 // possible base offset. |
1714 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); |
1648 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); |
1715 const bool off_beyond_header = ((uint)off >= (uint)min_base_off); |
1649 const bool off_beyond_header = ((uint)off >= (uint)min_base_off); |
1716 |
1650 |
1717 // Try to constant-fold a stable array element. |
1651 // Try to constant-fold a stable array element. |
1718 if (FoldStableValues && !is_mismatched_access() && ary->is_stable() && ary->const_oop() != NULL) { |
1652 if (FoldStableValues && !is_mismatched_access() && ary->is_stable()) { |
1719 // Make sure the reference is not into the header and the offset is constant |
1653 // Make sure the reference is not into the header and the offset is constant |
1720 if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) { |
1654 ciObject* aobj = ary->const_oop(); |
1721 const Type* con_type = fold_stable_ary_elem(ary, off, is_unsigned(), memory_type()); |
1655 if (aobj != NULL && off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) { |
|
1656 int stable_dimension = (ary->stable_dimension() > 0 ? ary->stable_dimension() - 1 : 0); |
|
1657 const Type* con_type = Type::make_constant_from_array_element(aobj->as_array(), off, |
|
1658 stable_dimension, |
|
1659 memory_type(), is_unsigned()); |
1722 if (con_type != NULL) { |
1660 if (con_type != NULL) { |
1723 return con_type; |
1661 return con_type; |
1724 } |
1662 } |
1725 } |
1663 } |
1726 } |
1664 } |
1783 C->has_unsafe_access(), |
1721 C->has_unsafe_access(), |
1784 "Field accesses must be precise" ); |
1722 "Field accesses must be precise" ); |
1785 // For oop loads, we expect the _type to be precise. |
1723 // For oop loads, we expect the _type to be precise. |
1786 // Optimizations for constant objects |
1724 // Optimizations for constant objects |
1787 ciObject* const_oop = tinst->const_oop(); |
1725 ciObject* const_oop = tinst->const_oop(); |
1788 if (const_oop != NULL) { |
1726 if (const_oop != NULL && const_oop->is_instance()) { |
1789 // For constant CallSites treat the target field as a compile time constant. |
1727 const Type* con_type = Type::make_constant_from_field(const_oop->as_instance(), off, is_unsigned(), memory_type()); |
1790 if (const_oop->is_call_site()) { |
1728 if (con_type != NULL) { |
1791 ciCallSite* call_site = const_oop->as_call_site(); |
1729 return con_type; |
1792 ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false); |
|
1793 if (field != NULL && field->is_call_site_target()) { |
|
1794 ciMethodHandle* target = call_site->get_target(); |
|
1795 if (target != NULL) { // just in case |
|
1796 ciConstant constant(T_OBJECT, target); |
|
1797 const Type* t; |
|
1798 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
|
1799 t = TypeNarrowOop::make_from_constant(constant.as_object(), true); |
|
1800 } else { |
|
1801 t = TypeOopPtr::make_from_constant(constant.as_object(), true); |
|
1802 } |
|
1803 // Add a dependence for invalidation of the optimization. |
|
1804 if (!call_site->is_constant_call_site()) { |
|
1805 C->dependencies()->assert_call_site_target_value(call_site, target); |
|
1806 } |
|
1807 return t; |
|
1808 } |
|
1809 } |
|
1810 } |
1730 } |
1811 } |
1731 } |
1812 } else if (tp->base() == Type::KlassPtr) { |
1732 } else if (tp->base() == Type::KlassPtr) { |
1813 assert( off != Type::OffsetBot || |
1733 assert( off != Type::OffsetBot || |
1814 // arrays can be cast to Objects |
1734 // arrays can be cast to Objects |
2977 case Op_StoreFence: return new StoreFenceNode(C, atp, pn); |
2897 case Op_StoreFence: return new StoreFenceNode(C, atp, pn); |
2978 case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn); |
2898 case Op_MemBarAcquireLock: return new MemBarAcquireLockNode(C, atp, pn); |
2979 case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn); |
2899 case Op_MemBarReleaseLock: return new MemBarReleaseLockNode(C, atp, pn); |
2980 case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn); |
2900 case Op_MemBarVolatile: return new MemBarVolatileNode(C, atp, pn); |
2981 case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn); |
2901 case Op_MemBarCPUOrder: return new MemBarCPUOrderNode(C, atp, pn); |
|
2902 case Op_OnSpinWait: return new OnSpinWaitNode(C, atp, pn); |
2982 case Op_Initialize: return new InitializeNode(C, atp, pn); |
2903 case Op_Initialize: return new InitializeNode(C, atp, pn); |
2983 case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); |
2904 case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn); |
2984 default: ShouldNotReachHere(); return NULL; |
2905 default: ShouldNotReachHere(); return NULL; |
2985 } |
2906 } |
2986 } |
2907 } |