src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page
rev 5514 : 8026844: Various Math functions needs intrinsification
Reviewed-by: duke
rev 5515 : [mq]: fixes


 187   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 188     return generate_method_call(method_id, false, true);
 189   }
 190   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 191     return generate_method_call(method_id, true, false);
 192   }
 193   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
 194 
 195   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
 196   Node* make_string_method_node(int opcode, Node* str1, Node* str2);
 197   bool inline_string_compareTo();
 198   bool inline_string_indexOf();
 199   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 200   bool inline_string_equals();
 201   Node* round_double_node(Node* n);
 202   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 203   bool inline_math_native(vmIntrinsics::ID id);
 204   bool inline_trig(vmIntrinsics::ID id);
 205   bool inline_math(vmIntrinsics::ID id);
 206   void inline_math_mathExact(Node* math);
 207   bool inline_math_addExact();
 208   bool inline_math_addExactL();
 209   bool inline_math_decrementExact();
 210   bool inline_math_decrementExactL();
 211   bool inline_math_incrementExact();
 212   bool inline_math_incrementExactL();
 213   bool inline_math_multiplyExact();
 214   bool inline_math_multiplyExactL();
 215   bool inline_math_negateExact();
 216   bool inline_math_negateExactL();
 217   bool inline_math_subtractExact();
 218   bool inline_math_subtractExactL();
 219   bool inline_exp();
 220   bool inline_pow();
 221   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 222   bool inline_min_max(vmIntrinsics::ID id);
 223   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 224   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 225   int classify_unsafe_addr(Node* &base, Node* &offset);
 226   Node* make_unsafe_address(Node* base, Node* offset);
 227   // Helper for inline_unsafe_access.
 228   // Generates the guards that check whether the result of
 229   // Unsafe.getObject should be recorded in an SATB log buffer.
 230   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 231   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 232   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
 233   static bool klass_needs_init_guard(Node* kls);
 234   bool inline_unsafe_allocate();
 235   bool inline_unsafe_copyMemory();
 236   bool inline_native_currentThread();
 237 #ifdef TRACE_HAVE_INTRINSICS
 238   bool inline_native_classID();


 501 #endif
 502 
 503   case vmIntrinsics::_aescrypt_encryptBlock:
 504   case vmIntrinsics::_aescrypt_decryptBlock:
 505     if (!UseAESIntrinsics) return NULL;
 506     break;
 507 
 508   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 509   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 510     if (!UseAESIntrinsics) return NULL;
 511     // these two require the predicated logic
 512     is_predicted = true;
 513     break;
 514 
 515   case vmIntrinsics::_updateCRC32:
 516   case vmIntrinsics::_updateBytesCRC32:
 517   case vmIntrinsics::_updateByteBufferCRC32:
 518     if (!UseCRC32Intrinsics) return NULL;
 519     break;
 520 
 521   case vmIntrinsics::_incrementExact:
 522   case vmIntrinsics::_addExact:
 523     if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
 524     break;
 525   case vmIntrinsics::_incrementExactL:
 526   case vmIntrinsics::_addExactL:
 527     if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
 528     break;
 529   case vmIntrinsics::_decrementExact:
 530   case vmIntrinsics::_subtractExact:
 531     if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
 532     break;
 533   case vmIntrinsics::_decrementExactL:
 534   case vmIntrinsics::_subtractExactL:
 535     if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
 536     break;
 537   case vmIntrinsics::_negateExact:
 538     if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
 539     break;
 540   case vmIntrinsics::_negateExactL:
 541     if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
 542     break;
 543   case vmIntrinsics::_multiplyExact:
 544     if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
 545     break;
 546   case vmIntrinsics::_multiplyExactL:
 547     if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
 548     break;
 549 
 550  default:
 551     assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
 552     assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
 553     break;
 554   }
 555 
 556   // -XX:-InlineClassNatives disables natives from the Class class.
 557   // The flag applies to all reflective calls, notably Array.newArray
 558   // (visible to Java programmers as Array.newInstance).
 559   if (m->holder()->name() == ciSymbol::java_lang_Class() ||
 560       m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
 561     if (!InlineClassNatives)  return NULL;
 562   }
 563 


 700 
 701   switch (intrinsic_id()) {
 702   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 703   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 704   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 705 
 706   case vmIntrinsics::_dsin:
 707   case vmIntrinsics::_dcos:
 708   case vmIntrinsics::_dtan:
 709   case vmIntrinsics::_dabs:
 710   case vmIntrinsics::_datan2:
 711   case vmIntrinsics::_dsqrt:
 712   case vmIntrinsics::_dexp:
 713   case vmIntrinsics::_dlog:
 714   case vmIntrinsics::_dlog10:
 715   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 716 
 717   case vmIntrinsics::_min:
 718   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 719 
 720   case vmIntrinsics::_addExact:                 return inline_math_addExact();
 721   case vmIntrinsics::_addExactL:                return inline_math_addExactL();
 722   case vmIntrinsics::_decrementExact:           return inline_math_decrementExact();
 723   case vmIntrinsics::_decrementExactL:          return inline_math_decrementExactL();
 724   case vmIntrinsics::_incrementExact:           return inline_math_incrementExact();
 725   case vmIntrinsics::_incrementExactL:          return inline_math_incrementExactL();
 726   case vmIntrinsics::_multiplyExact:            return inline_math_multiplyExact();
 727   case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
 728   case vmIntrinsics::_negateExact:              return inline_math_negateExact();
 729   case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
 730   case vmIntrinsics::_subtractExact:            return inline_math_subtractExact();
 731   case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL();
 732 
 733   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 734 
 735   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 736   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 737   case vmIntrinsics::_equals:                   return inline_string_equals();
 738 
 739   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);
 740   case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
 741   case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,    !is_volatile);
 742   case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,   !is_volatile);
 743   case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,    !is_volatile);
 744   case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,     !is_volatile);
 745   case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,    !is_volatile);
 746   case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,   !is_volatile);
 747   case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,  !is_volatile);
 748 
 749   case vmIntrinsics::_putObject:                return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,  !is_volatile);
 750   case vmIntrinsics::_putBoolean:               return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN, !is_volatile);
 751   case vmIntrinsics::_putByte:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,    !is_volatile);


