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" |
285 bool inline_encodeISOArray(); |
286 bool inline_encodeISOArray(); |
286 bool inline_updateCRC32(); |
287 bool inline_updateCRC32(); |
287 bool inline_updateBytesCRC32(); |
288 bool inline_updateBytesCRC32(); |
288 bool inline_updateByteBufferCRC32(); |
289 bool inline_updateByteBufferCRC32(); |
289 bool inline_multiplyToLen(); |
290 bool inline_multiplyToLen(); |
|
291 |
|
292 bool inline_profileBoolean(); |
290 }; |
293 }; |
291 |
294 |
292 |
295 |
293 //---------------------------make_vm_intrinsic---------------------------- |
296 //---------------------------make_vm_intrinsic---------------------------- |
294 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
297 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
897 return inline_updateCRC32(); |
900 return inline_updateCRC32(); |
898 case vmIntrinsics::_updateBytesCRC32: |
901 case vmIntrinsics::_updateBytesCRC32: |
899 return inline_updateBytesCRC32(); |
902 return inline_updateBytesCRC32(); |
900 case vmIntrinsics::_updateByteBufferCRC32: |
903 case vmIntrinsics::_updateByteBufferCRC32: |
901 return inline_updateByteBufferCRC32(); |
904 return inline_updateByteBufferCRC32(); |
|
905 |
|
906 case vmIntrinsics::_profileBoolean: |
|
907 return inline_profileBoolean(); |
902 |
908 |
903 default: |
909 default: |
904 // If you get here, it may be that someone has added a new intrinsic |
910 // If you get here, it may be that someone has added a new intrinsic |
905 // to the list in vmSymbols.hpp without implementing it here. |
911 // to the list in vmSymbols.hpp without implementing it here. |
906 #ifndef PRODUCT |
912 #ifndef PRODUCT |
5865 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); |
5871 Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne)); |
5866 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
5872 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
5867 |
5873 |
5868 return instof_false; // even if it is NULL |
5874 return instof_false; // even if it is NULL |
5869 } |
5875 } |
|
5876 |
|
5877 bool LibraryCallKit::inline_profileBoolean() { |
|
5878 Node* counts = argument(1); |
|
5879 const TypeAryPtr* ary = NULL; |
|
5880 ciArray* aobj = NULL; |
|
5881 if (counts->is_Con() |
|
5882 && (ary = counts->bottom_type()->isa_aryptr()) != NULL |
|
5883 && (aobj = ary->const_oop()->as_array()) != NULL |
|
5884 && (aobj->length() == 2)) { |
|
5885 // Profile is int[2] where [0] and [1] correspond to false and true value occurrences respectively. |
|
5886 jint false_cnt = aobj->element_value(0).as_int(); |
|
5887 jint true_cnt = aobj->element_value(1).as_int(); |
|
5888 |
|
5889 method()->set_injected_profile(true); |
|
5890 |
|
5891 if (C->log() != NULL) { |
|
5892 C->log()->elem("observe source='profileBoolean' false='%d' true='%d'", |
|
5893 false_cnt, true_cnt); |
|
5894 } |
|
5895 |
|
5896 if (false_cnt + true_cnt == 0) { |
|
5897 // According to profile, never executed. |
|
5898 uncommon_trap_exact(Deoptimization::Reason_intrinsic, |
|
5899 Deoptimization::Action_reinterpret); |
|
5900 return true; |
|
5901 } |
|
5902 // Stop profiling. |
|
5903 // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode. |
|
5904 // By replacing method's body with profile data (represented as ProfileBooleanNode |
|
5905 // on IR level) we effectively disable profiling. |
|
5906 // It enables full speed execution once optimized code is generated. |
|
5907 Node* profile = _gvn.transform(new ProfileBooleanNode(argument(0), false_cnt, true_cnt)); |
|
5908 C->record_for_igvn(profile); |
|
5909 set_result(profile); |
|
5910 return true; |
|
5911 } else { |
|
5912 // Continue profiling. |
|
5913 // Profile data isn't available at the moment. So, execute method's bytecode version. |
|
5914 // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod |
|
5915 // is compiled and counters aren't available since corresponding MethodHandle |
|
5916 // isn't a compile-time constant. |
|
5917 return false; |
|
5918 } |
|
5919 } |