changeset 3413:e2fe93124108

7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely Reviewed-by: kvn
author twisti
date Wed, 13 Jun 2012 11:36:03 -0700
parents 5e990493719e
children eba1d5bce9e8
files src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp src/cpu/x86/vm/c1_LIRAssembler_x86.cpp src/cpu/x86/vm/c1_LIRGenerator_x86.cpp src/share/vm/c1/c1_LIRGenerator.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/oops/methodOop.cpp src/share/vm/oops/methodOop.hpp
diffstat 7 files changed, 35 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -965,10 +965,10 @@
   if (!x->klass()->is_loaded() || PatchALot) {
     patching_info = state_for(x, x->state_before());
 
-    // cannot re-use same xhandlers for multiple CodeEmitInfos, so
-    // clone all handlers.  This is handled transparently in other
-    // places by the CodeEmitInfo cloning logic but is handled
-    // specially here because a stub isn't being used.
+    // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+    // clone all handlers (NOTE: Usually this is handled transparently
+    // by the CodeEmitInfo cloning logic in CodeStub constructors but
+    // is done explicitly here because a stub isn't being used).
     x->set_exception_handlers(new XHandlers(x->exception_handlers()));
   }
   CodeEmitInfo* info = state_for(x, x->state());
--- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -2673,7 +2673,7 @@
 #endif // _LP64
         }
       } else {
-        ShouldNotReachHere();
+        fatal(err_msg("unexpected type: %s", basictype_to_str(c->type())));
       }
       // cpu register - address
     } else if (opr2->is_address()) {
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -1087,10 +1087,10 @@
   if (!x->klass()->is_loaded() || PatchALot) {
     patching_info = state_for(x, x->state_before());
 
-    // cannot re-use same xhandlers for multiple CodeEmitInfos, so
-    // clone all handlers.  This is handled transparently in other
-    // places by the CodeEmitInfo cloning logic but is handled
-    // specially here because a stub isn't being used.
+    // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
+    // clone all handlers (NOTE: Usually this is handled transparently
+    // by the CodeEmitInfo cloning logic in CodeStub constructors but
+    // is done explicitly here because a stub isn't being used).
     x->set_exception_handlers(new XHandlers(x->exception_handlers()));
   }
   CodeEmitInfo* info = state_for(x, x->state());
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -2807,31 +2807,29 @@
       int index = bcs.get_method_index();
       size_t call_site_offset = cpcache->get_f1_offset(index);
 
+      // Load CallSite object from constant pool cache.
+      LIR_Opr call_site = new_register(objectType);
+      __ oop2reg(cpcache->constant_encoding(), call_site);
+      __ move_wide(new LIR_Address(call_site, call_site_offset, T_OBJECT), call_site);
+
       // If this invokedynamic call site hasn't been executed yet in
       // the interpreter, the CallSite object in the constant pool
       // cache is still null and we need to deoptimize.
       if (cpcache->is_f1_null_at(index)) {
-        // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
-        // clone all handlers.  This is handled transparently in other
-        // places by the CodeEmitInfo cloning logic but is handled
-        // specially here because a stub isn't being used.
-        x->set_exception_handlers(new XHandlers(x->exception_handlers()));
-
+        // Only deoptimize if the CallSite object is still null; we don't
+        // recompile methods in C1 after deoptimization so this call site
+        // might be resolved the next time we execute it after OSR.
         DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
-        __ jump(deopt_stub);
+        __ cmp(lir_cond_equal, call_site, LIR_OprFact::oopConst(NULL));
+        __ branch(lir_cond_equal, T_OBJECT, deopt_stub);
       }
 
       // Use the receiver register for the synthetic MethodHandle
       // argument.
       receiver = LIR_Assembler::receiverOpr();
-      LIR_Opr tmp = new_register(objectType);
-
-      // Load CallSite object from constant pool cache.
-      __ oop2reg(cpcache->constant_encoding(), tmp);
-      __ move_wide(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
 
       // Load target MethodHandle from CallSite object.
-      __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
+      __ load(new LIR_Address(call_site, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
 
       __ call_dynamic(target, receiver, result_register,
                       SharedRuntime::get_resolve_opt_virtual_call_stub(),
@@ -2839,7 +2837,7 @@
       break;
     }
     default:
-      ShouldNotReachHere();
+      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(x->code())));
       break;
   }
 
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -844,6 +844,14 @@
     int bci = method->bci_from(fr.interpreter_frame_bcp());
     nm = method->lookup_osr_nmethod_for(bci, CompLevel_none, false);
   }
+#ifndef PRODUCT
+  if (TraceOnStackReplacement) {
+    if (nm != NULL) {
+      tty->print("OSR entry @ pc: " INTPTR_FORMAT ": ", nm->osr_entry());
+      nm->print();
+    }
+  }
+#endif
   return nm;
 }
 
--- a/src/share/vm/oops/methodOop.cpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/share/vm/oops/methodOop.cpp	Wed Jun 13 11:36:03 2012 -0700
@@ -70,11 +70,11 @@
   return _adapter->get_c2i_unverified_entry();
 }
 
-char* methodOopDesc::name_and_sig_as_C_string() {
+char* methodOopDesc::name_and_sig_as_C_string() const {
   return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature());
 }
 
-char* methodOopDesc::name_and_sig_as_C_string(char* buf, int size) {
+char* methodOopDesc::name_and_sig_as_C_string(char* buf, int size) const {
   return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature(), buf, size);
 }
 
@@ -177,7 +177,8 @@
 
 
 int methodOopDesc::bci_from(address bcp) const {
-  assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(), "bcp doesn't belong to this method");
+  assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(),
+         err_msg("bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", bcp, name_and_sig_as_C_string()));
   return bcp - code_base();
 }
 
--- a/src/share/vm/oops/methodOop.hpp	Tue Jun 12 16:23:31 2012 -0700
+++ b/src/share/vm/oops/methodOop.hpp	Wed Jun 13 11:36:03 2012 -0700
@@ -198,8 +198,8 @@
   // C string, for the purpose of providing more useful NoSuchMethodErrors
   // and fatal error handling. The string is allocated in resource
   // area if a buffer is not provided by the caller.
-  char* name_and_sig_as_C_string();
-  char* name_and_sig_as_C_string(char* buf, int size);
+  char* name_and_sig_as_C_string() const;
+  char* name_and_sig_as_C_string(char* buf, int size) const;
 
   // Static routine in the situations we don't have a methodOop
   static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature);