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
|