soot.toolkits.graph.TrapUnitGraph Maven / Gradle / Ivy
/* Soot - a J*va Optimization Framework
* Copyright (C) 1999 Patrice Pominville, Raja Vallee-Rai
*
* 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.
*/
/*
* Modified by the Sable Research Group and others 1997-2003.
* See the 'credits' file distributed with Soot for the complete list of
* contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
*/
package soot.toolkits.graph;
import soot.*;
import java.util.*;
import soot.options.Options;
/**
*
* Represents a CFG for a {@link Body} instance where the nodes are
* {@link Unit} instances, and where, in additional to unexceptional
* control flow edges, edges are added from every trapped {@link
* Unit} to the {@link Trap}'s handler Unit
, regardless
* of whether the trapped Unit
s may actually throw the
* exception caught by the Trap
.
*
*
* There are three distinctions between the exceptional edges added
* in TrapUnitGraph
and the exceptional edges added in
* {@link ExceptionalUnitGraph}:
*
* -
* In
ExceptionalUnitGraph
, the edges to
* Trap
s are associated with Unit
s which
* may actually throw an exception which the Trap
* catches (according to the {@link
* soot.toolkits.exceptions.ThrowAnalysis ThrowAnalysis} used in the
* construction of the graph). In TrapUnitGraph
, there
* are edges from every trapped Unit
to the
* Trap
, regardless of whether it can throw an exception
* caught by the Trap
.
*
* -
* In
ExceptionalUnitGraph
, when a Unit
may
* throw an exception that is caught by a Trap
there
* are edges from every predecessor of the excepting
* Unit
to the Trap
's handler. In
* TrapUnitGraph
, edges are not added from the
* predecessors of excepting Unit
s.
* -
* In
ExceptionalUnitGraph
, when a Unit
may
* throw an exception that is caught by a Trap
, there
* may be no edge from the excepting Unit
itself to the
* Trap
(depending on the possibility of side effects
* and the setting of the omitExceptingUnitEdges
* parameter). In TrapUnitGraph
, there is always an edge
* from the excepting Unit
to the
* Trap
.
*
*/
public class TrapUnitGraph extends UnitGraph
{
/**
* Constructs the graph from a given Body instance.
* @param the Body instance from which the graph is built.
*/
public TrapUnitGraph(Body body)
{
super(body);
int size = unitChain.size();
if(Options.v().time())
Timers.v().graphTimer.start();
unitToSuccs = new HashMap(size * 2 + 1, 0.7f);
unitToPreds = new HashMap(size * 2 + 1, 0.7f);
buildUnexceptionalEdges(unitToSuccs, unitToPreds);
buildExceptionalEdges(unitToSuccs, unitToPreds);
makeMappedListsUnmodifiable(unitToSuccs);
makeMappedListsUnmodifiable(unitToPreds);
buildHeadsAndTails();
if(Options.v().time())
Timers.v().graphTimer.end();
}
/**
* Method to compute the edges corresponding to exceptional
* control flow.
*
* @param unitToSuccs A Map
from {@link Unit}s to {@link
* List}s of 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 Trap
s.
*
* @param unitToPreds A Map
from Unit
s to
* List
s of Unit
s. This is an
* “out parameter”;
* buildExceptionalEdges
will add a
* mapping for every Trap
handler to
* all the Unit
s within the scope of
* that Trap
.
*/
protected void buildExceptionalEdges(Map unitToSuccs, Map unitToPreds) {
for (Iterator trapIt = body.getTraps().iterator();
trapIt.hasNext(); ) {
Trap trap = (Trap) trapIt.next();
Unit first = trap.getBeginUnit();
Unit last = (Unit) unitChain.getPredOf(trap.getEndUnit());
Unit catcher = trap.getHandlerUnit();
for (Iterator unitIt = unitChain.iterator(first, last);
unitIt.hasNext(); ) {
Unit trapped = (Unit) unitIt.next();
addEdge(unitToSuccs, unitToPreds, trapped, catcher);
}
}
}
}