hotspot/src/share/vm/opto/callGenerator.cpp
changeset 4566 b363f6ef4068
parent 4450 6d700b859b3e
child 4567 7fc02fbe5c7a
equal deleted inserted replaced
4565:cbb3fed38514 4566:b363f6ef4068
     1 /*
     1 /*
     2  * Copyright 2000-2008 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2000-2009 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   134       // And dump it back to the caller, decorated with any exceptions:
   134       // And dump it back to the caller, decorated with any exceptions:
   135       return kit.transfer_exceptions_into_jvms();
   135       return kit.transfer_exceptions_into_jvms();
   136     }
   136     }
   137     // Mark the call node as virtual, sort of:
   137     // Mark the call node as virtual, sort of:
   138     call->set_optimized_virtual(true);
   138     call->set_optimized_virtual(true);
       
   139     if (method()->is_method_handle_invoke())
       
   140       call->set_method_handle_invoke(true);
   139   }
   141   }
   140   kit.set_arguments_for_java_call(call);
   142   kit.set_arguments_for_java_call(call);
   141   kit.set_edges_for_java_call(call, false, _separate_io_proj);
   143   kit.set_edges_for_java_call(call, false, _separate_io_proj);
   142   Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
   144   Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
   143   kit.push_node(method()->return_type()->basic_type(), ret);
   145   kit.push_node(method()->return_type()->basic_type(), ret);
   144   _call_node = call;  // Save the call node in case we need it later
   146   _call_node = call;  // Save the call node in case we need it later
   145   return kit.transfer_exceptions_into_jvms();
   147   return kit.transfer_exceptions_into_jvms();
   146 }
   148 }
   147 
   149 
       
   150 //---------------------------DynamicCallGenerator-----------------------------
       
   151 // Internal class which handles all out-of-line dynamic calls.
       
   152 class DynamicCallGenerator : public CallGenerator {
       
   153 public:
       
   154   DynamicCallGenerator(ciMethod* method)
       
   155     : CallGenerator(method)
       
   156   {
       
   157   }
       
   158   virtual JVMState* generate(JVMState* jvms);
       
   159 };
       
   160 
       
   161 JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
       
   162   GraphKit kit(jvms);
       
   163 
       
   164   if (kit.C->log() != NULL) {
       
   165     kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci());
       
   166   }
       
   167 
       
   168   // Get the constant pool cache from the caller class.
       
   169   ciMethod* caller_method = jvms->method();
       
   170   ciBytecodeStream str(caller_method);
       
   171   str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
       
   172   assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
       
   173   ciCPCache* cpcache = str.get_cpcache();
       
   174 
       
   175   // Get the offset of the CallSite from the constant pool cache
       
   176   // pointer.
       
   177   int index = str.get_method_index();
       
   178   size_t call_site_offset = cpcache->get_f1_offset(index);
       
   179 
       
   180   // Load the CallSite object from the constant pool cache.
       
   181   const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
       
   182   Node* cpc = kit.makecon(cpcache_ptr);
       
   183   Node* adr = kit.basic_plus_adr(cpc, cpc, call_site_offset);
       
   184   Node* call_site = kit.make_load(kit.control(), adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
       
   185 
       
   186   // Load the MethodHandle (target) from the CallSite object.
       
   187   Node* mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
       
   188   Node* mh = kit.make_load(kit.control(), mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
       
   189 
       
   190   address stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
       
   191 
       
   192   CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), stub, method(), kit.bci());
       
   193   // invokedynamic is treated as an optimized invokevirtual.
       
   194   call->set_optimized_virtual(true);
       
   195   // Take extra care (in the presence of argument motion) not to trash the SP:
       
   196   call->set_method_handle_invoke(true);
       
   197 
       
   198   // Pass the MethodHandle as first argument and shift the other
       
   199   // arguments.
       
   200   call->init_req(0 + TypeFunc::Parms, mh);
       
   201   uint nargs = call->method()->arg_size();
       
   202   for (uint i = 1; i < nargs; i++) {
       
   203     Node* arg = kit.argument(i - 1);
       
   204     call->init_req(i + TypeFunc::Parms, arg);
       
   205   }
       
   206 
       
   207   kit.set_edges_for_java_call(call);
       
   208   Node* ret = kit.set_results_for_java_call(call);
       
   209   kit.push_node(method()->return_type()->basic_type(), ret);
       
   210   return kit.transfer_exceptions_into_jvms();
       
   211 }
       
   212 
       
   213 //--------------------------VirtualCallGenerator------------------------------
       
   214 // Internal class which handles all out-of-line calls checking receiver type.
   148 class VirtualCallGenerator : public CallGenerator {
   215 class VirtualCallGenerator : public CallGenerator {
   149 private:
   216 private:
   150   int _vtable_index;
   217   int _vtable_index;
   151 public:
   218 public:
   152   VirtualCallGenerator(ciMethod* method, int vtable_index)
   219   VirtualCallGenerator(ciMethod* method, int vtable_index)
   157   }
   224   }
   158   virtual bool      is_virtual() const          { return true; }
   225   virtual bool      is_virtual() const          { return true; }
   159   virtual JVMState* generate(JVMState* jvms);
   226   virtual JVMState* generate(JVMState* jvms);
   160 };
   227 };
   161 
   228 
   162 //--------------------------VirtualCallGenerator------------------------------
       
   163 // Internal class which handles all out-of-line calls checking receiver type.
       
   164 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
   229 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
   165   GraphKit kit(jvms);
   230   GraphKit kit(jvms);
   166   Node* receiver = kit.argument(0);
   231   Node* receiver = kit.argument(0);
   167 
   232 
   168   if (kit.C->log() != NULL) {
   233   if (kit.C->log() != NULL) {
   251 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
   316 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
   252   assert(!m->is_abstract(), "for_direct_call mismatch");
   317   assert(!m->is_abstract(), "for_direct_call mismatch");
   253   return new DirectCallGenerator(m, separate_io_proj);
   318   return new DirectCallGenerator(m, separate_io_proj);
   254 }
   319 }
   255 
   320 
       
   321 CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
       
   322   assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
       
   323   return new DynamicCallGenerator(m);
       
   324 }
       
   325 
   256 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
   326 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
   257   assert(!m->is_static(), "for_virtual_call mismatch");
   327   assert(!m->is_static(), "for_virtual_call mismatch");
       
   328   assert(!m->is_method_handle_invoke(), "should be a direct call");
   258   return new VirtualCallGenerator(m, vtable_index);
   329   return new VirtualCallGenerator(m, vtable_index);
   259 }
   330 }
   260 
   331 
   261 // Allow inlining decisions to be delayed
   332 // Allow inlining decisions to be delayed
   262 class LateInlineCallGenerator : public DirectCallGenerator {
   333 class LateInlineCallGenerator : public DirectCallGenerator {