src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page
rev 7652 : 8063137: Never-taken branches should be pruned when GWT LambdaForms are shared
Reviewed-by: ?
rev 7653 : [mq]: branch.freq.1


  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "oops/objArrayKlass.hpp"
  32 #include "opto/addnode.hpp"
  33 #include "opto/callGenerator.hpp"
  34 #include "opto/castnode.hpp"
  35 #include "opto/cfgnode.hpp"
  36 #include "opto/convertnode.hpp"
  37 #include "opto/countbitsnode.hpp"
  38 #include "opto/intrinsicnode.hpp"
  39 #include "opto/idealKit.hpp"
  40 #include "opto/mathexactnode.hpp"
  41 #include "opto/movenode.hpp"
  42 #include "opto/mulnode.hpp"
  43 #include "opto/narrowptrnode.hpp"

  44 #include "opto/parse.hpp"
  45 #include "opto/runtime.hpp"
  46 #include "opto/subnode.hpp"
  47 #include "prims/nativeLookup.hpp"
  48 #include "runtime/sharedRuntime.hpp"
  49 #include "trace/traceMacros.hpp"
  50 
  51 class LibraryIntrinsic : public InlineCallGenerator {
  52   // Extend the set of intrinsics known to the runtime:
  53  public:
  54  private:
  55   bool             _is_virtual;
  56   bool             _does_virtual_dispatch;
  57   int8_t           _predicates_count;  // Intrinsic is predicated by several conditions
  58   int8_t           _last_predicate; // Last generated predicate
  59   vmIntrinsics::ID _intrinsic_id;
  60 
  61  public:
  62   LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
  63     : InlineCallGenerator(m),


 270   bool inline_reference_get();
 271   bool inline_Class_cast();
 272   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 273   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 274   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 275   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 276   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 277   bool inline_sha_implCompress(vmIntrinsics::ID id);
 278   bool inline_digestBase_implCompressMB(int predicate);
 279   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
 280                                  bool long_state, address stubAddr, const char *stubName,
 281                                  Node* src_start, Node* ofs, Node* limit);
 282   Node* get_state_from_sha_object(Node *sha_object);
 283   Node* get_state_from_sha5_object(Node *sha_object);
 284   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 285   bool inline_encodeISOArray();
 286   bool inline_updateCRC32();
 287   bool inline_updateBytesCRC32();
 288   bool inline_updateByteBufferCRC32();
 289   bool inline_multiplyToLen();


 290 };
 291 
 292 
 293 //---------------------------make_vm_intrinsic----------------------------
 294 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 295   vmIntrinsics::ID id = m->intrinsic_id();
 296   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 297 
 298   ccstr disable_intr = NULL;
 299 
 300   if ((DisableIntrinsic[0] != '\0'
 301        && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
 302       (method_has_option_value("DisableIntrinsic", disable_intr)
 303        && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
 304     // disabled by a user request on the command line:
 305     // example: -XX:DisableIntrinsic=_hashCode,_getClass
 306     return NULL;
 307   }
 308 
 309   if (!m->is_loaded()) {


 883   case vmIntrinsics::_sha2_implCompress:
 884   case vmIntrinsics::_sha5_implCompress:
 885     return inline_sha_implCompress(intrinsic_id());
 886 
 887   case vmIntrinsics::_digestBase_implCompressMB:
 888     return inline_digestBase_implCompressMB(predicate);
 889 
 890   case vmIntrinsics::_multiplyToLen:
 891     return inline_multiplyToLen();
 892 
 893   case vmIntrinsics::_encodeISOArray:
 894     return inline_encodeISOArray();
 895 
 896   case vmIntrinsics::_updateCRC32:
 897     return inline_updateCRC32();
 898   case vmIntrinsics::_updateBytesCRC32:
 899     return inline_updateBytesCRC32();
 900   case vmIntrinsics::_updateByteBufferCRC32:
 901     return inline_updateByteBufferCRC32();
 902 



 903   default:
 904     // 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.
 906 #ifndef PRODUCT
 907     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 908       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 909                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 910     }
 911 #endif
 912     return false;
 913   }
 914 }
 915 
 916 Node* LibraryCallKit::try_to_predicate(int predicate) {
 917   if (!jvms()->has_method()) {
 918     // Root JVMState has a null method.
 919     assert(map()->memory()->Opcode() == Op_Parm, "");
 920     // Insert the memory aliasing node
 921     set_all_memory(reset_memory());
 922   }


5856 
5857   ciKlass* klass_SHA = NULL;
5858   if (klass_SHA_name != NULL) {
5859     klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
5860   }
5861   if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
5862     // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
5863     Node* ctrl = control();
5864     set_control(top()); // no intrinsic path
5865     return ctrl;
5866   }
5867   ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
5868 
5869   Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
5870   Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1)));
5871   Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne));
5872   Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
5873 
5874   return instof_false;  // even if it is NULL
5875 }











































  24 
  25 #include "precompiled.hpp"
  26 #include "asm/macroAssembler.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "classfile/vmSymbols.hpp"
  29 #include "compiler/compileBroker.hpp"
  30 #include "compiler/compileLog.hpp"
  31 #include "oops/objArrayKlass.hpp"
  32 #include "opto/addnode.hpp"
  33 #include "opto/callGenerator.hpp"
  34 #include "opto/castnode.hpp"
  35 #include "opto/cfgnode.hpp"
  36 #include "opto/convertnode.hpp"
  37 #include "opto/countbitsnode.hpp"
  38 #include "opto/intrinsicnode.hpp"
  39 #include "opto/idealKit.hpp"
  40 #include "opto/mathexactnode.hpp"
  41 #include "opto/movenode.hpp"
  42 #include "opto/mulnode.hpp"
  43 #include "opto/narrowptrnode.hpp"
  44 #include "opto/opaquenode.hpp"
  45 #include "opto/parse.hpp"
  46 #include "opto/runtime.hpp"
  47 #include "opto/subnode.hpp"
  48 #include "prims/nativeLookup.hpp"
  49 #include "runtime/sharedRuntime.hpp"
  50 #include "trace/traceMacros.hpp"
  51 
  52 class LibraryIntrinsic : public InlineCallGenerator {
  53   // Extend the set of intrinsics known to the runtime:
  54  public:
  55  private:
  56   bool             _is_virtual;
  57   bool             _does_virtual_dispatch;
  58   int8_t           _predicates_count;  // Intrinsic is predicated by several conditions
  59   int8_t           _last_predicate; // Last generated predicate
  60   vmIntrinsics::ID _intrinsic_id;
  61 
  62  public:
  63   LibraryIntrinsic(ciMethod* m, bool is_virtual, int predicates_count, bool does_virtual_dispatch, vmIntrinsics::ID id)
  64     : InlineCallGenerator(m),


 271   bool inline_reference_get();
 272   bool inline_Class_cast();
 273   bool inline_aescrypt_Block(vmIntrinsics::ID id);
 274   bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
 275   Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
 276   Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 277   Node* get_original_key_start_from_aescrypt_object(Node* aescrypt_object);
 278   bool inline_sha_implCompress(vmIntrinsics::ID id);
 279   bool inline_digestBase_implCompressMB(int predicate);
 280   bool inline_sha_implCompressMB(Node* digestBaseObj, ciInstanceKlass* instklass_SHA,
 281                                  bool long_state, address stubAddr, const char *stubName,
 282                                  Node* src_start, Node* ofs, Node* limit);
 283   Node* get_state_from_sha_object(Node *sha_object);
 284   Node* get_state_from_sha5_object(Node *sha_object);
 285   Node* inline_digestBase_implCompressMB_predicate(int predicate);
 286   bool inline_encodeISOArray();
 287   bool inline_updateCRC32();
 288   bool inline_updateBytesCRC32();
 289   bool inline_updateByteBufferCRC32();
 290   bool inline_multiplyToLen();
 291 
 292   bool inline_profileBranch();
 293 };
 294 
 295 
 296 //---------------------------make_vm_intrinsic----------------------------
 297 CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
 298   vmIntrinsics::ID id = m->intrinsic_id();
 299   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 300 
 301   ccstr disable_intr = NULL;
 302 
 303   if ((DisableIntrinsic[0] != '\0'
 304        && strstr(DisableIntrinsic, vmIntrinsics::name_at(id)) != NULL) ||
 305       (method_has_option_value("DisableIntrinsic", disable_intr)
 306        && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL)) {
 307     // disabled by a user request on the command line:
 308     // example: -XX:DisableIntrinsic=_hashCode,_getClass
 309     return NULL;
 310   }
 311 
 312   if (!m->is_loaded()) {


 886   case vmIntrinsics::_sha2_implCompress:
 887   case vmIntrinsics::_sha5_implCompress:
 888     return inline_sha_implCompress(intrinsic_id());
 889 
 890   case vmIntrinsics::_digestBase_implCompressMB:
 891     return inline_digestBase_implCompressMB(predicate);
 892 
 893   case vmIntrinsics::_multiplyToLen:
 894     return inline_multiplyToLen();
 895 
 896   case vmIntrinsics::_encodeISOArray:
 897     return inline_encodeISOArray();
 898 
 899   case vmIntrinsics::_updateCRC32:
 900     return inline_updateCRC32();
 901   case vmIntrinsics::_updateBytesCRC32:
 902     return inline_updateBytesCRC32();
 903   case vmIntrinsics::_updateByteBufferCRC32:
 904     return inline_updateByteBufferCRC32();
 905 
 906   case vmIntrinsics::_profileBranch:
 907     return inline_profileBranch();
 908 
 909   default:
 910     // If you get here, it may be that someone has added a new intrinsic
 911     // to the list in vmSymbols.hpp without implementing it here.
 912 #ifndef PRODUCT
 913     if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
 914       tty->print_cr("*** Warning: Unimplemented intrinsic %s(%d)",
 915                     vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
 916     }
 917 #endif
 918     return false;
 919   }
 920 }
 921 
 922 Node* LibraryCallKit::try_to_predicate(int predicate) {
 923   if (!jvms()->has_method()) {
 924     // Root JVMState has a null method.
 925     assert(map()->memory()->Opcode() == Op_Parm, "");
 926     // Insert the memory aliasing node
 927     set_all_memory(reset_memory());
 928   }


5862 
5863   ciKlass* klass_SHA = NULL;
5864   if (klass_SHA_name != NULL) {
5865     klass_SHA = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make(klass_SHA_name));
5866   }
5867   if ((klass_SHA == NULL) || !klass_SHA->is_loaded()) {
5868     // if none of SHA/SHA2/SHA5 is loaded, we never take the intrinsic fast path
5869     Node* ctrl = control();
5870     set_control(top()); // no intrinsic path
5871     return ctrl;
5872   }
5873   ciInstanceKlass* instklass_SHA = klass_SHA->as_instance_klass();
5874 
5875   Node* instofSHA = gen_instanceof(digestBaseObj, makecon(TypeKlassPtr::make(instklass_SHA)));
5876   Node* cmp_instof = _gvn.transform(new CmpINode(instofSHA, intcon(1)));
5877   Node* bool_instof = _gvn.transform(new BoolNode(cmp_instof, BoolTest::ne));
5878   Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
5879 
5880   return instof_false;  // even if it is NULL
5881 }
5882 
5883 bool LibraryCallKit::inline_profileBranch() {
5884   Node* counts = argument(1);
5885   const TypeAryPtr* ary = NULL;
5886   ciArray* aobj = NULL;
5887   if (counts->is_Con()
5888       && (ary = counts->bottom_type()->isa_aryptr()) != NULL
5889       && (aobj = ary->const_oop()->as_array()) != NULL
5890       && (aobj->length() == 2)) {
5891     jint     taken = aobj->element_value(1).as_int();
5892     jint not_taken = aobj->element_value(0).as_int();
5893 
5894     if (C->log() != NULL) {
5895       C->log()->elem("observe source='profileBranch' taken='%d' not_taken='%d'",
5896                      taken, not_taken);
5897     }
5898 
5899     if (taken + not_taken == 0) {
5900       // According to profile, never executed.
5901       uncommon_trap_exact(Deoptimization::Reason_intrinsic,
5902                           Deoptimization::Action_reinterpret);
5903       return true;
5904     }
5905     // Stop profiling.
5906     // MethodHandleImpl::profileBranch() has profiling logic in it's bytecode.
5907     // By replacing method's body with profile data (represented as ProfileBranchNode
5908     // on IR level) we effectively disable profiling.
5909     // It enables full speed execution once optimized code is generated.
5910     Node* profile = _gvn.transform(new ProfileBranchNode(argument(0), taken, not_taken));
5911     C->record_for_igvn(profile);
5912     set_result(profile);
5913     return true;
5914   } else {
5915     // Continue profiling.
5916     // Profile data isn't available at the moment. So, execute method's bytecode version.
5917     // Usually, when GWT LambdaForms are profiled it means that a stand-alone nmethod
5918     // is compiled and counters aren't available since corresponding MethodHandle
5919     // isn't a compile-time constant.
5920     return false;
5921   }
5922 }
src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File