< prev index next >

src/hotspot/share/opto/callGenerator.cpp

Print this page
rev 52371 : [mq]: lvb.patch


  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/bcEscapeAnalyzer.hpp"
  27 #include "ci/ciCallSite.hpp"
  28 #include "ci/ciObjArray.hpp"
  29 #include "ci/ciMemberName.hpp"
  30 #include "ci/ciMethodHandle.hpp"
  31 #include "classfile/javaClasses.hpp"
  32 #include "compiler/compileLog.hpp"
  33 #include "opto/addnode.hpp"
  34 #include "opto/callGenerator.hpp"
  35 #include "opto/callnode.hpp"
  36 #include "opto/castnode.hpp"
  37 #include "opto/cfgnode.hpp"
  38 #include "opto/parse.hpp"
  39 #include "opto/rootnode.hpp"
  40 #include "opto/runtime.hpp"
  41 #include "opto/subnode.hpp"
  42 #include "runtime/sharedRuntime.hpp"



  43 
  44 // Utility function.
  45 const TypeFunc* CallGenerator::tf() const {
  46   return TypeFunc::make(method());
  47 }
  48 
  49 bool CallGenerator::is_inlined_method_handle_intrinsic(JVMState* jvms, ciMethod* callee) {
  50   ciMethod* symbolic_info = jvms->method()->get_method_at_bci(jvms->bci());
  51   return symbolic_info->is_method_handle_intrinsic() && !callee->is_method_handle_intrinsic();
  52 }
  53 
  54 //-----------------------------ParseGenerator---------------------------------
  55 // Internal class which handles all direct bytecode traversal.
  56 class ParseGenerator : public InlineCallGenerator {
  57 private:
  58   bool  _is_osr;
  59   float _expected_uses;
  60 
  61 public:
  62   ParseGenerator(ciMethod* method, float expected_uses, bool is_osr = false)


 817   if (IncrementalInline && call_site_count > 0 &&
 818       (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) {
 819     return CallGenerator::for_mh_late_inline(caller, callee, input_not_const);
 820   } else {
 821     // Out-of-line call.
 822     return CallGenerator::for_direct_call(callee);
 823   }
 824 }
 825 
 826 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
 827   GraphKit kit(jvms);
 828   PhaseGVN& gvn = kit.gvn();
 829   Compile* C = kit.C;
 830   vmIntrinsics::ID iid = callee->intrinsic_id();
 831   input_not_const = true;
 832   switch (iid) {
 833   case vmIntrinsics::_invokeBasic:
 834     {
 835       // Get MethodHandle receiver:
 836       Node* receiver = kit.argument(0);



 837       if (receiver->Opcode() == Op_ConP) {
 838         input_not_const = false;
 839         const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
 840         ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
 841         const int vtable_index = Method::invalid_vtable_index;
 842 
 843         if (!ciMethod::is_consistent_info(callee, target)) {
 844           print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 845                                  "signatures mismatch");
 846           return NULL;
 847         }
 848 
 849         CallGenerator* cg = C->call_generator(target, vtable_index,
 850                                               false /* call_does_dispatch */,
 851                                               jvms,
 852                                               true /* allow_inline */,
 853                                               PROB_ALWAYS);
 854         return cg;
 855       } else {
 856         print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 857                                "receiver not constant");
 858       }
 859     }
 860     break;
 861 
 862   case vmIntrinsics::_linkToVirtual:
 863   case vmIntrinsics::_linkToStatic:

 864   case vmIntrinsics::_linkToSpecial:
 865   case vmIntrinsics::_linkToInterface:
 866     {
 867       // Get MemberName argument:
 868       Node* member_name = kit.argument(callee->arg_size() - 1);



 869       if (member_name->Opcode() == Op_ConP) {
 870         input_not_const = false;
 871         const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
 872         ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
 873 
 874         if (!ciMethod::is_consistent_info(callee, target)) {
 875           print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 876                                  "signatures mismatch");
 877           return NULL;
 878         }
 879 
 880         // In lambda forms we erase signature types to avoid resolving issues
 881         // involving class loaders.  When we optimize a method handle invoke
 882         // to a direct call we must cast the receiver and arguments to its
 883         // actual types.
 884         ciSignature* signature = target->signature();
 885         const int receiver_skip = target->is_static() ? 0 : 1;
 886         // Cast receiver to its type.
 887         if (!target->is_static()) {
 888           Node* arg = kit.argument(0);




  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/bcEscapeAnalyzer.hpp"
  27 #include "ci/ciCallSite.hpp"
  28 #include "ci/ciObjArray.hpp"
  29 #include "ci/ciMemberName.hpp"
  30 #include "ci/ciMethodHandle.hpp"
  31 #include "classfile/javaClasses.hpp"
  32 #include "compiler/compileLog.hpp"
  33 #include "opto/addnode.hpp"
  34 #include "opto/callGenerator.hpp"
  35 #include "opto/callnode.hpp"
  36 #include "opto/castnode.hpp"
  37 #include "opto/cfgnode.hpp"
  38 #include "opto/parse.hpp"
  39 #include "opto/rootnode.hpp"
  40 #include "opto/runtime.hpp"
  41 #include "opto/subnode.hpp"
  42 #include "runtime/sharedRuntime.hpp"
  43 #if INCLUDE_SHENANDOAHGC
  44 #include "gc/shenandoah/c2/shenandoahSupport.hpp"
  45 #endif
  46 
  47 // Utility function.
  48 const TypeFunc* CallGenerator::tf() const {
  49   return TypeFunc::make(method());
  50 }
  51 
  52 bool CallGenerator::is_inlined_method_handle_intrinsic(JVMState* jvms, ciMethod* callee) {
  53   ciMethod* symbolic_info = jvms->method()->get_method_at_bci(jvms->bci());
  54   return symbolic_info->is_method_handle_intrinsic() && !callee->is_method_handle_intrinsic();
  55 }
  56 
  57 //-----------------------------ParseGenerator---------------------------------
  58 // Internal class which handles all direct bytecode traversal.
  59 class ParseGenerator : public InlineCallGenerator {
  60 private:
  61   bool  _is_osr;
  62   float _expected_uses;
  63 
  64 public:
  65   ParseGenerator(ciMethod* method, float expected_uses, bool is_osr = false)


 820   if (IncrementalInline && call_site_count > 0 &&
 821       (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) {
 822     return CallGenerator::for_mh_late_inline(caller, callee, input_not_const);
 823   } else {
 824     // Out-of-line call.
 825     return CallGenerator::for_direct_call(callee);
 826   }
 827 }
 828 
 829 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
 830   GraphKit kit(jvms);
 831   PhaseGVN& gvn = kit.gvn();
 832   Compile* C = kit.C;
 833   vmIntrinsics::ID iid = callee->intrinsic_id();
 834   input_not_const = true;
 835   switch (iid) {
 836   case vmIntrinsics::_invokeBasic:
 837     {
 838       // Get MethodHandle receiver:
 839       Node* receiver = kit.argument(0);
 840  #if INCLUDE_SHENANDOAHGC
 841       receiver = ShenandoahBarrierNode::skip_through_barrier(receiver);
 842  #endif
 843       if (receiver->Opcode() == Op_ConP) {
 844         input_not_const = false;
 845         const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
 846         ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
 847         const int vtable_index = Method::invalid_vtable_index;
 848 
 849         if (!ciMethod::is_consistent_info(callee, target)) {
 850           print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 851                                  "signatures mismatch");
 852           return NULL;
 853         }
 854 
 855         CallGenerator* cg = C->call_generator(target, vtable_index,
 856                                               false /* call_does_dispatch */,
 857                                               jvms,
 858                                               true /* allow_inline */,
 859                                               PROB_ALWAYS);
 860         return cg;
 861       } else {
 862         print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 863                                "receiver not constant");
 864       }
 865     }
 866     break;
 867 
 868   case vmIntrinsics::_linkToVirtual:
 869   case vmIntrinsics::_linkToStatic:
 870 
 871   case vmIntrinsics::_linkToSpecial:
 872   case vmIntrinsics::_linkToInterface:
 873     {
 874       // Get MemberName argument:
 875       Node* member_name = kit.argument(callee->arg_size() - 1);
 876  #if INCLUDE_SHENANDOAHGC
 877       member_name = ShenandoahBarrierNode::skip_through_barrier(member_name);
 878  #endif
 879       if (member_name->Opcode() == Op_ConP) {
 880         input_not_const = false;
 881         const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
 882         ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
 883 
 884         if (!ciMethod::is_consistent_info(callee, target)) {
 885           print_inlining_failure(C, callee, jvms->depth() - 1, jvms->bci(),
 886                                  "signatures mismatch");
 887           return NULL;
 888         }
 889 
 890         // In lambda forms we erase signature types to avoid resolving issues
 891         // involving class loaders.  When we optimize a method handle invoke
 892         // to a direct call we must cast the receiver and arguments to its
 893         // actual types.
 894         ciSignature* signature = target->signature();
 895         const int receiver_skip = target->is_static() ? 0 : 1;
 896         // Cast receiver to its type.
 897         if (!target->is_static()) {
 898           Node* arg = kit.argument(0);


< prev index next >