Mercurial > hg > truffle
comparison src/share/vm/opto/compile.cpp @ 127:e0bd2e08e3d0
6663848: assert(i < Max(),"oob") in C2 with -Xcomp
Summary: NeverBranchNodes aren't handled properly
Reviewed-by: kvn, sgoldman, rasbold, jrose
author | never |
---|---|
date | Thu, 24 Apr 2008 11:13:03 -0700 |
parents | ba764ed4b6f2 |
children | 885ed790ecf0 |
comparison
equal
deleted
inserted
replaced
126:72f4a668df19 | 127:e0bd2e08e3d0 |
---|---|
1979 assert( !tp || oop_offset_is_sane(tp), "" ); | 1979 assert( !tp || oop_offset_is_sane(tp), "" ); |
1980 } | 1980 } |
1981 #endif | 1981 #endif |
1982 break; | 1982 break; |
1983 } | 1983 } |
1984 case Op_If: | |
1985 case Op_CountedLoopEnd: | |
1986 fpu._tests.push(n); // Collect CFG split points | |
1987 break; | |
1988 | 1984 |
1989 case Op_AddP: { // Assert sane base pointers | 1985 case Op_AddP: { // Assert sane base pointers |
1990 const Node *addp = n->in(AddPNode::Address); | 1986 const Node *addp = n->in(AddPNode::Address); |
1991 assert( !addp->is_AddP() || | 1987 assert( !addp->is_AddP() || |
1992 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation | 1988 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation |
2081 } | 2077 } |
2082 break; | 2078 break; |
2083 default: | 2079 default: |
2084 assert( !n->is_Call(), "" ); | 2080 assert( !n->is_Call(), "" ); |
2085 assert( !n->is_Mem(), "" ); | 2081 assert( !n->is_Mem(), "" ); |
2086 if( n->is_If() || n->is_PCTable() ) | |
2087 fpu._tests.push(n); // Collect CFG split points | |
2088 break; | 2082 break; |
2089 } | 2083 } |
2084 | |
2085 // Collect CFG split points | |
2086 if (n->is_MultiBranch()) | |
2087 fpu._tests.push(n); | |
2090 } | 2088 } |
2091 | 2089 |
2092 //------------------------------final_graph_reshaping_walk--------------------- | 2090 //------------------------------final_graph_reshaping_walk--------------------- |
2093 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | 2091 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), |
2094 // requires that the walk visits a node's inputs before visiting the node. | 2092 // requires that the walk visits a node's inputs before visiting the node. |
2163 Node_Stack nstack(unique() >> 1); | 2161 Node_Stack nstack(unique() >> 1); |
2164 final_graph_reshaping_walk(nstack, root(), fpu); | 2162 final_graph_reshaping_walk(nstack, root(), fpu); |
2165 | 2163 |
2166 // Check for unreachable (from below) code (i.e., infinite loops). | 2164 // Check for unreachable (from below) code (i.e., infinite loops). |
2167 for( uint i = 0; i < fpu._tests.size(); i++ ) { | 2165 for( uint i = 0; i < fpu._tests.size(); i++ ) { |
2168 Node *n = fpu._tests[i]; | 2166 MultiBranchNode *n = fpu._tests[i]->as_MultiBranch(); |
2169 assert( n->is_PCTable() || n->is_If(), "either PCTables or IfNodes" ); | 2167 // Get number of CFG targets. |
2170 // Get number of CFG targets; 2 for IfNodes or _size for PCTables. | |
2171 // Note that PCTables include exception targets after calls. | 2168 // Note that PCTables include exception targets after calls. |
2172 uint expected_kids = n->is_PCTable() ? n->as_PCTable()->_size : 2; | 2169 uint required_outcnt = n->required_outcnt(); |
2173 if (n->outcnt() != expected_kids) { | 2170 if (n->outcnt() != required_outcnt) { |
2174 // Check for a few special cases. Rethrow Nodes never take the | 2171 // Check for a few special cases. Rethrow Nodes never take the |
2175 // 'fall-thru' path, so expected kids is 1 less. | 2172 // 'fall-thru' path, so expected kids is 1 less. |
2176 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { | 2173 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { |
2177 if (n->in(0)->in(0)->is_Call()) { | 2174 if (n->in(0)->in(0)->is_Call()) { |
2178 CallNode *call = n->in(0)->in(0)->as_Call(); | 2175 CallNode *call = n->in(0)->in(0)->as_Call(); |
2179 if (call->entry_point() == OptoRuntime::rethrow_stub()) { | 2176 if (call->entry_point() == OptoRuntime::rethrow_stub()) { |
2180 expected_kids--; // Rethrow always has 1 less kid | 2177 required_outcnt--; // Rethrow always has 1 less kid |
2181 } else if (call->req() > TypeFunc::Parms && | 2178 } else if (call->req() > TypeFunc::Parms && |
2182 call->is_CallDynamicJava()) { | 2179 call->is_CallDynamicJava()) { |
2183 // Check for null receiver. In such case, the optimizer has | 2180 // Check for null receiver. In such case, the optimizer has |
2184 // detected that the virtual call will always result in a null | 2181 // detected that the virtual call will always result in a null |
2185 // pointer exception. The fall-through projection of this CatchNode | 2182 // pointer exception. The fall-through projection of this CatchNode |
2186 // will not be populated. | 2183 // will not be populated. |
2187 Node *arg0 = call->in(TypeFunc::Parms); | 2184 Node *arg0 = call->in(TypeFunc::Parms); |
2188 if (arg0->is_Type() && | 2185 if (arg0->is_Type() && |
2189 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { | 2186 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { |
2190 expected_kids--; | 2187 required_outcnt--; |
2191 } | 2188 } |
2192 } else if (call->entry_point() == OptoRuntime::new_array_Java() && | 2189 } else if (call->entry_point() == OptoRuntime::new_array_Java() && |
2193 call->req() > TypeFunc::Parms+1 && | 2190 call->req() > TypeFunc::Parms+1 && |
2194 call->is_CallStaticJava()) { | 2191 call->is_CallStaticJava()) { |
2195 // Check for negative array length. In such case, the optimizer has | 2192 // Check for negative array length. In such case, the optimizer has |
2196 // detected that the allocation attempt will always result in an | 2193 // detected that the allocation attempt will always result in an |
2197 // exception. There is no fall-through projection of this CatchNode . | 2194 // exception. There is no fall-through projection of this CatchNode . |
2198 Node *arg1 = call->in(TypeFunc::Parms+1); | 2195 Node *arg1 = call->in(TypeFunc::Parms+1); |
2199 if (arg1->is_Type() && | 2196 if (arg1->is_Type() && |
2200 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { | 2197 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { |
2201 expected_kids--; | 2198 required_outcnt--; |
2202 } | 2199 } |
2203 } | 2200 } |
2204 } | 2201 } |
2205 } | 2202 } |
2206 // Recheck with a better notion of 'expected_kids' | 2203 // Recheck with a better notion of 'required_outcnt' |
2207 if (n->outcnt() != expected_kids) { | 2204 if (n->outcnt() != required_outcnt) { |
2208 record_method_not_compilable("malformed control flow"); | 2205 record_method_not_compilable("malformed control flow"); |
2209 return true; // Not all targets reachable! | 2206 return true; // Not all targets reachable! |
2210 } | 2207 } |
2211 } | 2208 } |
2212 // Check that I actually visited all kids. Unreached kids | 2209 // Check that I actually visited all kids. Unreached kids |