hotspot/src/share/vm/opto/library_call.cpp
changeset 28912 27fac2f8fdbe
parent 28719 5a9aedf87213
child 28932 4df7f6cfac99
equal deleted inserted replaced
28730:106944a21769 28912:27fac2f8fdbe
    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 }