001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 1999 Patrice Pominville, Raja Vallee-Rai
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: /*
021: * Modified by the Sable Research Group and others 1997-2003.
022: * See the 'credits' file distributed with Soot for the complete list of
023: * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
024: */
025:
026: package soot.toolkits.graph;
027:
028: import soot.*;
029: import java.util.*;
030: import soot.options.Options;
031:
032: /**
033: * <p>
034: * Represents a CFG for a {@link Body} instance where the nodes are
035: * {@link Unit} instances, and where, in additional to unexceptional
036: * control flow edges, edges are added from every trapped {@link
037: * Unit} to the {@link Trap}'s handler <code>Unit</code>, regardless
038: * of whether the trapped <code>Unit</code>s may actually throw the
039: * exception caught by the <code>Trap</code>.</p>
040: *
041: * <p>
042: * There are three distinctions between the exceptional edges added
043: * in <code>TrapUnitGraph</code> and the exceptional edges added in
044: * {@link ExceptionalUnitGraph}:
045: * <ol>
046: * <li>
047: * In <code>ExceptionalUnitGraph</code>, the edges to
048: * <code>Trap</code>s are associated with <code>Unit</code>s which
049: * may actually throw an exception which the <code>Trap</code>
050: * catches (according to the {@link
051: * soot.toolkits.exceptions.ThrowAnalysis ThrowAnalysis} used in the
052: * construction of the graph). In <code>TrapUnitGraph</code>, there
053: * are edges from every trapped <code>Unit</code> to the
054: * <code>Trap</code>, regardless of whether it can throw an exception
055: * caught by the <code>Trap</code>.
056: * </li>
057: * <li>
058: * In <code>ExceptionalUnitGraph</code>, when a <code>Unit</code> may
059: * throw an exception that is caught by a <code>Trap</code> there
060: * are edges from every predecessor of the excepting
061: * <code>Unit</code> to the <code>Trap</code>'s handler. In
062: * <code>TrapUnitGraph</code>, edges are not added from the
063: * predecessors of excepting <code>Unit</code>s.</li>
064: * <li>
065: * In <code>ExceptionalUnitGraph</code>, when a <code>Unit</code> may
066: * throw an exception that is caught by a <code>Trap</code>, there
067: * may be no edge from the excepting <code>Unit</code> itself to the
068: * <code>Trap</code> (depending on the possibility of side effects
069: * and the setting of the <code>omitExceptingUnitEdges</code>
070: * parameter). In <code>TrapUnitGraph</code>, there is always an edge
071: * from the excepting <code>Unit</code> to the
072: * <code>Trap</code>.</li>
073: * </ol>
074: */
075: public class TrapUnitGraph extends UnitGraph {
076: /**
077: * Constructs the graph from a given Body instance.
078: * @param the Body instance from which the graph is built.
079: */
080: public TrapUnitGraph(Body body) {
081: super (body);
082: int size = unitChain.size();
083:
084: if (Options.v().time())
085: Timers.v().graphTimer.start();
086:
087: unitToSuccs = new HashMap(size * 2 + 1, 0.7f);
088: unitToPreds = new HashMap(size * 2 + 1, 0.7f);
089: buildUnexceptionalEdges(unitToSuccs, unitToPreds);
090: buildExceptionalEdges(unitToSuccs, unitToPreds);
091: makeMappedListsUnmodifiable(unitToSuccs);
092: makeMappedListsUnmodifiable(unitToPreds);
093:
094: buildHeadsAndTails();
095:
096: if (Options.v().time())
097: Timers.v().graphTimer.end();
098:
099: soot.util.PhaseDumper.v().dumpGraph(this , body);
100: }
101:
102: /**
103: * Method to compute the edges corresponding to exceptional
104: * control flow.
105: *
106: * @param unitToSuccs A <code>Map</code> from {@link Unit}s to {@link
107: * List}s of <code>Unit</code>s. This is an “out
108: * parameter”; <code>buildExceptionalEdges</code>
109: * will add a mapping for every <code>Unit</code>
110: * within the scope of one or more {@link
111: * Trap}s to a <code>List</code> of the handler
112: * units of those <code>Trap</code>s.
113: *
114: * @param unitToPreds A <code>Map</code> from <code>Unit</code>s to
115: * <code>List</code>s of <code>Unit</code>s. This is an
116: * “out parameter”;
117: * <code>buildExceptionalEdges</code> will add a
118: * mapping for every <code>Trap</code> handler to
119: * all the <code>Unit</code>s within the scope of
120: * that <code>Trap</code>.
121: */
122: protected void buildExceptionalEdges(Map unitToSuccs,
123: Map unitToPreds) {
124: for (Iterator trapIt = body.getTraps().iterator(); trapIt
125: .hasNext();) {
126: Trap trap = (Trap) trapIt.next();
127: Unit first = trap.getBeginUnit();
128: Unit last = (Unit) unitChain.getPredOf(trap.getEndUnit());
129: Unit catcher = trap.getHandlerUnit();
130: for (Iterator unitIt = unitChain.iterator(first, last); unitIt
131: .hasNext();) {
132: Unit trapped = (Unit) unitIt.next();
133: addEdge(unitToSuccs, unitToPreds, trapped, catcher);
134: }
135: }
136: }
137: }
|