8167656: Unstable MethodHandle inlining causing huge performance variations
authorneliasso
Thu, 10 Nov 2016 18:08:31 +0100
changeset 42553 2aeb79d952f3
parent 42552 584f6c668be7
child 42554 6c5c1f1e7842
8167656: Unstable MethodHandle inlining causing huge performance variations Summary: Profile calls without a reciever Reviewed-by: jrose, vlivanov, kvn
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Nov 09 10:21:56 2016 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Nov 10 18:08:31 2016 +0100
@@ -2056,17 +2056,26 @@
   }
 #endif
 
-  // invokespecial always needs a NULL check. invokevirtual where the target is
-  // final or where it's not known whether the target is final requires a NULL check.
-  // Otherwise normal invokevirtual will perform the null check during the lookup
-  // logic or the unverified entry point.  Profiling of calls requires that
-  // the null check is performed in all cases.
-
-  bool do_null_check = (recv != NULL) &&
-        (code == Bytecodes::_invokespecial || (target->is_loaded() && (target->is_final() || (is_profiling() && profile_calls()))));
-
-  if (do_null_check) {
-    null_check(recv);
+  // A null check is required here (when there is a receiver) for any of the following cases
+  // - invokespecial, always need a null check.
+  // - invokevirtual, when the target is final and loaded. Calls to final targets will become optimized
+  //   and require null checking. If the target is loaded a null check is emitted here.
+  //   If the target isn't loaded the null check must happen after the call resolution. We achieve that
+  //   by using the target methods unverified entry point (see CompiledIC::compute_monomorphic_entry).
+  //   (The JVM specification requires that LinkageError must be thrown before a NPE. An unloaded target may
+  //   potentially fail, and can't have the null check before the resolution.)
+  // - A call that will be profiled. (But we can't add a null check when the target is unloaded, by the same
+  //   reason as above, so calls with a receiver to unloaded targets can't be profiled.)
+  //
+  // Normal invokevirtual will perform the null check during lookup
+
+  bool need_null_check = (code == Bytecodes::_invokespecial) ||
+      (target->is_loaded() && (target->is_final_method() || (is_profiling() && profile_calls())));
+
+  if (need_null_check) {
+    if (recv != NULL) {
+      null_check(recv);
+    }
 
     if (is_profiling()) {
       // Note that we'd collect profile data in this method if we wanted it.