1959   }
1960 }
1961 
1962 static bool is_simple_name(Node* n) {
1963   return (n->req() == 1         // constant
1964           || (n->is_Type() && n->as_Type()->type()->singleton())
1965           || n->is_Proj()       // parameter or return value
1966           || n->is_Phi()        // local of some sort
1967           );
1968 }
1969 
1970 //----------------------------inline_min_max-----------------------------------
1971 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1972   set_result(generate_min_max(id, argument(0), argument(1)));
1973   return true;
1974 }
1975 
1976 void LibraryCallKit::inline_math_mathExact(Node* math) {
1977   // If we didn't get the expected opcode it means we have optimized
1978   // the node to something else and don't need the exception edge.
1979   if (MathExactNode::is_MathExactOpcode(math->Opcode()) == false) {
1980     set_result(math);
1981     return;
1982   }
1983 
1984   Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
1985   Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1986 
1987   Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
1988   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1989   Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1990   Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1991 
1992   {
1993     PreserveJVMState pjvms(this);
1994     PreserveReexecuteState preexecs(this);
1995     jvms()->set_should_reexecute(true);
1996 
1997     set_control(slow_path);
1998     set_i_o(i_o());
1999 
2000     uncommon_trap(Deoptimization::Reason_intrinsic,
2001                   Deoptimization::Action_none);
2002   }
2003 
2004   set_control(fast_path);
2005   set_result(result);
2006 }
2007 
2008 bool LibraryCallKit::inline_math_addExact() {
2009   Node* arg1 = argument(0);
2010   Node* arg2 = argument(1);






2011 
2012   Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
2013   inline_math_mathExact(add);
2014   return true;
2015 }
2016 
2017 bool LibraryCallKit::inline_math_addExactL() {
2018   Node* arg1 = argument(0); // type long
2019   // argument(1) == TOP
2020   Node* arg2 = argument(2); // type long
2021   // argument(4) == TOP






2022 
2023   Node* add = _gvn.transform( new(C) AddExactLNode(NULL, arg1, arg2) );
2024   inline_math_mathExact(add);
2025   return true;
2026 }
2027 
2028 bool LibraryCallKit::inline_math_subtractExactL() {
2029   Node* arg1 = argument(0); // type long
2030   // argument(1) == TOP
2031   Node* arg2 = argument(2); // type long
2032   // argument(4) == TOP




2033 
2034   Node* sub = _gvn.transform( new(C) SubExactLNode(NULL, arg1, arg2) );
2035   inline_math_mathExact(sub);
2036   return true;
2037 }
2038 
2039 bool LibraryCallKit::inline_math_subtractExact() {
2040   Node* arg1 = argument(0);
2041   Node* arg2 = argument(1);

2042 
2043   Node* sub = _gvn.transform( new(C) SubExactINode(NULL, arg1, arg2) );







2044   inline_math_mathExact(sub);
2045   return true;
2046 }
2047 
2048 bool LibraryCallKit::inline_math_negateExact() {
2049   Node* arg1 = argument(0);
2050 
2051   Node* neg = _gvn.transform( new(C) NegExactINode(NULL, arg1));
2052   inline_math_mathExact(neg);
2053   return true;
2054 }
2055 
2056 bool LibraryCallKit::inline_math_negateExactL() {
2057   Node* arg1 = argument(0);
2058   // argument(1) == TOP
2059 
2060   Node* neg = _gvn.transform( new(C) NegExactLNode(NULL, arg1));
2061   inline_math_mathExact(neg);
2062   return true;
2063 }
2064 
2065 bool LibraryCallKit::inline_math_multiplyExact() {
2066   Node* arg1 = argument(0);
2067   Node* arg2 = argument(1);
2068 
2069   Node* mul = _gvn.transform( new(C) MulExactINode(NULL, arg1, arg2) );
2070   inline_math_mathExact(mul);
2071   return true;
2072 }
2073 
2074 bool LibraryCallKit::inline_math_multiplyExactL() {
2075   Node* arg1 = argument(0);
2076   // argument(1) == TOP
2077   Node* arg2 = argument(2);
2078   // argument(3) == TOP
2079 
2080   Node* mul = _gvn.transform( new(C) MulExactLNode(NULL, arg1, arg2) );
2081   inline_math_mathExact(mul);
2082   return true;
2083 }
2084 
2085 bool LibraryCallKit::inline_math_incrementExact() {
2086   Node* arg1 = argument(0);
2087   Node* arg2 = intcon(1);
2088 
2089   Node* inc = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2));
2090   inline_math_mathExact(inc);
2091   return true;
2092 }
2093 
2094 bool LibraryCallKit::inline_math_incrementExactL() {
2095   Node* arg1 = argument(0);
2096   // argument(1) == TOP
2097   Node* arg2 = longcon(1);
2098 
2099   Node* inc = _gvn.transform( new(C) AddExactLNode(NULL, arg1, arg2));
2100   inline_math_mathExact(inc);
2101   return true;
2102 }
2103 
2104 bool LibraryCallKit::inline_math_decrementExact() {
2105   Node* arg1 = argument(0);
2106   Node* arg2 = intcon(1);
2107 
2108   Node* dec = _gvn.transform( new(C) SubExactINode(NULL, arg1, arg2));
2109   inline_math_mathExact(dec);
2110   return true;
2111 }
2112 
2113 bool LibraryCallKit::inline_math_decrementExactL() {
2114   Node* arg1 = argument(0);
2115   // argument(1) == TOP
2116   Node* arg2 = longcon(1);
2117 
2118   Node* dec = _gvn.transform( new(C) SubExactLNode(NULL, arg1, arg2));
2119   inline_math_mathExact(dec);
2120   return true;
2121 }
2122 
2123 Node*
2124 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2125   // These are the candidate return value:
2126   Node* xvalue = x0;
2127   Node* yvalue = y0;
2128 
2129   if (xvalue == yvalue) {
2130     return xvalue;
2131   }
2132 
2133   bool want_max = (id == vmIntrinsics::_max);
2134 
2135   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
2136   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
2137   if (txvalue == NULL || tyvalue == NULL)  return top();
2138   // This is not really necessary, but it is consistent with a
2139   // hypothetical MaxINode::Value method:




 187   CallJavaNode* generate_method_call_static(vmIntrinsics::ID method_id) {
 188     return generate_method_call(method_id, false, true);
 189   }
 190   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
 191     return generate_method_call(method_id, true, false);
 192   }
 193   Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
 194 
 195   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
 196   Node* make_string_method_node(int opcode, Node* str1, Node* str2);
 197   bool inline_string_compareTo();
 198   bool inline_string_indexOf();
 199   Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
 200   bool inline_string_equals();
 201   Node* round_double_node(Node* n);
 202   bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
 203   bool inline_math_native(vmIntrinsics::ID id);
 204   bool inline_trig(vmIntrinsics::ID id);
 205   bool inline_math(vmIntrinsics::ID id);
 206   void inline_math_mathExact(Node* math);
 207   bool inline_math_addExactI(bool is_increment);
 208   bool inline_math_addExactL(bool is_increment);
 209   bool inline_math_multiplyExactI();




 210   bool inline_math_multiplyExactL();
 211   bool inline_math_negateExactI();
 212   bool inline_math_negateExactL();
 213   bool inline_math_subtractExactI(bool is_decrement);
 214   bool inline_math_subtractExactL(bool is_decrement);
 215   bool inline_exp();
 216   bool inline_pow();
 217   void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
 218   bool inline_min_max(vmIntrinsics::ID id);
 219   Node* generate_min_max(vmIntrinsics::ID id, Node* x, Node* y);
 220   // This returns Type::AnyPtr, RawPtr, or OopPtr.
 221   int classify_unsafe_addr(Node* &base, Node* &offset);
 222   Node* make_unsafe_address(Node* base, Node* offset);
 223   // Helper for inline_unsafe_access.
 224   // Generates the guards that check whether the result of
 225   // Unsafe.getObject should be recorded in an SATB log buffer.
 226   void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar);
 227   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
 228   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
 229   static bool klass_needs_init_guard(Node* kls);
 230   bool inline_unsafe_allocate();
 231   bool inline_unsafe_copyMemory();
 232   bool inline_native_currentThread();
 233 #ifdef TRACE_HAVE_INTRINSICS
 234   bool inline_native_classID();


 497 #endif
 498 
 499   case vmIntrinsics::_aescrypt_encryptBlock:
 500   case vmIntrinsics::_aescrypt_decryptBlock:
 501     if (!UseAESIntrinsics) return NULL;
 502     break;
 503 
 504   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
 505   case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
 506     if (!UseAESIntrinsics) return NULL;
 507     // these two require the predicated logic
 508     is_predicted = true;
 509     break;
 510 
 511   case vmIntrinsics::_updateCRC32:
 512   case vmIntrinsics::_updateBytesCRC32:
 513   case vmIntrinsics::_updateByteBufferCRC32:
 514     if (!UseCRC32Intrinsics) return NULL;
 515     break;
 516 
 517   case vmIntrinsics::_incrementExactI:
 518   case vmIntrinsics::_addExactI:
 519     if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL;
 520     break;
 521   case vmIntrinsics::_incrementExactL:
 522   case vmIntrinsics::_addExactL:
 523     if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL;
 524     break;
 525   case vmIntrinsics::_decrementExactI:
 526   case vmIntrinsics::_subtractExactI:
 527     if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL;
 528     break;
 529   case vmIntrinsics::_decrementExactL:
 530   case vmIntrinsics::_subtractExactL:
 531     if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL;
 532     break;
 533   case vmIntrinsics::_negateExactI:
 534     if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL;
 535     break;
 536   case vmIntrinsics::_negateExactL:
 537     if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL;
 538     break;
 539   case vmIntrinsics::_multiplyExactI:
 540     if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL;
 541     break;
 542   case vmIntrinsics::_multiplyExactL:
 543     if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL;
 544     break;
 545 
 546  default:
 547     assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
 548     assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
 549     break;
 550   }
 551 
 552   // -XX:-InlineClassNatives disables natives from the Class class.
 553   // The flag applies to all reflective calls, notably Array.newArray
 554   // (visible to Java programmers as Array.newInstance).
 555   if (m->holder()->name() == ciSymbol::java_lang_Class() ||
 556       m->holder()->name() == ciSymbol::java_lang_reflect_Array()) {
 557     if (!InlineClassNatives)  return NULL;
 558   }
 559 


 696 
 697   switch (intrinsic_id()) {
 698   case vmIntrinsics::_hashCode:                 return inline_native_hashcode(intrinsic()->is_virtual(), !is_static);
 699   case vmIntrinsics::_identityHashCode:         return inline_native_hashcode(/*!virtual*/ false,         is_static);
 700   case vmIntrinsics::_getClass:                 return inline_native_getClass();
 701 
 702   case vmIntrinsics::_dsin:
 703   case vmIntrinsics::_dcos:
 704   case vmIntrinsics::_dtan:
 705   case vmIntrinsics::_dabs:
 706   case vmIntrinsics::_datan2:
 707   case vmIntrinsics::_dsqrt:
 708   case vmIntrinsics::_dexp:
 709   case vmIntrinsics::_dlog:
 710   case vmIntrinsics::_dlog10:
 711   case vmIntrinsics::_dpow:                     return inline_math_native(intrinsic_id());
 712 
 713   case vmIntrinsics::_min:
 714   case vmIntrinsics::_max:                      return inline_min_max(intrinsic_id());
 715 
 716   case vmIntrinsics::_addExactI:                return inline_math_addExactI(false /* add */);
 717   case vmIntrinsics::_addExactL:                return inline_math_addExactL(false /* add */);
 718   case vmIntrinsics::_decrementExactI:          return inline_math_subtractExactI(true /* decrement */);
 719   case vmIntrinsics::_decrementExactL:          return inline_math_subtractExactL(true /* decrement */);
 720   case vmIntrinsics::_incrementExactI:          return inline_math_addExactI(true /* increment */);
 721   case vmIntrinsics::_incrementExactL:          return inline_math_addExactL(true /* increment */);
 722   case vmIntrinsics::_multiplyExactI:           return inline_math_multiplyExactI();
 723   case vmIntrinsics::_multiplyExactL:           return inline_math_multiplyExactL();
 724   case vmIntrinsics::_negateExactI:             return inline_math_negateExactI();
 725   case vmIntrinsics::_negateExactL:             return inline_math_negateExactL();
 726   case vmIntrinsics::_subtractExactI:           return inline_math_subtractExactI(false /* subtract */);
 727   case vmIntrinsics::_subtractExactL:           return inline_math_subtractExactL(false /* subtract */);
 728 
 729   case vmIntrinsics::_arraycopy:                return inline_arraycopy();
 730 
 731   case vmIntrinsics::_compareTo:                return inline_string_compareTo();
 732   case vmIntrinsics::_indexOf:                  return inline_string_indexOf();
 733   case vmIntrinsics::_equals:                   return inline_string_equals();
 734 
 735   case vmIntrinsics::_getObject:                return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT,  !is_volatile);
 736   case vmIntrinsics::_getBoolean:               return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
 737   case vmIntrinsics::_getByte:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_BYTE,    !is_volatile);
 738   case vmIntrinsics::_getShort:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_SHORT,   !is_volatile);
 739   case vmIntrinsics::_getChar:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_CHAR,    !is_volatile);
 740   case vmIntrinsics::_getInt:                   return inline_unsafe_access(!is_native_ptr, !is_store, T_INT,     !is_volatile);
 741   case vmIntrinsics::_getLong:                  return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG,    !is_volatile);
 742   case vmIntrinsics::_getFloat:                 return inline_unsafe_access(!is_native_ptr, !is_store, T_FLOAT,   !is_volatile);
 743   case vmIntrinsics::_getDouble:                return inline_unsafe_access(!is_native_ptr, !is_store, T_DOUBLE,  !is_volatile);
 744 
 745   case vmIntrinsics::_putObject:                return inline_unsafe_access(!is_native_ptr,  is_store, T_OBJECT,  !is_volatile);
 746   case vmIntrinsics::_putBoolean:               return inline_unsafe_access(!is_native_ptr,  is_store, T_BOOLEAN, !is_volatile);
 747   case vmIntrinsics::_putByte:                  return inline_unsafe_access(!is_native_ptr,  is_store, T_BYTE,    !is_volatile);


