[Soot-list] Split units in Jimple / missing equals-implementation

John Jorgensen jorgnsn at lcd.uregina.ca
Mon Feb 13 13:21:14 EST 2006


>>>>> "eric.bodden" == Eric Bodden <eric.bodden at mail.mcgill.ca> writes:

    eric.bodden> This week I implemented a "must reaching
    eric.bodden> definitions" analysis, i.e. a definition os
    eric.bodden> reachable from a use when it is reachable on
    eric.bodden> *all* paths.  Strangely, this analysis missed
    eric.bodden> the following case:

    eric.bodden> 		int j;
    eric.bodden> 		try {
    eric.bodden> 			j=3;
    eric.bodden> 		} catch(Throwable t) {
    eric.bodden> 			j=4;
    eric.bodden> 		} finally {
    eric.bodden> 			j=5;
    eric.bodden> 		}
		
    eric.bodden> 		//why is j here not 5 FOR SURE?
    eric.bodden> 		System.out.println(j); //(1)
		

    eric.bodden> Actually, the definition for j has definetely
    eric.bodden> one unambigous reachable definition:
    eric.bodden> j=5. However, Soot splits this definition into
    eric.bodden> multiple ones in the exceptional unit
    eric.bodden> graph. Since AssignStmt also does not implement
    eric.bodden> hashcode/equals, the intersection at line (1)
    eric.bodden> fails, i.e. throws the information j=5 away.

    eric.bodden> So am I missing something or is there something wrong?

I think your diagnosis of when the introduction of multiple j=5
assignments occurs is incorrect, though it's been a while
since I worked on this, and I won't have a chance to refresh my
memory of ExceptionalUnitGraph for a couple of days.

There are two cases to consider, code generated by compilers that
work like javac did before version N (where I think N is 1.3, but I
could be wrong) and code generated by compilers that work like
javac has since version N.

Compilers that worked like Sun's pre-N javac implemented finally
by emitting jsr instructions that jumped to a single copy of the
finally code, with such a jsr appearing at the end of the try
block and at the end of all exception handlers covering the try
block.

It is difficult to analyze code including jsrs (some of the
original Soot papers discuss the difficulties; I forget the
details), which led to the decision early in the development of
Soot to replace the jsr constructs with multiple copies of the
finally block.  The replacement occurs very early in Soot's
processing, implemented in coffi.CFG if I recall correctly.  So
if you want to have a single copy of code to analyze, the scope
of the change involves much more than ExceptionalUnitGraph.

Apparently jsrs are problematic outside of Soot as well (I
believe, for example, that they complicate verification---see
section 4.9 of the VM spec) and Sun's compiler at version N
stopped using jsr, and started to implement finally with multiple
copies of the finally code, just like soot.  For example, javac
1.5.0_06 produces, for this variant of your illustration:

  int m(int j) {
    try {
      j=3;
    } catch(Throwable t) {
      j=4;
    } finally {
      j=5;
    }
    return j;
  }

this bytecode:

  int m(int);
    Code:
     0:   iconst_3
     1:   istore_1
     2:   iconst_5
     3:   istore_1
     4:   goto    20
     7:   astore_2
     8:   iconst_4
     9:   istore_1
     10:  iconst_5
     11:  istore_1
     12:  goto    20
     15:  astore_3
     16:  iconst_5
     17:  istore_1
     18:  aload_3
     19:  athrow
     20:  iload_1
     21:  ireturn
    Exception table:
     from   to  target type
       0     2     7   Class java/lang/Throwable

       0     2    15   any
       7    10    15   any
      15    16    15   any

which has 3 stores of 5 to i.

So recognizing that 5 is always stored to i requires
analyzing the CFG, and it is not the case that all the
assignments of 5 to i occur at a single definition.


More information about the Soot-list mailing list