soot.toolkits.graph.ClassicCompleteUnitGraph Maven / Gradle / Ivy
Show all versions of robovm-soot Show documentation
/* Soot - a J*va Optimization Framework
* Copyright (C) 2003 John Jorgensen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.toolkits.graph;
import soot.*;
import java.util.*;
/**
* Represents a CFG for a Body instance where the nodes are
* {@link Unit} instances, and where edges are a conservative
* indication of unexceptional and exceptional control
* flow.
*
* ClassicCompleteUnitGraph attempts to duplicate the
* results that would have been produced by Soot's
* CompleteUnitGraph
in releases up to Soot 2.1.0 (the
* one known discrepancy is that the 2.1.0
* CompleteUnitGraph
would include two edges joining one
* node to another
* {@link Unit}s if the first node both branched to and fell through to
* the second). It is included solely for testing purposes, and
* should not be used in actual analyses.
*
* There are two distinctions between the graphs produced by the
* ClassicCompleteUnitGraph and
* ExceptionalUnitGraph:
*
*
* - ExceptionalUnitGraph only creates edges to a
* Trap handler for trapped Units that have the
* potential to throw the particular exception type caught by the
* handler, according to the {@link ThrowAnalysis} used to estimate
* which exceptions each {@link Unit} may throw.
* ClassicCompleteUnitGraph creates edges for all trapped
* Units, regardless of the types of exceptions they may
* throw.
*
* - When ExceptionalUnitGraph creates edges for a
* trapped Unit that may throw a caught exception, it adds
* edges from each predecessor of the excepting Unit to the
* handler. If the excepting Unit itself has no potential
* side effects, ExceptionalUnitGraph may omit an edge from
* it to the handler, depending on the parameters
* passed to the ExceptionalUnitGraph constructor.
* ClassicCompleteUnitGraph, on the other hand, always adds
* an edge from the excepting Unit itself to the handler,
* and adds edges from the predecessor only of the first
* Unit covered by a Trap (in this one aspect
* ClassicCompleteUnitGraph is less conservative than
* ExceptionalUnitGraph, since it ignores the possibility of
* a branch into the middle of a protected area).
*
*
*/
public class ClassicCompleteUnitGraph extends TrapUnitGraph
{
/**
* Constructs the graph from a given Body instance.
* @param the Body instance from which the graph is built.
*/
public ClassicCompleteUnitGraph(Body body)
{
// The TrapUnitGraph constructor will use our buildExceptionalEdges:
super(body);
}
/**
* Method to compute the edges corresponding to exceptional
* control flow.
*
* @param unitToSuccs A {@link Map} from {@link Unit}s to {@link
* List}s of {@link Unit}s. This is * an ``out
* parameter''; buildExceptionalEdges
* will add a mapping for every Unit
* within the scope of one or more {@link
* Trap}s to a List of the handler
* units of those Traps.
*
* @param unitToPreds A {@link Map} from {@link Unit}s to
* {@link List}s of {@link Unit}s. This is an
* ``out parameter'';
* buildExceptionalEdges will add a
* mapping for every {@link Trap} handler to
* all the Units within the scope of
* that Trap.
*/
protected void buildExceptionalEdges(Map unitToSuccs, Map unitToPreds) {
// First, add the same edges as TrapUnitGraph.
super.buildExceptionalEdges(unitToSuccs, unitToPreds);
// Then add edges from the predecessors of the first
// trapped Unit for each Trap.
for (Iterator trapIt = body.getTraps().iterator();
trapIt.hasNext(); ) {
Trap trap = (Trap) trapIt.next();
Unit firstTrapped = trap.getBeginUnit();
Unit catcher = trap.getHandlerUnit();
// Make a copy of firstTrapped's predecessors to iterate over,
// just in case we're about to add new predecessors to this
// very list, though that can only happen if the handler traps
// itself. And to really allow for that
// possibility, we should iterate here until we reach a fixed
// point; but the old UnitGraph that we are attempting to
// duplicate did not do that, so we won't either.
List origPredsOfTrapped = new ArrayList(getPredsOf(firstTrapped));
for (Iterator unitIt = origPredsOfTrapped.iterator();
unitIt.hasNext(); ) {
Unit pred = (Unit) unitIt.next();
addEdge(unitToSuccs, unitToPreds, pred, catcher);
}
}
}
}