hotspot/src/share/vm/opto/doCall.cpp
changeset 20296 bc70e1c29125
parent 20073 bfc95277d42b
child 21089 e1986ff6fe2e
--- a/hotspot/src/share/vm/opto/doCall.cpp	Sat Sep 28 12:42:22 2013 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Fri Sep 27 11:52:24 2013 +0400
@@ -110,6 +110,7 @@
   // then we return it as the inlined version of the call.
   // We do this before the strict f.p. check below because the
   // intrinsics handle strict f.p. correctly.
+  CallGenerator* cg_intrinsic = NULL;
   if (allow_inline && allow_intrinsics) {
     CallGenerator* cg = find_intrinsic(callee, call_does_dispatch);
     if (cg != NULL) {
@@ -121,7 +122,16 @@
           cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
         }
       }
-      return cg;
+
+      // If intrinsic does the virtual dispatch, we try to use the type profile
+      // first, and hopefully inline it as the regular virtual call below.
+      // We will retry the intrinsic if nothing had claimed it afterwards.
+      if (cg->does_virtual_dispatch()) {
+        cg_intrinsic = cg;
+        cg = NULL;
+      } else {
+        return cg;
+      }
     }
   }
 
@@ -266,6 +276,13 @@
     }
   }
 
+  // Nothing claimed the intrinsic, we go with straight-forward inlining
+  // for already discovered intrinsic.
+  if (allow_inline && allow_intrinsics && cg_intrinsic != NULL) {
+    assert(cg_intrinsic->does_virtual_dispatch(), "sanity");
+    return cg_intrinsic;
+  }
+
   // There was no special inlining tactic, or it bailed out.
   // Use a more generic tactic, like a simple call.
   if (call_does_dispatch) {