< prev index next >

src/hotspot/share/c1/c1_GraphBuilder.cpp

Print this page




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) {


< prev index next >