< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page




 210   }
 211   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls);
 212   Node * field_address_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls);
 213 
 214   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae);
 215   bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae);
 216   bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae);
 217   bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae);
 218   Node* make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
 219                           RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae);
 220   bool inline_string_indexOfChar();
 221   bool inline_string_equals(StrIntrinsicNode::ArgEnc ae);
 222   bool inline_string_toBytesU();
 223   bool inline_string_getCharsU();
 224   bool inline_string_copy(bool compress);
 225   bool inline_string_char_access(bool is_store);
 226   Node* round_double_node(Node* n);
 227   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 228   bool inline_math_native(vmIntrinsics::ID id);
 229   bool inline_math(vmIntrinsics::ID id);

 230   template <typename OverflowOp>
 231   bool inline_math_overflow(Node* arg1, Node* arg2);
 232   void inline_math_mathExact(Node* math, Node* test);
 233   bool inline_math_addExactI(bool is_increment);
 234   bool inline_math_addExactL(bool is_increment);
 235   bool inline_math_multiplyExactI();
 236   bool inline_math_multiplyExactL();
 237   bool inline_math_multiplyHigh();
 238   bool inline_math_negateExactI();
 239   bool inline_math_negateExactL();
 240   bool inline_math_subtractExactI(bool is_decrement);
 241   bool inline_math_subtractExactL(bool is_decrement);
 242   bool inline_min_max(vmIntrinsics::ID id);
 243   bool inline_notify(vmIntrinsics::ID id);
 244   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 245   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 246   int classify_unsafe_addr(Node* &base, Node* &offset, BasicType type);
 247   Node* make_unsafe_address(Node*& base, Node* offset, DecoratorSet decorators, BasicType type = T_ILLEGAL, bool can_cast = false);
 248 
 249   typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind;


 516   const bool is_volatile    = true;
 517 
 518   if (!jvms()->has_method()) {
 519     // Root JVMState has a null method.
 520     assert(map()->memory()->Opcode() == Op_Parm, "");
 521     // Insert the memory aliasing node
 522     set_all_memory(reset_memory());
 523   }
 524   assert(merged_memory(), "");
 525 
 526 
 527   switch (intrinsic_id()) {
 528   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 529   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 530   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 531 
 532   case vmIntrinsics::_dsin:
 533   case vmIntrinsics::_dcos:
 534   case vmIntrinsics::_dtan:
 535   case vmIntrinsics::_dabs:



 536   case vmIntrinsics::_datan2:
 537   case vmIntrinsics::_dsqrt:
 538   case vmIntrinsics::_dexp:
 539   case vmIntrinsics::_dlog:
 540   case vmIntrinsics::_dlog10:
 541   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 542 
 543   case vmIntrinsics::_min:
 544   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 545 
 546   case vmIntrinsics::_notify:
 547   case vmIntrinsics::_notifyAll:
 548     return inline_notify(intrinsic_id());
 549 
 550   case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
 551   case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
 552   case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
 553   case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
 554   case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
 555   case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);


1776   } else {
1777     ch = access_load_at(value, adr, TypeAryPtr::BYTES, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED | C2_CONTROL_DEPENDENT_LOAD);
1778     set_result(ch);
1779   }
1780   return true;
1781 }
1782 
1783 //--------------------------round_double_node--------------------------------
1784 // Round a double node if necessary.
1785 Node* LibraryCallKit::round_double_node(Node* n) {
1786   if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1787     n = _gvn.transform(new RoundDoubleNode(0, n));
1788   return n;
1789 }
1790 
1791 //------------------------------inline_math-----------------------------------
1792 // public static double Math.abs(double)
1793 // public static double Math.sqrt(double)
1794 // public static double Math.log(double)
1795 // public static double Math.log10(double)
1796 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1797   Node* arg = round_double_node(argument(0));
1798   Node* n = NULL;
1799   switch (id) {
1800   case vmIntrinsics::_dabs:   n = new AbsDNode(                arg);  break;
1801   case vmIntrinsics::_dsqrt:  n = new SqrtDNode(C, control(),  arg);  break;
1802   default:  fatal_unexpected_iid(id);  break;
1803   }
1804   set_result(_gvn.transform(n));
1805   return true;
1806 }
1807 

















1808 //------------------------------runtime_math-----------------------------
1809 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
1810   assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
1811          "must be (DD)D or (D)D type");
1812 
1813   // Inputs
1814   Node* a = round_double_node(argument(0));
1815   Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? round_double_node(argument(2)) : NULL;
1816 
1817   const TypePtr* no_memory_effects = NULL;
1818   Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
1819                                  no_memory_effects,
1820                                  a, top(), b, b ? top() : NULL);
1821   Node* value = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
1822 #ifdef ASSERT
1823   Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
1824   assert(value_top == top(), "second value must be top");
1825 #endif
1826 
1827   set_result(value);


