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