29 #include "compiler/compileLog.hpp" |
29 #include "compiler/compileLog.hpp" |
30 #include "oops/objArrayKlass.hpp" |
30 #include "oops/objArrayKlass.hpp" |
31 #include "opto/addnode.hpp" |
31 #include "opto/addnode.hpp" |
32 #include "opto/callGenerator.hpp" |
32 #include "opto/callGenerator.hpp" |
33 #include "opto/cfgnode.hpp" |
33 #include "opto/cfgnode.hpp" |
|
34 #include "opto/connode.hpp" |
34 #include "opto/idealKit.hpp" |
35 #include "opto/idealKit.hpp" |
35 #include "opto/mathexactnode.hpp" |
36 #include "opto/mathexactnode.hpp" |
36 #include "opto/mulnode.hpp" |
37 #include "opto/mulnode.hpp" |
37 #include "opto/parse.hpp" |
38 #include "opto/parse.hpp" |
38 #include "opto/runtime.hpp" |
39 #include "opto/runtime.hpp" |
321 bool inline_encodeISOArray(); |
322 bool inline_encodeISOArray(); |
322 bool inline_updateCRC32(); |
323 bool inline_updateCRC32(); |
323 bool inline_updateBytesCRC32(); |
324 bool inline_updateBytesCRC32(); |
324 bool inline_updateByteBufferCRC32(); |
325 bool inline_updateByteBufferCRC32(); |
325 bool inline_multiplyToLen(); |
326 bool inline_multiplyToLen(); |
|
327 |
|
328 bool inline_profileBoolean(); |
326 }; |
329 }; |
327 |
330 |
328 |
331 |
329 //---------------------------make_vm_intrinsic---------------------------- |
332 //---------------------------make_vm_intrinsic---------------------------- |
330 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
333 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { |
931 return inline_updateCRC32(); |
934 return inline_updateCRC32(); |
932 case vmIntrinsics::_updateBytesCRC32: |
935 case vmIntrinsics::_updateBytesCRC32: |
933 return inline_updateBytesCRC32(); |
936 return inline_updateBytesCRC32(); |
934 case vmIntrinsics::_updateByteBufferCRC32: |
937 case vmIntrinsics::_updateByteBufferCRC32: |
935 return inline_updateByteBufferCRC32(); |
938 return inline_updateByteBufferCRC32(); |
|
939 |
|
940 case vmIntrinsics::_profileBoolean: |
|
941 return inline_profileBoolean(); |
936 |
942 |
937 default: |
943 default: |
938 // If you get here, it may be that someone has added a new intrinsic |
944 // If you get here, it may be that someone has added a new intrinsic |
939 // to the list in vmSymbols.hpp without implementing it here. |
945 // to the list in vmSymbols.hpp without implementing it here. |
940 #ifndef PRODUCT |
946 #ifndef PRODUCT |
6542 Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne)); |
6548 Node* bool_instof = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne)); |
6543 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
6549 Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN); |
6544 |
6550 |
6545 return instof_false; // even if it is NULL |
6551 return instof_false; // even if it is NULL |
6546 } |
6552 } |
|
6553 |
|
6554 bool LibraryCallKit::inline_profileBoolean() { |
|
6555 Node* counts = argument(1); |
|
6556 const TypeAryPtr* ary = NULL; |
|
6557 ciArray* aobj = NULL; |
|
6558 if (counts->is_Con() |
|
6559 && (ary = counts->bottom_type()->isa_aryptr()) != NULL |
|
6560 && (aobj = ary->const_oop()->as_array()) != NULL |
|
6561 && (aobj->length() == 2)) { |
|
6562 // Profile is int[2] where [0] and [1] correspond to false and true value occurrences respectively. |
|
6563 jint false_cnt = aobj->element_value(0).as_int(); |
|
6564 jint true_cnt = aobj->element_value(1).as_int(); |
|
6565 |
|
6566 method()->set_injected_profile(true); |
|
6567 |
|
6568 if (C->log() != NULL) { |
|
6569 C->log()->elem("observe source='profileBoolean' false='%d' true='%d'", |
|
6570 false_cnt, true_cnt); |
|
6571 } |
|
6572 |
|
6573 if (false_cnt + true_cnt == 0) { |
|
6574 // According to profile, never executed. |
|
6575 uncommon_trap_exact(Deoptimization::Reason_intrinsic, |
|
6576 Deoptimization::Action_reinterpret); |
|
6577 return true; |
|
6578 } |
|
6579 // Stop profiling. |
|
6580 // MethodHandleImpl::profileBoolean() has profiling logic in it's bytecode. |
|
6581 // By replacing method's body with profile data (represented as ProfileBooleanNode |
|
6582 // on IR level) we effectively disable profiling. |
|
6583 // It enables full speed execution once optimized code is generated. |
|
6584 Node* profile = _gvn.transform(new (C) ProfileBooleanNode(argument(0), false_cnt, true_cnt)); |
|
6585 C->record_for_igvn(profile); |
|
6586 set_result(profile); |
|
6587 return true; |
|
6588 } else { |
|
6589 // Continue profiling. |
|
6590 // Profile data isn't available at the moment. So, execute method's bytecode version. |
|
6591 // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod |
|
6592 // is compiled and counters aren't available since corresponding MethodHandle |
|
6593 // isn't a compile-time constant. |
|
6594 return false; |
|
6595 } |
|
6596 } |