@ -820,7 +820,9 @@ public class FlowBlock {
/* The special start marker */
/* The special start marker */
continue ;
continue ;
if ( ! pred . successors . containsKey ( this ) )
if ( ! pred . successors . containsKey ( this ) )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError
( "Inconsistency: " + pred . getLabel ( ) + " not in "
+ this . getLabel ( ) + ".successors" ) ;
}
}
StructuredBlock last = lastModified ;
StructuredBlock last = lastModified ;
@ -829,41 +831,51 @@ public class FlowBlock {
| | last . outer instanceof FinallyBlock )
| | last . outer instanceof FinallyBlock )
last = last . outer ;
last = last . outer ;
if ( last . outer ! = null )
if ( last . outer ! = null )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError
( "Inconsistency: last " + lastModified
+ " surrounded by unexpected structure" ) ;
Iterator iter = successors . entrySet ( ) . iterator ( ) ;
Iterator iter = successors . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
while ( iter . hasNext ( ) ) {
Map . Entry entry = ( Map . Entry ) iter . next ( ) ;
Map . Entry entry = ( Map . Entry ) iter . next ( ) ;
FlowBlock dest = ( FlowBlock ) entry . getKey ( ) ;
FlowBlock dest = ( FlowBlock ) entry . getKey ( ) ;
if ( dest . predecessors . contains ( this ) = = ( dest = = END_OF_METHOD ) )
if ( dest . predecessors . contains ( this ) = = ( dest = = END_OF_METHOD ) )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError
( "Inconsistency: dest " + dest . getLabel ( )
+ " doesn't contain this predecessor" ) ;
Jump jumps = ( ( SuccessorInfo ) entry . getValue ( ) ) . jumps ;
Jump jumps = ( ( SuccessorInfo ) entry . getValue ( ) ) . jumps ;
if ( jumps = = null )
if ( jumps = = null )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError ( "Inconsistency: no jumps for "
+ dest . getLabel ( ) ) ;
for ( ; jumps ! = null ; jumps = jumps . next ) {
for ( ; jumps ! = null ; jumps = jumps . next ) {
if ( jumps . destination ! = dest )
if ( jumps . destination ! = dest )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError ( "Inconsistency:" + jumps
+ "doesn't point to "
+ dest . getLabel ( ) ) ;
if ( jumps . prev = = null
if ( jumps . prev = = null
| | jumps . prev . flowBlock ! = this
| | jumps . prev . flowBlock ! = this
| | jumps . prev . jump ! = jumps )
| | jumps . prev . jump ! = jumps )
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError ( "Inconsistency in " + jumps ) ;
prev_loop :
prev_loop :
for ( StructuredBlock prev = jumps . prev ; prev ! = block ;
for ( StructuredBlock prev = jumps . prev ; prev ! = block ;
prev = prev . outer ) {
prev = prev . outer ) {
if ( prev . outer = = null )
if ( prev . outer = = null )
throw new RuntimeException ( "Inconsistency" ) ;
throw new InternalError ( "Inconsistency: " + prev
+ " not in flowblock" ) ;
StructuredBlock [ ] blocks = prev . outer . getSubBlocks ( ) ;
StructuredBlock [ ] blocks = prev . outer . getSubBlocks ( ) ;
int i ;
int i ;
for ( i = 0 ; i < blocks . length ; i + + )
for ( i = 0 ; i < blocks . length ; i + + )
if ( blocks [ i ] = = prev )
if ( blocks [ i ] = = prev )
continue prev_loop ;
continue prev_loop ;
throw new InternalError ( "Inconsistency" ) ;
throw new InternalError ( "Inconsistency: " + prev
+ " not in its outer block "
+ prev . outer ) ;
}
}
}
}
}
}
@ -1357,18 +1369,45 @@ public class FlowBlock {
changed | = analyzeSwitch ( start , end ) ;
changed | = analyzeSwitch ( start , end ) ;
}
}
/ * Do T1 analysis when there is a loop , but only if :
if ( doT1 ( start , end ) ) {
* - the loop has only one exit ( plus returns )
* - or the successor block doesn ' t belong to the loop .
if ( ( GlobalOptions . debuggingFlags & GlobalOptions . DEBUG_FLOW ) ! = 0 )
*
GlobalOptions . err . println ( "after T1: " + this ) ;
* The reason for the extra checks are loops like
*
/ * T1 transformation succeeded . This may
* while ( x )
* make another T2 analysis in the previous
* . . .
* block possible .
* if ( y )
* /
* . . .
* return
*
* which would otherwise be translated to :
*
* outer : do {
* do {
* if ( ! x ) break outer ;
* . . .
* } while ( ! y )
* . . .
* return
* } while ( false )
* /
if ( successors . containsKey ( this )
& & ( ! successors . containsKey ( nextByCodeOrder )
| | successors . size ( ) = = 2
| | ( successors . size ( ) = = 3
& & successors . containsKey ( END_OF_METHOD ) ) )
& & doT1 ( start , end ) ) {
if ( ( GlobalOptions . debuggingFlags & GlobalOptions . DEBUG_FLOW ) ! = 0 )
GlobalOptions . err . println ( "after T1: " + this ) ;
/ * T1 transformation succeeded . This may
* make another T2 analysis in the previous
* block possible .
* /
return true ;
return true ;
}
}
FlowBlock succ = getSuccessor ( start , end ) ;
FlowBlock succ = getSuccessor ( start , end ) ;
while ( true ) {
while ( true ) {
@ -1443,7 +1482,7 @@ public class FlowBlock {
* The switch analyzation . This calls doSwitchT2 and doT1 on apropriate
* The switch analyzation . This calls doSwitchT2 and doT1 on apropriate
* regions . Only blocks whose block number lies in the given block number
* regions . Only blocks whose block number lies in the given block number
* range are considered and it is taken care of , that the switch
* range are considered and it is taken care of , that the switch
* is never leaved . < p >
* is never left . < p >
* The current flow block must contain the switch block as lastModified .
* The current flow block must contain the switch block as lastModified .
* @param start the start of the block number range .
* @param start the start of the block number range .
* @param end the end of the block number range .
* @param end the end of the block number range .