hotspot/src/share/vm/opto/library_call.cpp

Print this page




  29 #include "compiler/compileLog.hpp"
  30 #include "oops/objArrayKlass.hpp"
  31 #include "opto/addnode.hpp"
  32 #include "opto/callGenerator.hpp"
  33 #include "opto/cfgnode.hpp"
  34 #include "opto/idealKit.hpp"
  35 #include "opto/mulnode.hpp"
  36 #include "opto/parse.hpp"
  37 #include "opto/runtime.hpp"
  38 #include "opto/subnode.hpp"
  39 #include "prims/nativeLookup.hpp"
  40 #include "runtime/sharedRuntime.hpp"
  41 #include "trace/traceMacros.hpp"
  42 
  43 class LibraryIntrinsic : public InlineCallGenerator {
  44   // Extend the set of intrinsics known to the runtime:
  45  public:
  46  private:
  47   bool             _is_virtual;
  48   bool             _is_predicted;

  49   vmIntrinsics::ID _intrinsic_id;
  50 
  51  public:
  52   LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id)
  53     : InlineCallGenerator(m),
  54       _is_virtual(is_virtual),
  55       _is_predicted(is_predicted),

  56       _intrinsic_id(id)
  57   {
  58   }
  59   virtual bool is_intrinsic() const { return true; }
  60   virtual bool is_virtual()   const { return _is_virtual; }
  61   virtual bool is_predicted()   const { return _is_predicted; }

  62   virtual JVMState* generate(JVMState* jvms);
  63   virtual Node* generate_predicate(JVMState* jvms);
  64   vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
  65 };
  66 
  67 
  68 // Local helper class for LibraryIntrinsic:
  69 class LibraryCallKit : public GraphKit {
  70  private:
  71   LibraryIntrinsic* _intrinsic;     // the library intrinsic being called
  72   Node*             _result;        // the result node, if any
  73   int               _reexecute_sp;  // the stack pointer when bytecode needs to be reexecuted
  74 
  75   const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
  76 
  77  public:
  78   LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
  79     : GraphKit(jvms),
  80       _intrinsic(intrinsic),
  81       _result(NULL)


 335     case vmIntrinsics::_compareTo:
 336     case vmIntrinsics::_equals:
 337     case vmIntrinsics::_equalsC:
 338     case vmIntrinsics::_getAndAddInt:
 339     case vmIntrinsics::_getAndAddLong:
 340     case vmIntrinsics::_getAndSetInt:
 341     case vmIntrinsics::_getAndSetLong:
 342     case vmIntrinsics::_getAndSetObject:
 343     case vmIntrinsics::_loadFence:
 344     case vmIntrinsics::_storeFence:
 345     case vmIntrinsics::_fullFence:
 346       break;  // InlineNatives does not control String.compareTo
 347     case vmIntrinsics::_Reference_get:
 348       break;  // InlineNatives does not control Reference.get
 349     default:
 350       return NULL;
 351     }
 352   }
 353 
 354   bool is_predicted = false;

 355 
 356   switch (id) {
 357   case vmIntrinsics::_compareTo:
 358     if (!SpecialStringCompareTo)  return NULL;
 359     if (!Matcher::match_rule_supported(Op_StrComp))  return NULL;
 360     break;
 361   case vmIntrinsics::_indexOf:
 362     if (!SpecialStringIndexOf)  return NULL;
 363     break;
 364   case vmIntrinsics::_equals:
 365     if (!SpecialStringEquals)  return NULL;
 366     if (!Matcher::match_rule_supported(Op_StrEquals))  return NULL;
 367     break;
 368   case vmIntrinsics::_equalsC:
 369     if (!SpecialArraysEquals)  return NULL;
 370     if (!Matcher::match_rule_supported(Op_AryEq))  return NULL;
 371     break;
 372   case vmIntrinsics::_arraycopy:
 373     if (!InlineArrayCopy)  return NULL;
 374     break;
 375   case vmIntrinsics::_copyMemory:
 376     if (StubRoutines::unsafe_arraycopy() == NULL)  return NULL;
 377     if (!InlineArrayCopy)  return NULL;
 378     break;
 379   case vmIntrinsics::_hashCode:
 380     if (!InlineObjectHash)  return NULL;

 381     break;
 382   case vmIntrinsics::_clone:
 383   case vmIntrinsics::_copyOf:
 384   case vmIntrinsics::_copyOfRange:
 385     if (!InlineObjectCopy)  return NULL;
 386     // These also use the arraycopy intrinsic mechanism:
 387     if (!InlineArrayCopy)  return NULL;
 388     break;
 389   case vmIntrinsics::_encodeISOArray:
 390     if (!SpecialEncodeISOArray)  return NULL;
 391     if (!Matcher::match_rule_supported(Op_EncodeISOArray))  return NULL;
 392     break;
 393   case vmIntrinsics::_checkIndex:
 394     // We do not intrinsify this.  The optimizer does fine with it.
 395     return NULL;
 396 
 397   case vmIntrinsics::_getCallerClass:
 398     if (!UseNewReflection)  return NULL;
 399     if (!InlineReflectionGetCallerClass)  return NULL;
 400     if (SystemDictionary::reflect_CallerSensitive_klass() == NULL)  return NULL;


 512     if (!InlineClassNatives)  return NULL;
 513   }
 514 
 515   // -XX:-InlineThreadNatives disables natives from the Thread class.
 516   if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
 517     if (!InlineThreadNatives)  return NULL;
 518   }
 519 
 520   // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
 521   if (m->holder()->name() == ciSymbol::java_lang_Math() ||
 522       m->holder()->name() == ciSymbol::java_lang_Float() ||
 523       m->holder()->name() == ciSymbol::java_lang_Double()) {
 524     if (!InlineMathNatives)  return NULL;
 525   }
 526 
 527   // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
 528   if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
 529     if (!InlineUnsafeOps)  return NULL;
 530   }
 531 
 532   return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id);
 533 }
 534 
 535 //----------------------register_library_intrinsics-----------------------
 536 // Initialize this file's data structures, for each Compile instance.
 537 void Compile::register_library_intrinsics() {
 538   // Nothing to do here.
 539 }
 540 
 541 JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
 542   LibraryCallKit kit(jvms, this);
 543   Compile* C = kit.C;
 544   int nodes = C->unique();
 545 #ifndef PRODUCT
 546   if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
 547     char buf[1000];
 548     const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
 549     tty->print_cr("Intrinsic %s", str);
 550   }
 551 #endif
 552   ciMethod* callee = kit.callee();




  29 #include "compiler/compileLog.hpp"
  30 #include "oops/objArrayKlass.hpp"
  31 #include "opto/addnode.hpp"
  32 #include "opto/callGenerator.hpp"
  33 #include "opto/cfgnode.hpp"
  34 #include "opto/idealKit.hpp"
  35 #include "opto/mulnode.hpp"
  36 #include "opto/parse.hpp"
  37 #include "opto/runtime.hpp"
  38 #include "opto/subnode.hpp"
  39 #include "prims/nativeLookup.hpp"
  40 #include "runtime/sharedRuntime.hpp"
  41 #include "trace/traceMacros.hpp"
  42 
  43 class LibraryIntrinsic : public InlineCallGenerator {
  44   // Extend the set of intrinsics known to the runtime:
  45  public:
  46  private:
  47   bool             _is_virtual;
  48   bool             _is_predicted;
  49   bool             _is_low_priority;
  50   vmIntrinsics::ID _intrinsic_id;
  51 
  52  public:
  53   LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, bool is_low_priority, vmIntrinsics::ID id)
  54     : InlineCallGenerator(m),
  55       _is_virtual(is_virtual),
  56       _is_predicted(is_predicted),
  57       _is_low_priority(is_low_priority),
  58       _intrinsic_id(id)
  59   {
  60   }
  61   virtual bool is_intrinsic() const { return true; }
  62   virtual bool is_virtual()   const { return _is_virtual; }
  63   virtual bool is_predicted()   const { return _is_predicted; }
  64   virtual bool is_low_priority()   const { return _is_low_priority; }
  65   virtual JVMState* generate(JVMState* jvms);
  66   virtual Node* generate_predicate(JVMState* jvms);
  67   vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
  68 };
  69 
  70 
  71 // Local helper class for LibraryIntrinsic:
  72 class LibraryCallKit : public GraphKit {
  73  private:
  74   LibraryIntrinsic* _intrinsic;     // the library intrinsic being called
  75   Node*             _result;        // the result node, if any
  76   int               _reexecute_sp;  // the stack pointer when bytecode needs to be reexecuted
  77 
  78   const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
  79 
  80  public:
  81   LibraryCallKit(JVMState* jvms, LibraryIntrinsic* intrinsic)
  82     : GraphKit(jvms),
  83       _intrinsic(intrinsic),
  84       _result(NULL)


 338     case vmIntrinsics::_compareTo:
 339     case vmIntrinsics::_equals:
 340     case vmIntrinsics::_equalsC:
 341     case vmIntrinsics::_getAndAddInt:
 342     case vmIntrinsics::_getAndAddLong:
 343     case vmIntrinsics::_getAndSetInt:
 344     case vmIntrinsics::_getAndSetLong:
 345     case vmIntrinsics::_getAndSetObject:
 346     case vmIntrinsics::_loadFence:
 347     case vmIntrinsics::_storeFence:
 348     case vmIntrinsics::_fullFence:
 349       break;  // InlineNatives does not control String.compareTo
 350     case vmIntrinsics::_Reference_get:
 351       break;  // InlineNatives does not control Reference.get
 352     default:
 353       return NULL;
 354     }
 355   }
 356 
 357   bool is_predicted = false;
 358   bool is_low_priority = false;
 359 
 360   switch (id) {
 361   case vmIntrinsics::_compareTo:
 362     if (!SpecialStringCompareTo)  return NULL;
 363     if (!Matcher::match_rule_supported(Op_StrComp))  return NULL;
 364     break;
 365   case vmIntrinsics::_indexOf:
 366     if (!SpecialStringIndexOf)  return NULL;
 367     break;
 368   case vmIntrinsics::_equals:
 369     if (!SpecialStringEquals)  return NULL;
 370     if (!Matcher::match_rule_supported(Op_StrEquals))  return NULL;
 371     break;
 372   case vmIntrinsics::_equalsC:
 373     if (!SpecialArraysEquals)  return NULL;
 374     if (!Matcher::match_rule_supported(Op_AryEq))  return NULL;
 375     break;
 376   case vmIntrinsics::_arraycopy:
 377     if (!InlineArrayCopy)  return NULL;
 378     break;
 379   case vmIntrinsics::_copyMemory:
 380     if (StubRoutines::unsafe_arraycopy() == NULL)  return NULL;
 381     if (!InlineArrayCopy)  return NULL;
 382     break;
 383   case vmIntrinsics::_hashCode:
 384     if (!InlineObjectHash)  return NULL;
 385     is_low_priority = true;
 386     break;
 387   case vmIntrinsics::_clone:
 388   case vmIntrinsics::_copyOf:
 389   case vmIntrinsics::_copyOfRange:
 390     if (!InlineObjectCopy)  return NULL;
 391     // These also use the arraycopy intrinsic mechanism:
 392     if (!InlineArrayCopy)  return NULL;
 393     break;
 394   case vmIntrinsics::_encodeISOArray:
 395     if (!SpecialEncodeISOArray)  return NULL;
 396     if (!Matcher::match_rule_supported(Op_EncodeISOArray))  return NULL;
 397     break;
 398   case vmIntrinsics::_checkIndex:
 399     // We do not intrinsify this.  The optimizer does fine with it.
 400     return NULL;
 401 
 402   case vmIntrinsics::_getCallerClass:
 403     if (!UseNewReflection)  return NULL;
 404     if (!InlineReflectionGetCallerClass)  return NULL;
 405     if (SystemDictionary::reflect_CallerSensitive_klass() == NULL)  return NULL;


 517     if (!InlineClassNatives)  return NULL;
 518   }
 519 
 520   // -XX:-InlineThreadNatives disables natives from the Thread class.
 521   if (m->holder()->name() == ciSymbol::java_lang_Thread()) {
 522     if (!InlineThreadNatives)  return NULL;
 523   }
 524 
 525   // -XX:-InlineMathNatives disables natives from the Math,Float and Double classes.
 526   if (m->holder()->name() == ciSymbol::java_lang_Math() ||
 527       m->holder()->name() == ciSymbol::java_lang_Float() ||
 528       m->holder()->name() == ciSymbol::java_lang_Double()) {
 529     if (!InlineMathNatives)  return NULL;
 530   }
 531 
 532   // -XX:-InlineUnsafeOps disables natives from the Unsafe class.
 533   if (m->holder()->name() == ciSymbol::sun_misc_Unsafe()) {
 534     if (!InlineUnsafeOps)  return NULL;
 535   }
 536 
 537   return new LibraryIntrinsic(m, is_virtual, is_predicted, is_low_priority, (vmIntrinsics::ID) id);
 538 }
 539 
 540 //----------------------register_library_intrinsics-----------------------
 541 // Initialize this file's data structures, for each Compile instance.
 542 void Compile::register_library_intrinsics() {
 543   // Nothing to do here.
 544 }
 545 
 546 JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
 547   LibraryCallKit kit(jvms, this);
 548   Compile* C = kit.C;
 549   int nodes = C->unique();
 550 #ifndef PRODUCT
 551   if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
 552     char buf[1000];
 553     const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
 554     tty->print_cr("Intrinsic %s", str);
 555   }
 556 #endif
 557   ciMethod* callee = kit.callee();