diff src/share/vm/ci/bcEscapeAnalyzer.cpp @ 6634:7f813940ac35

7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites Reviewed-by: kvn
author twisti
date Tue, 28 Aug 2012 15:24:39 -0700
parents 1d7922586cf6
children da91efe96a93
line wrap: on
line diff
--- a/src/share/vm/ci/bcEscapeAnalyzer.cpp	Mon Aug 27 15:17:17 2012 -0700
+++ b/src/share/vm/ci/bcEscapeAnalyzer.cpp	Tue Aug 28 15:24:39 2012 -0700
@@ -236,12 +236,16 @@
   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   ciInstanceKlass* actual_recv = callee_holder;
 
-  // some methods are obviously bindable without any type checks so
-  // convert them directly to an invokespecial.
+  // Some methods are obviously bindable without any type checks so
+  // convert them directly to an invokespecial or invokestatic.
   if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
     switch (code) {
-    case Bytecodes::_invokevirtual:  code = Bytecodes::_invokespecial;  break;
-    case Bytecodes::_invokehandle:   code = Bytecodes::_invokestatic;   break;
+    case Bytecodes::_invokevirtual:
+      code = Bytecodes::_invokespecial;
+      break;
+    case Bytecodes::_invokehandle:
+      code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
+      break;
     }
   }
 
@@ -826,8 +830,8 @@
         break;
       case Bytecodes::_getstatic:
       case Bytecodes::_getfield:
-        { bool will_link;
-          ciField* field = s.get_field(will_link);
+        { bool ignored_will_link;
+          ciField* field = s.get_field(ignored_will_link);
           BasicType field_type = field->type()->basic_type();
           if (s.cur_bc() != Bytecodes::_getstatic) {
             set_method_escape(state.apop());
@@ -865,16 +869,21 @@
       case Bytecodes::_invokestatic:
       case Bytecodes::_invokedynamic:
       case Bytecodes::_invokeinterface:
-        { bool will_link;
-          ciMethod* target = s.get_method(will_link);
-          ciKlass* holder = s.get_declared_method_holder();
+        { bool ignored_will_link;
+          ciSignature* declared_signature = NULL;
+          ciMethod* target = s.get_method(ignored_will_link, &declared_signature);
+          ciKlass*  holder = s.get_declared_method_holder();
+          assert(declared_signature != NULL, "cannot be null");
           // Push appendix argument, if one.
           if (s.has_appendix()) {
             state.apush(unknown_obj);
           }
           // Pass in raw bytecode because we need to see invokehandle instructions.
           invoke(state, s.cur_bc_raw(), target, holder);
-          ciType* return_type = target->return_type();
+          // We are using the return type of the declared signature here because
+          // it might be a more concrete type than the one from the target (for
+          // e.g. invokedynamic and invokehandle).
+          ciType* return_type = declared_signature->return_type();
           if (!return_type->is_primitive_type()) {
             state.apush(unknown_obj);
           } else if (return_type->is_one_word()) {