8024067: Missing replace_in_map() calls following null checks
authorroland
Thu, 03 Oct 2013 10:55:07 +0200
changeset 20696 946797ddfade
parent 20695 4f5a5e95090b
child 20697 2a5211252a04
8024067: Missing replace_in_map() calls following null checks Summary: add replace_in_map() calls following some null checks in type checks Reviewed-by: kvn
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/graphKit.hpp
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Mon Oct 07 10:41:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Thu Oct 03 10:55:07 2013 +0200
@@ -2122,7 +2122,7 @@
 // Null check oop.  Set null-path control into Region in slot 3.
 // Make a cast-not-nullness use the other not-null control.  Return cast.
 Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
-                               bool never_see_null) {
+                               bool never_see_null, bool safe_for_replace) {
   // Initial NULL check taken path
   (*null_control) = top();
   Node* cast = null_check_common(value, T_OBJECT, false, null_control);
@@ -2140,6 +2140,9 @@
                   Deoptimization::Action_make_not_entrant);
     (*null_control) = top();    // NULL path is dead
   }
+  if ((*null_control) == top() && safe_for_replace) {
+    replace_in_map(value, cast);
+  }
 
   // Cast away null-ness on the result
   return cast;
@@ -2634,15 +2637,17 @@
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
   ciProfileData* data = NULL;
+  bool safe_for_replace = false;
   if (java_bc() == Bytecodes::_instanceof) {  // Only for the bytecode
     data = method()->method_data()->bci_to_data(bci());
+    safe_for_replace = true;
   }
   bool never_see_null = (ProfileDynamicTypes  // aggressive use of profile
                          && seems_never_null(obj, data));
 
   // Null check; get casted pointer; set region slot 3
   Node* null_ctl = top();
-  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
+  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
 
   // If not_null_obj is dead, only null-path is taken
   if (stopped()) {              // Doing instance-of on a NULL?
@@ -2723,11 +2728,13 @@
   }
 
   ciProfileData* data = NULL;
+  bool safe_for_replace = false;
   if (failure_control == NULL) {        // use MDO in regular case only
     assert(java_bc() == Bytecodes::_aastore ||
            java_bc() == Bytecodes::_checkcast,
            "interpreter profiles type checks only for these BCs");
     data = method()->method_data()->bci_to_data(bci());
+    safe_for_replace = true;
   }
 
   // Make the merge point
@@ -2742,7 +2749,7 @@
 
   // Null check; get casted pointer; set region slot 3
   Node* null_ctl = top();
-  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null);
+  Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
 
   // If not_null_obj is dead, only null-path is taken
   if (stopped()) {              // Doing instance-of on a NULL?
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Mon Oct 07 10:41:56 2013 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Thu Oct 03 10:55:07 2013 +0200
@@ -378,8 +378,10 @@
   // Return a cast-not-null node which depends on the not-null control.
   // If never_see_null, use an uncommon trap (*null_control sees a top).
   // The cast is not valid along the null path; keep a copy of the original.
+  // If safe_for_replace, then we can replace the value with the cast
+  // in the parsing map (the cast is guaranteed to dominate the map)
   Node* null_check_oop(Node* value, Node* *null_control,
-                       bool never_see_null = false);
+                       bool never_see_null = false, bool safe_for_replace = false);
 
   // Check the null_seen bit.
   bool seems_never_null(Node* obj, ciProfileData* data);