1955   }
1956 }
1957 
1958 static bool is_simple_name(Node* n) {
1959   return (n->req() == 1         // constant
1960           || (n->is_Type() && n->as_Type()->type()->singleton())
1961           || n->is_Proj()       // parameter or return value
1962           || n->is_Phi()        // local of some sort
1963           );
1964 }
1965 
1966 //----------------------------inline_min_max-----------------------------------
1967 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1968   set_result(generate_min_max(id, argument(0), argument(1)));
1969   return true;
1970 }
1971 
1972 void LibraryCallKit::inline_math_mathExact(Node* math) {
1973   // If we didn't get the expected opcode it means we have optimized
1974   // the node to something else and don't need the exception edge.
1975   if (!math->is_MathExact()) {
1976     set_result(math);
1977     return;
1978   }
1979 
1980   Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
1981   Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1982 
1983   Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
1984   IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1985   Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1986   Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1987 
1988   {
1989     PreserveJVMState pjvms(this);
1990     PreserveReexecuteState preexecs(this);
1991     jvms()->set_should_reexecute(true);
1992 
1993     set_control(slow_path);
1994     set_i_o(i_o());
1995 
1996     uncommon_trap(Deoptimization::Reason_intrinsic,
1997                   Deoptimization::Action_none);
1998   }
1999 
2000   set_control(fast_path);
2001   set_result(result);
2002 }
2003 
2004 bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
2005   Node* arg1 = argument(0);
2006   Node* arg2 = NULL;
2007 
2008   if (is_increment) {
2009       arg2 = intcon(1);
2010   } else {
2011       arg2 = argument(1);
2012   }
2013 
2014   Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
2015   inline_math_mathExact(add);
2016   return true;
2017 }
2018 
2019 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
2020   Node* arg1 = argument(0); // type long
2021   // argument(1) == TOP
2022   Node* arg2 = NULL;
2023 
2024   if (is_increment) {
2025     arg2 = longcon(1);
2026   } else {
2027     arg2 = argument(2); // type long
2028     // argument(3) == TOP
2029   }
2030 
2031   Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
2032   inline_math_mathExact(add);
2033   return true;
2034 }
2035 
2036 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
2037   Node* arg1 = argument(0);
2038   Node* arg2 = NULL;
2039 
2040   if (is_decrement) {
2041     arg2 = intcon(1);
2042   } else {
2043     arg2 = argument(1);
2044   }
2045 
2046   Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
2047   inline_math_mathExact(sub);
2048   return true;
2049 }
2050 
2051 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
2052   Node* arg1 = argument(0); // type long
2053   // argument(1) == TOP
2054   Node* arg2 = NULL;
2055 
2056   if (is_decrement) {
2057     arg2 = longcon(1);
2058   } else {
2059     Node* arg2 = argument(2); // type long
2060     // argument(3) == TOP
2061   }
2062 
2063   Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
2064   inline_math_mathExact(sub);
2065   return true;
2066 }
2067 
2068 bool LibraryCallKit::inline_math_negateExactI() {
2069   Node* arg1 = argument(0);
2070 
2071   Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
2072   inline_math_mathExact(neg);
2073   return true;
2074 }
2075 
2076 bool LibraryCallKit::inline_math_negateExactL() {
2077   Node* arg1 = argument(0);
2078   // argument(1) == TOP
2079 
2080   Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
2081   inline_math_mathExact(neg);
2082   return true;
2083 }
2084 
2085 bool LibraryCallKit::inline_math_multiplyExactI() {
2086   Node* arg1 = argument(0);
2087   Node* arg2 = argument(1);
2088 
2089   Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
2090   inline_math_mathExact(mul);
2091   return true;
2092 }
2093 
2094 bool LibraryCallKit::inline_math_multiplyExactL() {
2095   Node* arg1 = argument(0);
2096   // argument(1) == TOP
2097   Node* arg2 = argument(2);
2098   // argument(3) == TOP
2099 
2100   Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
2101   inline_math_mathExact(mul);






































2102   return true;
2103 }
2104 
2105 Node*
2106 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2107   // These are the candidate return value:
2108   Node* xvalue = x0;
2109   Node* yvalue = y0;
2110 
2111   if (xvalue == yvalue) {
2112     return xvalue;
2113   }
2114 
2115   bool want_max = (id == vmIntrinsics::_max);
2116 
2117   const TypeInt* txvalue = _gvn.type(xvalue)->isa_int();
2118   const TypeInt* tyvalue = _gvn.type(yvalue)->isa_int();
2119   if (txvalue == NULL || tyvalue == NULL)  return top();
2120   // This is not really necessary, but it is consistent with a
2121   // hypothetical MaxINode::Value method:


src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File