src/share/vm/opto/library_call.cpp

Print this page




 208   Node* round_double_node(Node* n);
 209   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 210   bool inline_math_native(vmIntrinsics::ID id);
 211   bool inline_trig(vmIntrinsics::ID id);
 212   bool inline_math(vmIntrinsics::ID id);
 213   template <typename OverflowOp>
 214   bool inline_math_overflow(Node* arg1, Node* arg2);
 215   void inline_math_mathExact(Node* math, Node* test);
 216   bool inline_math_addExactI(bool is_increment);
 217   bool inline_math_addExactL(bool is_increment);
 218   bool inline_math_multiplyExactI();
 219   bool inline_math_multiplyExactL();
 220   bool inline_math_negateExactI();
 221   bool inline_math_negateExactL();
 222   bool inline_math_subtractExactI(bool is_decrement);
 223   bool inline_math_subtractExactL(bool is_decrement);
 224   bool inline_exp();
 225   bool inline_pow();
 226   Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 227   bool inline_min_max(vmIntrinsics::ID id);

 228   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 229   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 230   int classify_unsafe_addr(Node* &base, Node* &offset);
 231   Node* make_unsafe_address(Node* base, Node* offset);
 232   // Helper for inline_unsafe_access.
 233   // Generates the guards that check whether the result of
 234   // Unsafe.getObject should be recorded in an SATB log buffer.
 235   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 236   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 237   static bool klass_needs_init_guard(Node* kls);
 238   bool inline_unsafe_allocate();
 239   bool inline_unsafe_copyMemory();
 240   bool inline_native_currentThread();
 241 #ifdef TRACE_HAVE_INTRINSICS
 242   bool inline_native_classID();
 243   bool inline_native_threadID();
 244 #endif
 245   bool inline_native_time_funcs(address method, const char* funcName);
 246   bool inline_native_isInterrupted();
 247   bool inline_native_Class_query(vmIntrinsics::ID id);


 720 
 721   switch (intrinsic_id()) {
 722   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 723   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 724   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 725 
 726   case vmIntrinsics::_dsin:
 727   case vmIntrinsics::_dcos:
 728   case vmIntrinsics::_dtan:
 729   case vmIntrinsics::_dabs:
 730   case vmIntrinsics::_datan2:
 731   case vmIntrinsics::_dsqrt:
 732   case vmIntrinsics::_dexp:
 733   case vmIntrinsics::_dlog:
 734   case vmIntrinsics::_dlog10:
 735   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 736 
 737   case vmIntrinsics::_min:
 738   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 739 







 740   case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
 741   case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
 742   case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
 743   case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
 744   case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
 745   case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);
 746   case vmIntrinsics::_multiplyExactI:           return inline_math_multiplyExactI();
 747   case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
 748   case vmIntrinsics::_negateExactI:             return inline_math_negateExactI();
 749   case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
 750   case vmIntrinsics::_subtractExactI:           return inline_math_subtractExactI(false /* subtract */);
 751   case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL(false /* subtract */);
 752 
 753   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 754 
 755   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 756   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 757   case vmIntrinsics::_equals:                   return inline_string_equals();
 758 
 759   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);


2000 #undef FN_PTR
2001 
2002    // These intrinsics are not yet correctly implemented
2003   case vmIntrinsics::_datan2:
2004     return false;
2005 
2006   default:
2007     fatal_unexpected_iid(id);
2008     return false;
2009   }
2010 }
2011 
2012 static bool is_simple_name(Node* n) {
2013   return (n->req() == 1         // constant
2014           || (n->is_Type() && n->as_Type()->type()->singleton())
2015           || n->is_Proj()       // parameter or return value
2016           || n->is_Phi()        // local of some sort
2017           );
2018 }
2019 