1838       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dsin(), "dsin") :
1839       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin),   "SIN");
1840   case vmIntrinsics::_dcos:
1841     return StubRoutines::dcos() != NULL ?
1842       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dcos(), "dcos") :
1843       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos),   "COS");
1844   case vmIntrinsics::_dtan:
1845     return StubRoutines::dtan() != NULL ?
1846       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtan(), "dtan") :
1847       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
1848   case vmIntrinsics::_dlog:
1849     return StubRoutines::dlog() != NULL ?
1850       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog(), "dlog") :
1851       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog),   "LOG");
1852   case vmIntrinsics::_dlog10:
1853     return StubRoutines::dlog10() != NULL ?
1854       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog10(), "dlog10") :
1855       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1856 
1857     // These intrinsics are supported on all hardware
1858   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
1859   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_math(id) : false;



1860 
1861   case vmIntrinsics::_dexp:
1862     return StubRoutines::dexp() != NULL ?
1863       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
1864       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
1865   case vmIntrinsics::_dpow: {
1866     Node* exp = round_double_node(argument(2));
1867     const TypeD* d = _gvn.type(exp)->isa_double_constant();
1868     if (d != NULL && d->getd() == 2.0) {
1869       // Special case: pow(x, 2.0) => x * x
1870       Node* base = round_double_node(argument(0));
1871       set_result(_gvn.transform(new MulDNode(base, base)));
1872       return true;
1873     }
1874     return StubRoutines::dpow() != NULL ?
1875       runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(),  "dpow") :
1876       runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
1877   }
1878 #undef FN_PTR
1879 




 210   }
 211   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls);
 212   Node * field_address_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls);
 213 
 214   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae);
 215   bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae);
 216   bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae);
 217   bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae);
 218   Node* make_indexOf_node(Node* src_start, Node* src_count, Node* tgt_start, Node* tgt_count,
 219                           RegionNode* region, Node* phi, StrIntrinsicNode::ArgEnc ae);
 220   bool inline_string_indexOfChar();
 221   bool inline_string_equals(StrIntrinsicNode::ArgEnc ae);
 222   bool inline_string_toBytesU();
 223   bool inline_string_getCharsU();
 224   bool inline_string_copy(bool compress);
 225   bool inline_string_char_access(bool is_store);
 226   Node* round_double_node(Node* n);
 227   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 228   bool inline_math_native(vmIntrinsics::ID id);
 229   bool inline_math(vmIntrinsics::ID id);
 230   bool inline_double_math(vmIntrinsics::ID id);
 231   template <typename OverflowOp>
 232   bool inline_math_overflow(Node* arg1, Node* arg2);
 233   void inline_math_mathExact(Node* math, Node* test);
 234   bool inline_math_addExactI(bool is_increment);
 235   bool inline_math_addExactL(bool is_increment);
 236   bool inline_math_multiplyExactI();
 237   bool inline_math_multiplyExactL();
 238   bool inline_math_multiplyHigh();
 239   bool inline_math_negateExactI();
 240   bool inline_math_negateExactL();
 241   bool inline_math_subtractExactI(bool is_decrement);
 242   bool inline_math_subtractExactL(bool is_decrement);
 243   bool inline_min_max(vmIntrinsics::ID id);
 244   bool inline_notify(vmIntrinsics::ID id);
 245   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 246   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 247   int classify_unsafe_addr(Node* &base, Node* &offset, BasicType type);
 248   Node* make_unsafe_address(Node*& base, Node* offset, DecoratorSet decorators, BasicType type = T_ILLEGAL, bool can_cast = false);
 249 
 250   typedef enum { Relaxed, Opaque, Volatile, Acquire, Release } AccessKind;


 517   const bool is_volatile    = true;
 518 
 519   if (!jvms()->has_method()) {
 520     // Root JVMState has a null method.
 521     assert(map()->memory()->Opcode() == Op_Parm, "");
 522     // Insert the memory aliasing node
 523     set_all_memory(reset_memory());
 524   }
 525   assert(merged_memory(), "");
 526 
 527 
 528   switch (intrinsic_id()) {
 529   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 530   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 531   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 532 
 533   case vmIntrinsics::_dsin:
 534   case vmIntrinsics::_dcos:
 535   case vmIntrinsics::_dtan:
 536   case vmIntrinsics::_dabs:
 537   case vmIntrinsics::_fabs:
 538   case vmIntrinsics::_iabs:
 539   case vmIntrinsics::_labs:
 540   case vmIntrinsics::_datan2:
 541   case vmIntrinsics::_dsqrt:
 542   case vmIntrinsics::_dexp:
 543   case vmIntrinsics::_dlog:
 544   case vmIntrinsics::_dlog10:
 545   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 546 
 547   case vmIntrinsics::_min:
 548   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 549 
 550   case vmIntrinsics::_notify:
 551   case vmIntrinsics::_notifyAll:
 552     return inline_notify(intrinsic_id());
 553 
 554   case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
 555   case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
 556   case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
 557   case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
 558   case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
 559   case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);


