Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/node.cpp @ 163:885ed790ecf0
6695810: null oop passed to encode_heap_oop_not_null
Summary: fix several problems in C2 related to Escape Analysis and Compressed Oops.
Reviewed-by: never, jrose
author | kvn |
---|---|
date | Wed, 21 May 2008 10:45:07 -0700 |
parents | 723be81c1212 |
children | 44a553b2809d |
comparison
equal
deleted
inserted
replaced
162:8aa010f60e0f | 163:885ed790ecf0 |
---|---|
1047 int iterations_without_region_limit = DominatorSearchLimit; | 1047 int iterations_without_region_limit = DominatorSearchLimit; |
1048 | 1048 |
1049 Node* orig_sub = sub; | 1049 Node* orig_sub = sub; |
1050 nlist.clear(); | 1050 nlist.clear(); |
1051 bool this_dominates = false; | 1051 bool this_dominates = false; |
1052 uint region_input = 0; | 1052 bool result = false; // Conservative answer |
1053 | |
1053 while (sub != NULL) { // walk 'sub' up the chain to 'this' | 1054 while (sub != NULL) { // walk 'sub' up the chain to 'this' |
1054 if (sub == this) { | 1055 if (sub == this) { |
1055 if (nlist.size() == 0) { | 1056 if (nlist.size() == 0) { |
1056 // No Region nodes except loops were visited before and the EntryControl | 1057 // No Region nodes except loops were visited before and the EntryControl |
1057 // path was taken for loops: it did not walk in a cycle. | 1058 // path was taken for loops: it did not walk in a cycle. |
1058 return true; | 1059 result = true; |
1059 } else if (!this_dominates) { | 1060 break; |
1061 } else if (this_dominates) { | |
1062 result = false; // already met before: walk in a cycle | |
1063 break; | |
1064 } else { | |
1060 // Region nodes were visited. Continue walk up to Start or Root | 1065 // Region nodes were visited. Continue walk up to Start or Root |
1061 // to make sure that it did not walk in a cycle. | 1066 // to make sure that it did not walk in a cycle. |
1062 this_dominates = true; // first time meet | 1067 this_dominates = true; // first time meet |
1063 iterations_without_region_limit = DominatorSearchLimit; // Reset | 1068 iterations_without_region_limit = DominatorSearchLimit; // Reset |
1064 } else { | 1069 } |
1065 return false; // already met before: walk in a cycle | 1070 } |
1066 } | 1071 if (sub->is_Start() || sub->is_Root()) { |
1067 } | 1072 result = this_dominates; |
1068 if (sub->is_Start() || sub->is_Root()) | 1073 break; |
1069 return this_dominates; | 1074 } |
1070 | |
1071 Node* up = sub->find_exact_control(sub->in(0)); | 1075 Node* up = sub->find_exact_control(sub->in(0)); |
1072 if (up == NULL || up->is_top()) | 1076 if (up == NULL || up->is_top()) { |
1073 return false; // Conservative answer for dead code | 1077 result = false; // Conservative answer for dead code |
1074 | 1078 break; |
1075 if (sub == up && sub->is_Loop()) { | 1079 } |
1080 if (sub == up && (sub->is_Loop() || sub->is_Region() && sub->req() != 3)) { | |
1081 // Take first valid path on the way up to 'this'. | |
1076 up = sub->in(1); // in(LoopNode::EntryControl); | 1082 up = sub->in(1); // in(LoopNode::EntryControl); |
1077 } else if (sub == up && sub->is_Region() && sub->req() == 3) { | 1083 } else if (sub == up && sub->is_Region()) { |
1084 assert(sub->req() == 3, "sanity"); | |
1078 iterations_without_region_limit = DominatorSearchLimit; // Reset | 1085 iterations_without_region_limit = DominatorSearchLimit; // Reset |
1086 | |
1087 // Try both paths for such Regions. | |
1088 // It is not accurate without regions dominating information. | |
1089 // With such information the other path should be checked for | |
1090 // the most dominating Region which was visited before. | |
1091 bool region_was_visited_before = false; | |
1079 uint i = 1; | 1092 uint i = 1; |
1080 uint size = nlist.size(); | 1093 uint size = nlist.size(); |
1081 if (size == 0) { | 1094 if (size == 0) { |
1082 // No Region nodes (except Loops) were visited before. | 1095 // No such Region nodes were visited before. |
1083 // Take first valid path on the way up to 'this'. | 1096 // Take first valid path on the way up to 'this'. |
1084 } else if (nlist.at(size - 1) == sub) { | |
1085 // This Region node was just visited. Take other path. | |
1086 i = region_input + 1; | |
1087 nlist.pop(); | |
1088 } else { | 1097 } else { |
1089 // Was this Region node visited before? | 1098 // Was this Region node visited before? |
1090 for (uint j = 0; j < size; j++) { | 1099 intptr_t ni; |
1091 if (nlist.at(j) == sub) { | 1100 int j = size - 1; |
1092 return false; // The Region node was visited before. Give up. | 1101 for (; j >= 0; j--) { |
1102 ni = (intptr_t)nlist.at(j); | |
1103 if ((Node*)(ni & ~1) == sub) { | |
1104 if ((ni & 1) != 0) { | |
1105 break; // Visited 2 paths. Give up. | |
1106 } else { | |
1107 // The Region node was visited before only once. | |
1108 nlist.remove(j); | |
1109 region_was_visited_before = true; | |
1110 for (; i < sub->req(); i++) { | |
1111 Node* in = sub->in(i); | |
1112 if (in != NULL && !in->is_top() && in != sub) { | |
1113 break; | |
1114 } | |
1115 } | |
1116 i++; // Take other path. | |
1117 break; | |
1118 } | |
1093 } | 1119 } |
1094 } | 1120 } |
1121 if (j >= 0 && (ni & 1) != 0) { | |
1122 result = false; // Visited 2 paths. Give up. | |
1123 break; | |
1124 } | |
1095 // The Region node was not visited before. | 1125 // The Region node was not visited before. |
1096 // Take first valid path on the way up to 'this'. | |
1097 } | 1126 } |
1098 for (; i < sub->req(); i++) { | 1127 for (; i < sub->req(); i++) { |
1099 Node* in = sub->in(i); | 1128 Node* in = sub->in(i); |
1100 if (in != NULL && !in->is_top() && in != sub) { | 1129 if (in != NULL && !in->is_top() && in != sub) { |
1101 break; | 1130 break; |
1102 } | 1131 } |
1103 } | 1132 } |
1104 if (i < sub->req()) { | 1133 if (i < sub->req()) { |
1105 nlist.push(sub); | |
1106 up = sub->in(i); | 1134 up = sub->in(i); |
1107 region_input = i; | 1135 if (region_was_visited_before && sub != up) { |
1136 // Set 0 bit to indicate that both paths were taken. | |
1137 nlist.push((Node*)((intptr_t)sub + 1)); | |
1138 } else { | |
1139 nlist.push(sub); | |
1140 } | |
1108 } | 1141 } |
1109 } | 1142 } |
1110 if (sub == up) | 1143 if (sub == up) { |
1111 return false; // some kind of tight cycle | 1144 result = false; // some kind of tight cycle |
1112 | 1145 break; |
1113 if (--iterations_without_region_limit < 0) | 1146 } |
1114 return false; // dead cycle | 1147 if (--iterations_without_region_limit < 0) { |
1115 | 1148 result = false; // dead cycle |
1149 break; | |
1150 } | |
1116 sub = up; | 1151 sub = up; |
1117 } | 1152 } |
1118 return false; | 1153 return result; |
1119 } | 1154 } |
1120 | 1155 |
1121 //------------------------------remove_dead_region----------------------------- | 1156 //------------------------------remove_dead_region----------------------------- |
1122 // This control node is dead. Follow the subgraph below it making everything | 1157 // This control node is dead. Follow the subgraph below it making everything |
1123 // using it dead as well. This will happen normally via the usual IterGVN | 1158 // using it dead as well. This will happen normally via the usual IterGVN |