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
|