# HG changeset patch # User roland # Date 1380790507 -7200 # Node ID d9043b88eeb30237a70abd129cf7d0cb59f6ad4e # Parent c775af091fe9f08493831e5cdab708879f1ce561 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 diff -r c775af091fe9 -r d9043b88eeb3 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Mon Oct 07 10:41:56 2013 -0700 +++ b/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? diff -r c775af091fe9 -r d9043b88eeb3 src/share/vm/opto/graphKit.hpp --- a/src/share/vm/opto/graphKit.hpp Mon Oct 07 10:41:56 2013 -0700 +++ b/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);