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


< prev index next >