1780   } else {
1781     ch = access_load_at(value, adr, TypeAryPtr::BYTES, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED | C2_CONTROL_DEPENDENT_LOAD);
1782     set_result(ch);
1783   }
1784   return true;
1785 }
1786 
1787 //--------------------------round_double_node--------------------------------
1788 // Round a double node if necessary.
1789 Node* LibraryCallKit::round_double_node(Node* n) {
1790   if (Matcher::strict_fp_requires_explicit_rounding && UseSSE <= 1)
1791     n = _gvn.transform(new RoundDoubleNode(0, n));
1792   return n;
1793 }
1794 
1795 //------------------------------inline_math-----------------------------------
1796 // public static double Math.abs(double)
1797 // public static double Math.sqrt(double)
1798 // public static double Math.log(double)
1799 // public static double Math.log10(double)
1800 bool LibraryCallKit::inline_double_math(vmIntrinsics::ID id) {
1801   Node* arg = round_double_node(argument(0));
1802   Node* n = NULL;
1803   switch (id) {
1804   case vmIntrinsics::_dabs:   n = new AbsDNode(                arg);  break;
1805   case vmIntrinsics::_dsqrt:  n = new SqrtDNode(C, control(),  arg);  break;
1806   default:  fatal_unexpected_iid(id);  break;
1807   }
1808   set_result(_gvn.transform(n));
1809   return true;
1810 }
1811 
1812 //------------------------------inline_math-----------------------------------
1813 // public static float Math.abs(float)
1814 // public static int Math.abs(int)
1815 // public static long Math.abs(long)
1816 bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
1817   Node* arg = argument(0);
1818   Node* n = NULL;
1819   switch (id) {
1820   case vmIntrinsics::_fabs:   n = new AbsFNode(                arg);  break;
1821   case vmIntrinsics::_iabs:   n = new AbsINode(                arg);  break;
1822   case vmIntrinsics::_labs:   n = new AbsLNode(                arg);  break;
1823   default:  fatal_unexpected_iid(id);  break;
1824   }
1825   set_result(_gvn.transform(n));
1826   return true;
1827 }
1828 
1829 //------------------------------runtime_math-----------------------------
1830 bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
1831   assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
1832          "must be (DD)D or (D)D type");
1833 
1834   // Inputs
1835   Node* a = round_double_node(argument(0));
1836   Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? round_double_node(argument(2)) : NULL;
1837 
1838   const TypePtr* no_memory_effects = NULL;
1839   Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
1840                                  no_memory_effects,
1841                                  a, top(), b, b ? top() : NULL);
1842   Node* value = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
1843 #ifdef ASSERT
1844   Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
1845   assert(value_top == top(), "second value must be top");
1846 #endif
1847 
1848   set_result(value);


1859       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dsin(), "dsin") :
1860       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dsin),   "SIN");
1861   case vmIntrinsics::_dcos:
1862     return StubRoutines::dcos() != NULL ?
1863       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dcos(), "dcos") :
1864       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dcos),   "COS");
1865   case vmIntrinsics::_dtan:
1866     return StubRoutines::dtan() != NULL ?
1867       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dtan(), "dtan") :
1868       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dtan), "TAN");
1869   case vmIntrinsics::_dlog:
1870     return StubRoutines::dlog() != NULL ?
1871       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog(), "dlog") :
1872       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog),   "LOG");
1873   case vmIntrinsics::_dlog10:
1874     return StubRoutines::dlog10() != NULL ?
1875       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dlog10(), "dlog10") :
1876       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
1877 
1878     // These intrinsics are supported on all hardware
1879   case vmIntrinsics::_dsqrt:  return Matcher::match_rule_supported(Op_SqrtD) ? inline_double_math(id) : false;
1880   case vmIntrinsics::_dabs:   return Matcher::has_match_rule(Op_AbsD)   ? inline_double_math(id) : false;
1881   case vmIntrinsics::_fabs:   return Matcher::match_rule_supported(Op_AbsF)   ? inline_math(id) : false;
1882   case vmIntrinsics::_iabs:   return Matcher::match_rule_supported(Op_AbsI)   ? inline_math(id) : false;
1883   case vmIntrinsics::_labs:   return Matcher::match_rule_supported(Op_AbsL)   ? inline_math(id) : false;
1884 
1885   case vmIntrinsics::_dexp:
1886     return StubRoutines::dexp() != NULL ?
1887       runtime_math(OptoRuntime::Math_D_D_Type(), StubRoutines::dexp(),  "dexp") :
1888       runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dexp),  "EXP");
1889   case vmIntrinsics::_dpow: {
1890     Node* exp = round_double_node(argument(2));
1891     const TypeD* d = _gvn.type(exp)->isa_double_constant();
1892     if (d != NULL && d->getd() == 2.0) {
1893       // Special case: pow(x, 2.0) => x * x
1894       Node* base = round_double_node(argument(0));
1895       set_result(_gvn.transform(new MulDNode(base, base)));
1896       return true;
1897     }
1898     return StubRoutines::dpow() != NULL ?
1899       runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(),  "dpow") :
1900       runtime_math(OptoRuntime::Math_DD_D_Type(), FN_PTR(SharedRuntime::dpow),  "POW");
1901   }
1902 #undef FN_PTR
1903 


< prev index next >