提交 c74644c6 编写于 作者: R roland

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
上级 72894796
...@@ -2122,7 +2122,7 @@ Node* GraphKit::dstore_rounding(Node* n) { ...@@ -2122,7 +2122,7 @@ Node* GraphKit::dstore_rounding(Node* n) {
// Null check oop. Set null-path control into Region in slot 3. // 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. // Make a cast-not-nullness use the other not-null control. Return cast.
Node* GraphKit::null_check_oop(Node* value, Node* *null_control, 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 // Initial NULL check taken path
(*null_control) = top(); (*null_control) = top();
Node* cast = null_check_common(value, T_OBJECT, false, null_control); Node* cast = null_check_common(value, T_OBJECT, false, null_control);
...@@ -2140,6 +2140,9 @@ Node* GraphKit::null_check_oop(Node* value, Node* *null_control, ...@@ -2140,6 +2140,9 @@ Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
Deoptimization::Action_make_not_entrant); Deoptimization::Action_make_not_entrant);
(*null_control) = top(); // NULL path is dead (*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 // Cast away null-ness on the result
return cast; return cast;
...@@ -2634,15 +2637,17 @@ Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) { ...@@ -2634,15 +2637,17 @@ Node* GraphKit::gen_instanceof(Node* obj, Node* superklass) {
C->set_has_split_ifs(true); // Has chance for split-if optimization C->set_has_split_ifs(true); // Has chance for split-if optimization
ciProfileData* data = NULL; ciProfileData* data = NULL;
bool safe_for_replace = false;
if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode
data = method()->method_data()->bci_to_data(bci()); data = method()->method_data()->bci_to_data(bci());
safe_for_replace = true;
} }
bool never_see_null = (ProfileDynamicTypes // aggressive use of profile bool never_see_null = (ProfileDynamicTypes // aggressive use of profile
&& seems_never_null(obj, data)); && seems_never_null(obj, data));
// Null check; get casted pointer; set region slot 3 // Null check; get casted pointer; set region slot 3
Node* null_ctl = top(); 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 not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL? if (stopped()) { // Doing instance-of on a NULL?
...@@ -2723,11 +2728,13 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, ...@@ -2723,11 +2728,13 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
} }
ciProfileData* data = NULL; ciProfileData* data = NULL;
bool safe_for_replace = false;
if (failure_control == NULL) { // use MDO in regular case only if (failure_control == NULL) { // use MDO in regular case only
assert(java_bc() == Bytecodes::_aastore || assert(java_bc() == Bytecodes::_aastore ||
java_bc() == Bytecodes::_checkcast, java_bc() == Bytecodes::_checkcast,
"interpreter profiles type checks only for these BCs"); "interpreter profiles type checks only for these BCs");
data = method()->method_data()->bci_to_data(bci()); data = method()->method_data()->bci_to_data(bci());
safe_for_replace = true;
} }
// Make the merge point // Make the merge point
...@@ -2742,7 +2749,7 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, ...@@ -2742,7 +2749,7 @@ Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
// Null check; get casted pointer; set region slot 3 // Null check; get casted pointer; set region slot 3
Node* null_ctl = top(); 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 not_null_obj is dead, only null-path is taken
if (stopped()) { // Doing instance-of on a NULL? if (stopped()) { // Doing instance-of on a NULL?
......
...@@ -378,8 +378,10 @@ class GraphKit : public Phase { ...@@ -378,8 +378,10 @@ class GraphKit : public Phase {
// Return a cast-not-null node which depends on the not-null control. // 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). // 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. // 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, 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. // Check the null_seen bit.
bool seems_never_null(Node* obj, ciProfileData* data); bool seems_never_null(Node* obj, ciProfileData* data);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册