hotspot/src/share/vm/opto/doCall.cpp
changeset 4566 b363f6ef4068
parent 4564 55dfb20908d0
child 4567 7fc02fbe5c7a
--- a/hotspot/src/share/vm/opto/doCall.cpp	Mon Jan 04 15:21:09 2010 -0800
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Tue Jan 05 13:05:58 2010 +0100
@@ -228,6 +228,12 @@
   // Use a more generic tactic, like a simple call.
   if (call_is_virtual) {
     return CallGenerator::for_virtual_call(call_method, vtable_index);
+  } else if (call_method->is_method_handle_invoke()) {
+    if (jvms->method()->java_code_at_bci(jvms->bci()) == Bytecodes::_invokedynamic)
+      return CallGenerator::for_dynamic_call(call_method);
+    else
+      // %%% if the target MH is a compile-time constant, we should try to inline it
+      return CallGenerator::for_direct_call(call_method);
   } else {
     // Class Hierarchy Analysis or Type Profile reveals a unique target,
     // or it is a static or special call.
@@ -299,7 +305,7 @@
   // Interface classes can be loaded & linked and never get around to
   // being initialized.  Uncommon-trap for not-initialized static or
   // v-calls.  Let interface calls happen.
-  ciInstanceKlass* holder_klass  = dest_method->holder();
+  ciInstanceKlass* holder_klass = dest_method->holder();
   if (!holder_klass->is_initialized() &&
       !holder_klass->is_interface()) {
     uncommon_trap(Deoptimization::Reason_uninitialized,
@@ -307,14 +313,6 @@
                   holder_klass);
     return true;
   }
-  if (dest_method->is_method_handle_invoke()
-      && holder_klass->name() == ciSymbol::java_dyn_InvokeDynamic()) {
-    // FIXME: NYI
-    uncommon_trap(Deoptimization::Reason_unhandled,
-                  Deoptimization::Action_none,
-                  holder_klass);
-    return true;
-  }
 
   assert(dest_method->will_link(method()->holder(), klass, bc()), "dest_method: typeflow responsibility");
   return false;
@@ -333,6 +331,7 @@
   bool is_virtual = bc() == Bytecodes::_invokevirtual;
   bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
   bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
+  bool is_invokedynamic = bc() == Bytecodes::_invokedynamic;
 
   // Find target being called
   bool             will_link;
@@ -341,7 +340,8 @@
   ciKlass* holder = iter().get_declared_method_holder();
   ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
 
-  int   nargs    = dest_method->arg_size();
+  int nargs = dest_method->arg_size();
+  if (is_invokedynamic)  nargs -= 1;
 
   // uncommon-trap when callee is unloaded, uninitialized or will not link
   // bailout when too many arguments for register representation
@@ -355,7 +355,7 @@
     return;
   }
   assert(holder_klass->is_loaded(), "");
-  assert(dest_method->is_static() == !has_receiver, "must match bc");
+  assert((dest_method->is_static() || is_invokedynamic) == !has_receiver , "must match bc");
   // Note: this takes into account invokeinterface of methods declared in java/lang/Object,
   // which should be invokevirtuals but according to the VM spec may be invokeinterfaces
   assert(holder_klass->is_interface() || holder_klass->super() == NULL || (bc() != Bytecodes::_invokeinterface), "must match bc");