2020 //----------------------------inline_min_max-----------------------------------
2021 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
2022   set_result(generate_min_max(id, argument(0), argument(1)));
2023   return true;
2024 }
2025 
2026 void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) {
2027   Node* bol = _gvn.transform( new BoolNode(test, BoolTest::overflow) );
2028   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
2029   Node* fast_path = _gvn.transform( new IfFalseNode(check));
2030   Node* slow_path = _gvn.transform( new IfTrueNode(check) );
2031 
2032   {
2033     PreserveJVMState pjvms(this);
2034     PreserveReexecuteState preexecs(this);
2035     jvms()->set_should_reexecute(true);
2036 
2037     set_control(slow_path);
2038     set_i_o(i_o());
2039 




 208   Node* round_double_node(Node* n);
 209   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 210   bool inline_math_native(vmIntrinsics::ID id);
 211   bool inline_trig(vmIntrinsics::ID id);
 212   bool inline_math(vmIntrinsics::ID id);
 213   template <typename OverflowOp>
 214   bool inline_math_overflow(Node* arg1, Node* arg2);
 215   void inline_math_mathExact(Node* math, Node* test);
 216   bool inline_math_addExactI(bool is_increment);
 217   bool inline_math_addExactL(bool is_increment);
 218   bool inline_math_multiplyExactI();
 219   bool inline_math_multiplyExactL();
 220   bool inline_math_negateExactI();
 221   bool inline_math_negateExactL();
 222   bool inline_math_subtractExactI(bool is_decrement);
 223   bool inline_math_subtractExactL(bool is_decrement);
 224   bool inline_exp();
 225   bool inline_pow();
 226   Node* finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 227   bool inline_min_max(vmIntrinsics::ID id);
 228   bool inline_notify(vmIntrinsics::ID id);
 229   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 230   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 231   int classify_unsafe_addr(Node* &base, Node* &offset);
 232   Node* make_unsafe_address(Node* base, Node* offset);
 233   // Helper for inline_unsafe_access.
 234   // Generates the guards that check whether the result of
 235   // Unsafe.getObject should be recorded in an SATB log buffer.
 236   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 237   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 238   static bool klass_needs_init_guard(Node* kls);
 239   bool inline_unsafe_allocate();
 240   bool inline_unsafe_copyMemory();
 241   bool inline_native_currentThread();
 242 #ifdef TRACE_HAVE_INTRINSICS
 243   bool inline_native_classID();
 244   bool inline_native_threadID();
 245 #endif
 246   bool inline_native_time_funcs(address method, const char* funcName);
 247   bool inline_native_isInterrupted();
 248   bool inline_native_Class_query(vmIntrinsics::ID id);


 721 
 722   switch (intrinsic_id()) {
 723   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 724   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 725   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 726 
 727   case vmIntrinsics::_dsin:
 728   case vmIntrinsics::_dcos:
 729   case vmIntrinsics::_dtan:
 730   case vmIntrinsics::_dabs:
 731   case vmIntrinsics::_datan2:
 732   case vmIntrinsics::_dsqrt:
 733   case vmIntrinsics::_dexp:
 734   case vmIntrinsics::_dlog:
 735   case vmIntrinsics::_dlog10:
 736   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 737 
 738   case vmIntrinsics::_min:
 739   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 740 
 741   case vmIntrinsics::_notify:
 742   case vmIntrinsics::_notifyAll:
 743     if (InlineNotify) {
 744       return inline_notify(intrinsic_id());
 745     }
 746     return false;
 747 
 748   case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
 749   case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
 750   case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
 751   case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
 752   case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
 753   case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);
 754   case vmIntrinsics::_multiplyExactI:           return inline_math_multiplyExactI();
 755   case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
 756   case vmIntrinsics::_negateExactI:             return inline_math_negateExactI();
 757   case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
 758   case vmIntrinsics::_subtractExactI:           return inline_math_subtractExactI(false /* subtract */);
 759   case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL(false /* subtract */);
 760 
 761   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 762 
 763   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 764   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 765   case vmIntrinsics::_equals:                   return inline_string_equals();
 766 
 767   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);


2008 #undef FN_PTR
2009 
2010    // These intrinsics are not yet correctly implemented
2011   case vmIntrinsics::_datan2:
2012     return false;
2013 
2014   default:
2015     fatal_unexpected_iid(id);
2016     return false;
2017   }
2018 }
2019 
2020 static bool is_simple_name(Node* n) {
2021   return (n->req() == 1         // constant
2022           || (n->is_Type() && n->as_Type()->type()->singleton())
2023           || n->is_Proj()       // parameter or return value
2024           || n->is_Phi()        // local of some sort
2025           );
2026 }
2027 
2028 //----------------------------inline_notify-----------------------------------*
2029 bool LibraryCallKit::inline_notify(vmIntrinsics::ID id) {
2030   const TypeFunc* ftype = OptoRuntime::monitor_notify_Type();
2031   address func;
2032   if (id == vmIntrinsics::_notify) {
2033     func = OptoRuntime::monitor_notify_Java();
2034   } else {
2035     func = OptoRuntime::monitor_notifyAll_Java();
2036   }
2037   Node* call = make_runtime_call(RC_NO_LEAF, ftype, func, NULL, TypeRawPtr::BOTTOM, argument(0));
2038   make_slow_call_ex(call, env()->Throwable_klass(), false);
2039   return true;
2040 }
2041 
2042 
2043 //----------------------------inline_min_max-----------------------------------
2044 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
2045   set_result(generate_min_max(id, argument(0), argument(1)));
2046   return true;
2047 }
2048 
2049 void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) {
2050   Node* bol = _gvn.transform( new BoolNode(test, BoolTest::overflow) );
2051   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
2052   Node* fast_path = _gvn.transform( new IfFalseNode(check));
2053   Node* slow_path = _gvn.transform( new IfTrueNode(check) );
2054 
2055   {
2056     PreserveJVMState pjvms(this);
2057     PreserveReexecuteState preexecs(this);
2058     jvms()->set_should_reexecute(true);
2059 
2060     set_control(slow_path);
2061     set_i_o(i_o());
2062