comparison src/share/vm/opto/library_call.cpp @ 17810:62c54fcc0a35

Merge
author kvn
date Tue, 25 Mar 2014 17:07:36 -0700
parents 7c462558a08a 9ab9f254cfe2
children 400709e275c1
comparison
equal deleted inserted replaced
17809:a433eb716ce1 17810:62c54fcc0a35
201 Node* round_double_node(Node* n); 201 Node* round_double_node(Node* n);
202 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName); 202 bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
203 bool inline_math_native(vmIntrinsics::ID id); 203 bool inline_math_native(vmIntrinsics::ID id);
204 bool inline_trig(vmIntrinsics::ID id); 204 bool inline_trig(vmIntrinsics::ID id);
205 bool inline_math(vmIntrinsics::ID id); 205 bool inline_math(vmIntrinsics::ID id);
206 void inline_math_mathExact(Node* math); 206 template <typename OverflowOp>
207 bool inline_math_overflow(Node* arg1, Node* arg2);
208 void inline_math_mathExact(Node* math, Node* test);
207 bool inline_math_addExactI(bool is_increment); 209 bool inline_math_addExactI(bool is_increment);
208 bool inline_math_addExactL(bool is_increment); 210 bool inline_math_addExactL(bool is_increment);
209 bool inline_math_multiplyExactI(); 211 bool inline_math_multiplyExactI();
210 bool inline_math_multiplyExactL(); 212 bool inline_math_multiplyExactL();
211 bool inline_math_negateExactI(); 213 bool inline_math_negateExactI();
515 if (!UseCRC32Intrinsics) return NULL; 517 if (!UseCRC32Intrinsics) return NULL;
516 break; 518 break;
517 519
518 case vmIntrinsics::_incrementExactI: 520 case vmIntrinsics::_incrementExactI:
519 case vmIntrinsics::_addExactI: 521 case vmIntrinsics::_addExactI:
520 if (!Matcher::match_rule_supported(Op_AddExactI) || !UseMathExactIntrinsics) return NULL; 522 if (!Matcher::match_rule_supported(Op_OverflowAddI) || !UseMathExactIntrinsics) return NULL;
521 break; 523 break;
522 case vmIntrinsics::_incrementExactL: 524 case vmIntrinsics::_incrementExactL:
523 case vmIntrinsics::_addExactL: 525 case vmIntrinsics::_addExactL:
524 if (!Matcher::match_rule_supported(Op_AddExactL) || !UseMathExactIntrinsics) return NULL; 526 if (!Matcher::match_rule_supported(Op_OverflowAddL) || !UseMathExactIntrinsics) return NULL;
525 break; 527 break;
526 case vmIntrinsics::_decrementExactI: 528 case vmIntrinsics::_decrementExactI:
527 case vmIntrinsics::_subtractExactI: 529 case vmIntrinsics::_subtractExactI:
528 if (!Matcher::match_rule_supported(Op_SubExactI) || !UseMathExactIntrinsics) return NULL; 530 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
529 break; 531 break;
530 case vmIntrinsics::_decrementExactL: 532 case vmIntrinsics::_decrementExactL:
531 case vmIntrinsics::_subtractExactL: 533 case vmIntrinsics::_subtractExactL:
532 if (!Matcher::match_rule_supported(Op_SubExactL) || !UseMathExactIntrinsics) return NULL; 534 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
533 break; 535 break;
534 case vmIntrinsics::_negateExactI: 536 case vmIntrinsics::_negateExactI:
535 if (!Matcher::match_rule_supported(Op_NegExactI) || !UseMathExactIntrinsics) return NULL; 537 if (!Matcher::match_rule_supported(Op_OverflowSubI) || !UseMathExactIntrinsics) return NULL;
536 break; 538 break;
537 case vmIntrinsics::_negateExactL: 539 case vmIntrinsics::_negateExactL:
538 if (!Matcher::match_rule_supported(Op_NegExactL) || !UseMathExactIntrinsics) return NULL; 540 if (!Matcher::match_rule_supported(Op_OverflowSubL) || !UseMathExactIntrinsics) return NULL;
539 break; 541 break;
540 case vmIntrinsics::_multiplyExactI: 542 case vmIntrinsics::_multiplyExactI:
541 if (!Matcher::match_rule_supported(Op_MulExactI) || !UseMathExactIntrinsics) return NULL; 543 if (!Matcher::match_rule_supported(Op_OverflowMulI) || !UseMathExactIntrinsics) return NULL;
542 break; 544 break;
543 case vmIntrinsics::_multiplyExactL: 545 case vmIntrinsics::_multiplyExactL:
544 if (!Matcher::match_rule_supported(Op_MulExactL) || !UseMathExactIntrinsics) return NULL; 546 if (!Matcher::match_rule_supported(Op_OverflowMulL) || !UseMathExactIntrinsics) return NULL;
545 break; 547 break;
546 548
547 default: 549 default:
548 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); 550 assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
549 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); 551 assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
1968 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) { 1970 bool LibraryCallKit::inline_min_max(vmIntrinsics::ID id) {
1969 set_result(generate_min_max(id, argument(0), argument(1))); 1971 set_result(generate_min_max(id, argument(0), argument(1)));
1970 return true; 1972 return true;
1971 } 1973 }
1972 1974
1973 void LibraryCallKit::inline_math_mathExact(Node* math) { 1975 void LibraryCallKit::inline_math_mathExact(Node* math, Node *test) {
1974 // If we didn't get the expected opcode it means we have optimized 1976 Node* bol = _gvn.transform( new (C) BoolNode(test, BoolTest::overflow) );
1975 // the node to something else and don't need the exception edge.
1976 if (!math->is_MathExact()) {
1977 set_result(math);
1978 return;
1979 }
1980
1981 Node* result = _gvn.transform( new(C) ProjNode(math, MathExactNode::result_proj_node));
1982 Node* flags = _gvn.transform( new(C) FlagsProjNode(math, MathExactNode::flags_proj_node));
1983
1984 Node* bol = _gvn.transform( new (C) BoolNode(flags, BoolTest::overflow) );
1985 IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); 1977 IfNode* check = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
1986 Node* fast_path = _gvn.transform( new (C) IfFalseNode(check)); 1978 Node* fast_path = _gvn.transform( new (C) IfFalseNode(check));
1987 Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) ); 1979 Node* slow_path = _gvn.transform( new (C) IfTrueNode(check) );
1988 1980
1989 { 1981 {
1997 uncommon_trap(Deoptimization::Reason_intrinsic, 1989 uncommon_trap(Deoptimization::Reason_intrinsic,
1998 Deoptimization::Action_none); 1990 Deoptimization::Action_none);
1999 } 1991 }
2000 1992
2001 set_control(fast_path); 1993 set_control(fast_path);
2002 set_result(result); 1994 set_result(math);
1995 }
1996
1997 template <typename OverflowOp>
1998 bool LibraryCallKit::inline_math_overflow(Node* arg1, Node* arg2) {
1999 typedef typename OverflowOp::MathOp MathOp;
2000
2001 MathOp* mathOp = new(C) MathOp(arg1, arg2);
2002 Node* operation = _gvn.transform( mathOp );
2003 Node* ofcheck = _gvn.transform( new(C) OverflowOp(arg1, arg2) );
2004 inline_math_mathExact(operation, ofcheck);
2005 return true;
2003 } 2006 }
2004 2007
2005 bool LibraryCallKit::inline_math_addExactI(bool is_increment) { 2008 bool LibraryCallKit::inline_math_addExactI(bool is_increment) {
2006 Node* arg1 = argument(0); 2009 return inline_math_overflow<OverflowAddINode>(argument(0), is_increment ? intcon(1) : argument(1));
2007 Node* arg2 = NULL;
2008
2009 if (is_increment) {
2010 arg2 = intcon(1);
2011 } else {
2012 arg2 = argument(1);
2013 }
2014
2015 Node* add = _gvn.transform( new(C) AddExactINode(NULL, arg1, arg2) );
2016 inline_math_mathExact(add);
2017 return true;
2018 } 2010 }
2019 2011
2020 bool LibraryCallKit::inline_math_addExactL(bool is_increment) { 2012 bool LibraryCallKit::inline_math_addExactL(bool is_increment) {
2021 Node* arg1 = argument(0); // type long 2013 return inline_math_overflow<OverflowAddLNode>(argument(0), is_increment ? longcon(1) : argument(2));
2022 // argument(1) == TOP
2023 Node* arg2 = NULL;
2024
2025 if (is_increment) {
2026 arg2 = longcon(1);
2027 } else {
2028 arg2 = argument(2); // type long
2029 // argument(3) == TOP
2030 }
2031
2032 Node* add = _gvn.transform(new(C) AddExactLNode(NULL, arg1, arg2));
2033 inline_math_mathExact(add);
2034 return true;
2035 } 2014 }
2036 2015
2037 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) { 2016 bool LibraryCallKit::inline_math_subtractExactI(bool is_decrement) {
2038 Node* arg1 = argument(0); 2017 return inline_math_overflow<OverflowSubINode>(argument(0), is_decrement ? intcon(1) : argument(1));
2039 Node* arg2 = NULL;
2040
2041 if (is_decrement) {
2042 arg2 = intcon(1);
2043 } else {
2044 arg2 = argument(1);
2045 }
2046
2047 Node* sub = _gvn.transform(new(C) SubExactINode(NULL, arg1, arg2));
2048 inline_math_mathExact(sub);
2049 return true;
2050 } 2018 }
2051 2019
2052 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) { 2020 bool LibraryCallKit::inline_math_subtractExactL(bool is_decrement) {
2053 Node* arg1 = argument(0); // type long 2021 return inline_math_overflow<OverflowSubLNode>(argument(0), is_decrement ? longcon(1) : argument(2));
2054 // argument(1) == TOP
2055 Node* arg2 = NULL;
2056
2057 if (is_decrement) {
2058 arg2 = longcon(1);
2059 } else {
2060 arg2 = argument(2); // type long
2061 // argument(3) == TOP
2062 }
2063
2064 Node* sub = _gvn.transform(new(C) SubExactLNode(NULL, arg1, arg2));
2065 inline_math_mathExact(sub);
2066 return true;
2067 } 2022 }
2068 2023
2069 bool LibraryCallKit::inline_math_negateExactI() { 2024 bool LibraryCallKit::inline_math_negateExactI() {
2070 Node* arg1 = argument(0); 2025 return inline_math_overflow<OverflowSubINode>(intcon(0), argument(0));
2071
2072 Node* neg = _gvn.transform(new(C) NegExactINode(NULL, arg1));
2073 inline_math_mathExact(neg);
2074 return true;
2075 } 2026 }
2076 2027
2077 bool LibraryCallKit::inline_math_negateExactL() { 2028 bool LibraryCallKit::inline_math_negateExactL() {
2078 Node* arg1 = argument(0); 2029 return inline_math_overflow<OverflowSubLNode>(longcon(0), argument(0));
2079 // argument(1) == TOP
2080
2081 Node* neg = _gvn.transform(new(C) NegExactLNode(NULL, arg1));
2082 inline_math_mathExact(neg);
2083 return true;
2084 } 2030 }
2085 2031
2086 bool LibraryCallKit::inline_math_multiplyExactI() { 2032 bool LibraryCallKit::inline_math_multiplyExactI() {
2087 Node* arg1 = argument(0); 2033 return inline_math_overflow<OverflowMulINode>(argument(0), argument(1));
2088 Node* arg2 = argument(1);
2089
2090 Node* mul = _gvn.transform(new(C) MulExactINode(NULL, arg1, arg2));
2091 inline_math_mathExact(mul);
2092 return true;
2093 } 2034 }
2094 2035
2095 bool LibraryCallKit::inline_math_multiplyExactL() { 2036 bool LibraryCallKit::inline_math_multiplyExactL() {
2096 Node* arg1 = argument(0); 2037 return inline_math_overflow<OverflowMulLNode>(argument(0), argument(2));
2097 // argument(1) == TOP
2098 Node* arg2 = argument(2);
2099 // argument(3) == TOP
2100
2101 Node* mul = _gvn.transform(new(C) MulExactLNode(NULL, arg1, arg2));
2102 inline_math_mathExact(mul);
2103 return true;
2104 } 2038 }
2105 2039
2106 Node* 2040 Node*
2107 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { 2041 LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) {
2108 // These are the candidate return value: 2042 // These are the candidate return value:
2664 } 2598 }
2665 break; 2599 break;
2666 case T_ADDRESS: 2600 case T_ADDRESS:
2667 // Cast to an int type. 2601 // Cast to an int type.
2668 p = _gvn.transform(new (C) CastP2XNode(NULL, p)); 2602 p = _gvn.transform(new (C) CastP2XNode(NULL, p));
2669 p = ConvX2L(p); 2603 p = ConvX2UL(p);
2670 break; 2604 break;
2671 default: 2605 default:
2672 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type))); 2606 fatal(err_msg_res("unexpected type %d: %s", type, type2name(type)));
2673 break; 2607 break;
2674 } 2608 }
3244 3178
3245 //------------------------inline_native_isInterrupted------------------ 3179 //------------------------inline_native_isInterrupted------------------
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); 3180 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
3247 bool LibraryCallKit::inline_native_isInterrupted() { 3181 bool LibraryCallKit::inline_native_isInterrupted() {
3248 // Add a fast path to t.isInterrupted(clear_int): 3182 // Add a fast path to t.isInterrupted(clear_int):
3249 // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) 3183 // (t == Thread.current() &&
3184 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
3250 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) 3185 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
3251 // So, in the common case that the interrupt bit is false, 3186 // So, in the common case that the interrupt bit is false,
3252 // we avoid making a call into the VM. Even if the interrupt bit 3187 // we avoid making a call into the VM. Even if the interrupt bit
3253 // is true, if the clear_int argument is false, we avoid the VM call. 3188 // is true, if the clear_int argument is false, we avoid the VM call.
3254 // However, if the receiver is not currentThread, we must call the VM, 3189 // However, if the receiver is not currentThread, we must call the VM,
3301 result_val->init_req(no_int_result_path, intcon(0)); 3236 result_val->init_req(no_int_result_path, intcon(0));
3302 3237
3303 // drop through to next case 3238 // drop through to next case
3304 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); 3239 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
3305 3240
3241 #ifndef TARGET_OS_FAMILY_windows
3306 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. 3242 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
3307 Node* clr_arg = argument(1); 3243 Node* clr_arg = argument(1);
3308 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); 3244 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
3309 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); 3245 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
3310 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); 3246 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
3314 result_rgn->init_req(no_clear_result_path, false_arg); 3250 result_rgn->init_req(no_clear_result_path, false_arg);
3315 result_val->init_req(no_clear_result_path, intcon(1)); 3251 result_val->init_req(no_clear_result_path, intcon(1));
3316 3252
3317 // drop through to next case 3253 // drop through to next case
3318 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); 3254 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
3255 #else
3256 // To return true on Windows you must read the _interrupted field
3257 // and check the the event state i.e. take the slow path.
3258 #endif // TARGET_OS_FAMILY_windows
3319 3259
3320 // (d) Otherwise, go to the slow path. 3260 // (d) Otherwise, go to the slow path.
3321 slow_region->add_req(control()); 3261 slow_region->add_req(control());
3322 set_control( _gvn.transform(slow_region)); 3262 set_control( _gvn.transform(slow_region));
3323 3263