39 #include "opto/idealKit.hpp" |
39 #include "opto/idealKit.hpp" |
40 #include "opto/mathexactnode.hpp" |
40 #include "opto/mathexactnode.hpp" |
41 #include "opto/movenode.hpp" |
41 #include "opto/movenode.hpp" |
42 #include "opto/mulnode.hpp" |
42 #include "opto/mulnode.hpp" |
43 #include "opto/narrowptrnode.hpp" |
43 #include "opto/narrowptrnode.hpp" |
|
44 #include "opto/opaquenode.hpp" |
44 #include "opto/parse.hpp" |
45 #include "opto/parse.hpp" |
45 #include "opto/runtime.hpp" |
46 #include "opto/runtime.hpp" |
46 #include "opto/subnode.hpp" |
47 #include "opto/subnode.hpp" |
47 #include "prims/nativeLookup.hpp" |
48 #include "prims/nativeLookup.hpp" |
48 #include "runtime/sharedRuntime.hpp" |
49 #include "runtime/sharedRuntime.hpp" |
284 bool inline_encodeISOArray(); |
285 bool inline_encodeISOArray(); |
285 bool inline_updateCRC32(); |
286 bool inline_updateCRC32(); |
286 bool inline_updateBytesCRC32(); |
287 bool inline_updateBytesCRC32(); |
287 bool inline_updateByteBufferCRC32(); |
288 bool inline_updateByteBufferCRC32(); |
288 bool inline_multiplyToLen(); |
289 bool inline_multiplyToLen(); |
|
290 |
|
291 bool inline_profileBoolean(); |
289 }; |
292 }; |
290 |
293 |
291 |
294 |
292 //---------------------------make_vm_intrinsic---------------------------- |
295 //---------------------------make_vm_intrinsic---------------------------- |
293 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
296 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
891 return inline_updateCRC32(); |
894 return inline_updateCRC32(); |
892 case vmIntrinsics::_updateBytesCRC32: |
895 case vmIntrinsics::_updateBytesCRC32: |
893 return inline_updateBytesCRC32(); |
896 return inline_updateBytesCRC32(); |
894 case vmIntrinsics::_updateByteBufferCRC32: |
897 case vmIntrinsics::_updateByteBufferCRC32: |
895 return inline_updateByteBufferCRC32(); |
898 return inline_updateByteBufferCRC32(); |
|
899 |
|
900 case vmIntrinsics::_profileBoolean: |
|
901 return inline_profileBoolean(); |
896 |
902 |
897 default: |
903 default: |
898 // If you get here, it may be that someone has added a new intrinsic |
904 // If you get here, it may be that someone has added a new intrinsic |
899 // to the list in vmSymbols.hpp without implementing it here. |
905 // to the list in vmSymbols.hpp without implementing it here. |
900 #ifndef PRODUCT |
906 #ifndef PRODUCT |
4659 |
4665 |
4660 // Check for allocation before we add nodes that would confuse |
4666 // Check for allocation before we add nodes that would confuse |
4661 // tightly_coupled_allocation() |
4667 // tightly_coupled_allocation() |
4662 AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL); |
4668 AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL); |
4663 |
4669 |
|
4670 ciMethod* trap_method = method(); |
|
4671 int trap_bci = bci(); |
4664 SafePointNode* sfpt = NULL; |
4672 SafePointNode* sfpt = NULL; |
4665 if (alloc != NULL) { |
4673 if (alloc != NULL) { |
4666 // The JVM state for uncommon traps between the allocation and |
4674 // The JVM state for uncommon traps between the allocation and |
4667 // arraycopy is set to the state before the allocation: if the |
4675 // arraycopy is set to the state before the allocation: if the |
4668 // initialization is performed by the array copy, we don't want to |
4676 // initialization is performed by the array copy, we don't want to |
4683 jvms->set_endoff(jvms->endoff()+1); |
4691 jvms->set_endoff(jvms->endoff()+1); |
4684 jvms->set_should_reexecute(true); |
4692 jvms->set_should_reexecute(true); |
4685 |
4693 |
4686 sfpt->set_i_o(map()->i_o()); |
4694 sfpt->set_i_o(map()->i_o()); |
4687 sfpt->set_memory(map()->memory()); |
4695 sfpt->set_memory(map()->memory()); |
|
4696 |
|
4697 trap_method = jvms->method(); |
|
4698 trap_bci = jvms->bci(); |
4688 } |
4699 } |
4689 |
4700 |
4690 bool validated = false; |
4701 bool validated = false; |
4691 |
4702 |
4692 const Type* src_type = _gvn.type(src); |
4703 const Type* src_type = _gvn.type(src); |
4787 } |
4798 } |
4788 } |
4799 } |
4789 } |
4800 } |
4790 } |
4801 } |
4791 |
4802 |
4792 if (!too_many_traps(Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { |
4803 if (!C->too_many_traps(trap_method, trap_bci, Deoptimization::Reason_intrinsic) && !src->is_top() && !dest->is_top()) { |
4793 // validate arguments: enables transformation the ArrayCopyNode |
4804 // validate arguments: enables transformation the ArrayCopyNode |
4794 validated = true; |
4805 validated = true; |
4795 |
4806 |
4796 RegionNode* slow_region = new RegionNode(1); |
4807 RegionNode* slow_region = new RegionNode(1); |
4797 record_for_igvn(slow_region); |
4808 record_for_igvn(slow_region); |
5792 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); |
5803 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); |
5793 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
5804 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
5794 |
5805 |
5795 return instof_false; // even if it is NULL |
5806 return instof_false; // even if it is NULL |
5796 } |
5807 } |
|
5808 |
|
5809 bool LibraryCallKit::inline_profileBoolean() { |
|
5810 Node* counts = argument(1); |
|
5811 const TypeAryPtr* ary = NULL; |
|
5812 ciArray* aobj = NULL; |
|
5813 if (counts->is_Con() |
|
5814 && (ary = counts->bottom_type()->isa_aryptr()) != NULL |
|
5815 && (aobj = ary->const_oop()->as_array()) != NULL |
|
5816 && (aobj->length() == 2)) { |
|
5817 // Profile is int[2] where [0] and [1] correspond to false and true value occurrences respectively. |
|
5818 jint false_cnt = aobj->element_value(0).as_int(); |
|
5819 jint true_cnt = aobj->element_value(1).as_int(); |
|
5820 |
|
5821 method()->set_injected_profile(true); |
|
5822 |
|
5823 if (C->log() != NULL) { |
|
5824 C->log()->elem("observe source='profileBoolean' false='%d' true='%d'", |
|
5825 false_cnt, true_cnt); |
|
5826 } |
|
5827 |
|
5828 if (false_cnt + true_cnt == 0) { |
|
5829 // According to profile, never executed. |
|
5830 uncommon_trap_exact(Deoptimization::Reason_intrinsic, |
|
5831 Deoptimization::Action_reinterpret); |
|
5832 return true; |
|
5833 } |
|
5834 // Stop profiling. |
|
5835 // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode. |
|
5836 // By replacing method's body with profile data (represented as ProfileBooleanNode |
|
5837 // on IR level) we effectively disable profiling. |
|
5838 // It enables full speed execution once optimized code is generated. |
|
5839 Node* profile = _gvn.transform(new ProfileBooleanNode(argument(0), false_cnt, true_cnt)); |
|
5840 C->record_for_igvn(profile); |
|
5841 set_result(profile); |
|
5842 return true; |
|
5843 } else { |
|
5844 // Continue profiling. |
|
5845 // Profile data isn't available at the moment. So, execute method's bytecode version. |
|
5846 // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod |
|
5847 // is compiled and counters aren't available since corresponding MethodHandle |
|
5848 // isn't a compile-time constant. |
|
5849 return false; |
|
5850 } |
|
5851 } |