1629 // Attach dimension info to stable arrays.
1630 if (FoldStableValues &&
1631 field->is_stable() && field_type == T_ARRAY && !field_value.is_null_or_zero()) {
1632 ciArray* array = field_value.as_object()->as_array();
1633 jint dimension = field->type()->as_array_klass()->dimension();
1634 value = new StableArrayConstant(array, dimension);
1635 }
1636
1637 switch (field_type) {
1638 case T_ARRAY:
1639 case T_OBJECT:
1640 if (field_value.as_object()->should_be_constant()) {
1641 return new Constant(value);
1642 }
1643 return NULL; // Not a constant.
1644 default:
1645 return new Constant(value);
1646 }
1647 }
1648
1649 void GraphBuilder::access_field(Bytecodes::Code code) {
1650 bool will_link;
1651 ciField* field = stream()->get_field(will_link);
1652 ciInstanceKlass* holder = field->holder();
1653 BasicType field_type = field->type()->basic_type();
1654 ValueType* type = as_ValueType(field_type);
1655 // call will_link again to determine if the field is valid.
1656 const bool needs_patching = !holder->is_loaded() ||
1657 !field->will_link(method(), code) ||
1658 PatchALot;
1659
1660 ValueStack* state_before = NULL;
1661 if (!holder->is_initialized() || needs_patching) {
1662 // save state before instruction for debug info when
1663 // deoptimization happens during patching
1664 state_before = copy_state_before();
1665 }
1666
1667 Value obj = NULL;
1668 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
1730 ciConstant field_value = field->constant_value_of(const_oop);
1731 if (field_value.is_valid()) {
1732 constant = make_constant(field_value, field);
1733 // For CallSite objects add a dependency for invalidation of the optimization.
1734 if (field->is_call_site_target()) {
1735 ciCallSite* call_site = const_oop->as_call_site();
1736 if (!call_site->is_constant_call_site()) {
1737 ciMethodHandle* target = field_value.as_object()->as_method_handle();
1738 dependency_recorder()->assert_call_site_target_value(call_site, target);
1739 }
1740 }
1741 }
1742 }
1743 }
1744 if (constant != NULL) {
1745 push(type, append(constant));
1746 } else {
1747 if (state_before == NULL) {
1748 state_before = copy_state_for_exception();
1749 }
1750 // Pb with test below, is_flattened() can return true for fields that are not value types
1751 // (initialization issue of ciField?)
1752 if (!(field->type()->is_valuetype() && field->is_flattened())) {
1753 LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching);
1754 Value replacement = !needs_patching ? _memory->load(load) : load;
1755 if (replacement != load) {
1756 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
1757 push(type, replacement);
1758 } else {
1759 push(type, append(load));
1760 }
1761 } else { // flattened field, not optimized solution: re-instantiate the flattened value
1762 ciValueKlass* value_klass = field->type()->as_value_klass();
1763 int flattening_offset = field->offset() - value_klass->first_field_offset();
1764 assert(field->type()->is_valuetype(), "Sanity check");
1765 scope()->set_wrote_final();
1766 scope()->set_wrote_fields();
1767 NewValueTypeInstance* new_instance = new NewValueTypeInstance(value_klass, state_before, false);
1768 _memory->new_instance(new_instance);
1769 apush(append_split(new_instance));
1770 for (int i = 0; i < holder->nof_nonstatic_fields(); i++) {
1771 ciField* inner_field = holder->nonstatic_field_at(i);
1772 int off = inner_field->offset();
1773 LoadField* load = new LoadField(obj, off + flattening_offset, inner_field, false, state_before, needs_patching);
1774 Value replacement = append(load);
1775 StoreField* store = new StoreField(new_instance, off, inner_field, replacement, false, state_before, needs_patching);
1776 append(store);
1777 }
1778 }
1779 }
1780 break;
1781 }
1782 case Bytecodes::_putfield: {
1783 Value val = pop(type);
1784 obj = apop();
1785 if (state_before == NULL) {
1786 state_before = copy_state_for_exception();
1787 }
1788 if (field->type()->basic_type() == T_BOOLEAN) {
1789 Value mask = append(new Constant(new IntConstant(1)));
1790 val = append(new LogicOp(Bytecodes::_iand, val, mask));
1791 }
1792 // Pb with test below, is_flattened() can return true for fields that are not value types
1793 // (initialization issue of ciField?) <---- FIXME
1794 if (!(field->type()->is_valuetype() && field->is_flattened())) {
1795 StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
1796 if (!needs_patching) store = _memory->store(store);
1797 if (store != NULL) {
1798 append(store);
1799 }
1800 } else {
1801 ciValueKlass* value_klass = field->type()->as_value_klass();
1802 int flattening_offset = field->offset() - value_klass->first_field_offset();
1803 for (int i = 0; i < holder->nof_nonstatic_fields(); i++) {
1804 ciField* inner_field = holder->nonstatic_field_at(i);
1805 int off = inner_field->offset();
1806 LoadField* load = new LoadField(val, off, inner_field, false, state_before, needs_patching);
1807 Value replacement = append(load);
1808 StoreField* store = new StoreField(obj, off + flattening_offset, inner_field, replacement, false, state_before, needs_patching);
1809 append(store);
1810 }
1811 }
1812 break;
1813 }
1814 default:
1815 ShouldNotReachHere();
1816 break;
1817 }
1818 }
1819
1820 // Baseline version of withfield, allocate every time
1821 void GraphBuilder::withfield(int field_index)
1822 {
1823 bool will_link;
1824 ciField* field_modify = stream()->get_field(will_link);
1825 ciInstanceKlass* holder = field_modify->holder();
1826 assert(holder->is_valuetype(), "must be a value klass");
1827 BasicType field_type = field_modify->type()->basic_type();
1828 ValueType* type = as_ValueType(field_type);
1829
1830 // call will_link again to determine if the field is valid.
1834
1835
1836 scope()->set_wrote_final();
1837 scope()->set_wrote_fields();
1838
1839 const int offset = !needs_patching ? field_modify->offset() : -1;
1840 Value val = pop(type);
1841 Value obj = apop();
1842
1843 ValueStack* state_before = copy_state_for_exception();
1844
1845 NewValueTypeInstance* new_instance = new NewValueTypeInstance(holder->as_value_klass(), state_before, false);
1846 _memory->new_instance(new_instance);
1847 apush(append_split(new_instance));
1848
1849 for (int i = 0; i < holder->nof_nonstatic_fields(); i++) {
1850 ciField* field = holder->nonstatic_field_at(i);
1851 int off = field->offset();
1852
1853 if (field->offset() != offset) {
1854 // Only load those fields who are not modified
1855 LoadField* load = new LoadField(obj, off, field, false, state_before, needs_patching);
1856 Value replacement = append(load);
1857
1858 StoreField* store = new StoreField(new_instance, off, field, replacement, false, state_before, needs_patching);
1859 append(store);
1860 }
1861 }
1862
1863 // Field to modify
1864 if (field_modify->type()->basic_type() == T_BOOLEAN) {
1865 Value mask = append(new Constant(new IntConstant(1)));
1866 val = append(new LogicOp(Bytecodes::_iand, val, mask));
1867 }
1868 StoreField* store = new StoreField(new_instance, offset, field_modify, val, false, state_before, needs_patching);
1869 append(store);
1870 }
1871
1872 Dependencies* GraphBuilder::dependency_recorder() const {
1873 assert(DeoptC1, "need debug information");
1874 return compilation()->dependency_recorder();
1875 }
1876
1877 // How many arguments do we want to profile?
1878 Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) {
1879 int n = 0;
1880 bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
1881 start = has_receiver ? 1 : 0;
1882 if (profile_arguments()) {
1883 ciProfileData* data = method()->method_data()->bci_to_data(bci());
1884 if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
1885 n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
1886 }
1887 }
1888 // If we are inlining then we need to collect arguments to profile parameters for the target
1889 if (profile_parameters() && target != NULL) {
|
1629 // Attach dimension info to stable arrays.
1630 if (FoldStableValues &&
1631 field->is_stable() && field_type == T_ARRAY && !field_value.is_null_or_zero()) {
1632 ciArray* array = field_value.as_object()->as_array();
1633 jint dimension = field->type()->as_array_klass()->dimension();
1634 value = new StableArrayConstant(array, dimension);
1635 }
1636
1637 switch (field_type) {
1638 case T_ARRAY:
1639 case T_OBJECT:
1640 if (field_value.as_object()->should_be_constant()) {
1641 return new Constant(value);
1642 }
1643 return NULL; // Not a constant.
1644 default:
1645 return new Constant(value);
1646 }
1647 }
1648
1649 void GraphBuilder::copy_value_content(ciValueKlass* vk, Value src, int src_off, Value dest, int dest_off,
1650 ValueStack* state_before, bool needs_patching) {
1651 for (int i = 0; i < vk->nof_nonstatic_fields(); i++) {
1652 ciField* inner_field = vk->nonstatic_field_at(i);
1653 int off = inner_field->offset() - vk->first_field_offset();
1654 if (inner_field->is_flattened()) {
1655 assert(inner_field->type()->is_valuetype(), "Sanity check");
1656 copy_value_content(inner_field->type()->as_value_klass(), src, src_off + off, dest, dest_off + off,
1657 state_before, needs_patching);
1658 } else {
1659 LoadField* load = new LoadField(src, src_off + off, inner_field, false, state_before, needs_patching);
1660 Value replacement = append(load);
1661 StoreField* store = new StoreField(dest, dest_off + off, inner_field, replacement, false, state_before, needs_patching);
1662 append(store);
1663 }
1664 }
1665 }
1666
1667 void GraphBuilder::access_field(Bytecodes::Code code) {
1668 bool will_link;
1669 ciField* field = stream()->get_field(will_link);
1670 ciInstanceKlass* holder = field->holder();
1671 BasicType field_type = field->type()->basic_type();
1672 ValueType* type = as_ValueType(field_type);
1673 // call will_link again to determine if the field is valid.
1674 const bool needs_patching = !holder->is_loaded() ||
1675 !field->will_link(method(), code) ||
1676 PatchALot;
1677
1678 ValueStack* state_before = NULL;
1679 if (!holder->is_initialized() || needs_patching) {
1680 // save state before instruction for debug info when
1681 // deoptimization happens during patching
1682 state_before = copy_state_before();
1683 }
1684
1685 Value obj = NULL;
1686 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
1748 ciConstant field_value = field->constant_value_of(const_oop);
1749 if (field_value.is_valid()) {
1750 constant = make_constant(field_value, field);
1751 // For CallSite objects add a dependency for invalidation of the optimization.
1752 if (field->is_call_site_target()) {
1753 ciCallSite* call_site = const_oop->as_call_site();
1754 if (!call_site->is_constant_call_site()) {
1755 ciMethodHandle* target = field_value.as_object()->as_method_handle();
1756 dependency_recorder()->assert_call_site_target_value(call_site, target);
1757 }
1758 }
1759 }
1760 }
1761 }
1762 if (constant != NULL) {
1763 push(type, append(constant));
1764 } else {
1765 if (state_before == NULL) {
1766 state_before = copy_state_for_exception();
1767 }
1768
1769 if (!field->is_flattened()) {
1770 LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching);
1771 Value replacement = !needs_patching ? _memory->load(load) : load;
1772 if (replacement != load) {
1773 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
1774 push(type, replacement);
1775 } else {
1776 push(type, append(load));
1777 }
1778 } else { // flattened field, not optimized solution: re-instantiate the flattened value
1779 assert(field->type()->is_valuetype(), "Sanity check");
1780 ciValueKlass* value_klass = field->type()->as_value_klass();
1781 int flattening_offset = field->offset() - value_klass->first_field_offset();
1782 assert(field->type()->is_valuetype(), "Sanity check");
1783 scope()->set_wrote_final();
1784 scope()->set_wrote_fields();
1785 NewValueTypeInstance* new_instance = new NewValueTypeInstance(value_klass, state_before, false);
1786 _memory->new_instance(new_instance);
1787 apush(append_split(new_instance));
1788 copy_value_content(value_klass, obj, field->offset() , new_instance, value_klass->first_field_offset(),
1789 state_before, needs_patching);
1790 }
1791 }
1792 break;
1793 }
1794 case Bytecodes::_putfield: {
1795 Value val = pop(type);
1796 obj = apop();
1797 if (state_before == NULL) {
1798 state_before = copy_state_for_exception();
1799 }
1800 if (field->type()->basic_type() == T_BOOLEAN) {
1801 Value mask = append(new Constant(new IntConstant(1)));
1802 val = append(new LogicOp(Bytecodes::_iand, val, mask));
1803 }
1804
1805 if (!field->is_flattened()) {
1806 StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
1807 if (!needs_patching) store = _memory->store(store);
1808 if (store != NULL) {
1809 append(store);
1810 }
1811 } else {
1812 assert(field->type()->is_valuetype(), "Sanity check");
1813 ciValueKlass* value_klass = field->type()->as_value_klass();
1814 int flattening_offset = field->offset() - value_klass->first_field_offset();
1815 copy_value_content(value_klass, val, value_klass->first_field_offset(), obj, field->offset(),
1816 state_before, needs_patching);
1817 }
1818 break;
1819 }
1820 default:
1821 ShouldNotReachHere();
1822 break;
1823 }
1824 }
1825
1826 // Baseline version of withfield, allocate every time
1827 void GraphBuilder::withfield(int field_index)
1828 {
1829 bool will_link;
1830 ciField* field_modify = stream()->get_field(will_link);
1831 ciInstanceKlass* holder = field_modify->holder();
1832 assert(holder->is_valuetype(), "must be a value klass");
1833 BasicType field_type = field_modify->type()->basic_type();
1834 ValueType* type = as_ValueType(field_type);
1835
1836 // call will_link again to determine if the field is valid.
1840
1841
1842 scope()->set_wrote_final();
1843 scope()->set_wrote_fields();
1844
1845 const int offset = !needs_patching ? field_modify->offset() : -1;
1846 Value val = pop(type);
1847 Value obj = apop();
1848
1849 ValueStack* state_before = copy_state_for_exception();
1850
1851 NewValueTypeInstance* new_instance = new NewValueTypeInstance(holder->as_value_klass(), state_before, false);
1852 _memory->new_instance(new_instance);
1853 apush(append_split(new_instance));
1854
1855 for (int i = 0; i < holder->nof_nonstatic_fields(); i++) {
1856 ciField* field = holder->nonstatic_field_at(i);
1857 int off = field->offset();
1858
1859 if (field->offset() != offset) {
1860 if (field->is_flattened()) {
1861 assert(field->type()->is_valuetype(), "Sanity check");
1862 assert(field->type()->is_valuetype(), "Only value types can be flattened");
1863 ciValueKlass* vk = field->type()->as_value_klass();
1864 copy_value_content(vk, obj, off, new_instance, vk->first_field_offset(), state_before, needs_patching);
1865 } else {
1866 // Only load those fields who are not modified
1867 LoadField* load = new LoadField(obj, off, field, false, state_before, needs_patching);
1868 Value replacement = append(load);
1869 StoreField* store = new StoreField(new_instance, off, field, replacement, false, state_before, needs_patching);
1870 append(store);
1871 }
1872 }
1873 }
1874
1875 // Field to modify
1876 if (field_modify->type()->basic_type() == T_BOOLEAN) {
1877 Value mask = append(new Constant(new IntConstant(1)));
1878 val = append(new LogicOp(Bytecodes::_iand, val, mask));
1879 }
1880 if (field_modify->is_flattened()) {
1881 assert(field_modify->type()->is_valuetype(), "Only value types can be flattened");
1882 ciValueKlass* vk = field_modify->type()->as_value_klass();
1883 copy_value_content(vk, val, vk->first_field_offset(), new_instance, field_modify->offset(), state_before, needs_patching);
1884 } else {
1885 StoreField* store = new StoreField(new_instance, offset, field_modify, val, false, state_before, needs_patching);
1886 append(store);
1887 }
1888 }
1889
1890 Dependencies* GraphBuilder::dependency_recorder() const {
1891 assert(DeoptC1, "need debug information");
1892 return compilation()->dependency_recorder();
1893 }
1894
1895 // How many arguments do we want to profile?
1896 Values* GraphBuilder::args_list_for_profiling(ciMethod* target, int& start, bool may_have_receiver) {
1897 int n = 0;
1898 bool has_receiver = may_have_receiver && Bytecodes::has_receiver(method()->java_code_at_bci(bci()));
1899 start = has_receiver ? 1 : 0;
1900 if (profile_arguments()) {
1901 ciProfileData* data = method()->method_data()->bci_to_data(bci());
1902 if (data != NULL && (data->is_CallTypeData() || data->is_VirtualCallTypeData())) {
1903 n = data->is_CallTypeData() ? data->as_CallTypeData()->number_of_arguments() : data->as_VirtualCallTypeData()->number_of_arguments();
1904 }
1905 }
1906 // If we are inlining then we need to collect arguments to profile parameters for the target
1907 if (profile_parameters() && target != NULL) {
|