001: /* ControlFlowGraph.java */
002: package org.quilt.cl;
003:
004: import java.util.HashMap;
005: import java.util.Map;
006: import org.apache.bcel.generic.InstructionList;
007: import org.quilt.graph.*;
008:
009: /**
010: * Directed graph extended for use in analyzing method instruction
011: * lists.
012: *
013: * @author <a href="jddixon@users.sourceforge.net">Jim Dixon</a>
014: */
015: public class ControlFlowGraph extends Directed {
016:
017: /** Key code vertex, value handle on first instruction. */
018: protected Map startHandles = null;
019: /** Key code vertex, value handle on last instruction. */
020: protected Map endHandles = null;
021: /** Key source vertex, value target vertex where connecting
022: * instruction is GotoInstruction. */
023: protected Map gotoFixMeUps = null;
024: /** Instruction list built in walking the graph. */
025: protected InstructionList ilist = null;
026:
027: /** Get a reference to the map of handles on first instructions. */
028: public Map getStartHandles() {
029: return startHandles;
030: }
031:
032: /** Get a reference to the map of handles on last instructions. */
033: public Map getEndHandles() {
034: return endHandles;
035: }
036:
037: /** Get a reference to the source/target vertex map where the
038: * connecting instruction is a GotoInstruction. */
039: public Map getGotoFixMeUps() {
040: return gotoFixMeUps;
041: }
042:
043: /** Get a reference to the instruction list built while walking the
044: * graph. */
045: public InstructionList getInstructionList() {
046: return ilist;
047: }
048:
049: /** Create a new top level control flow graph. */
050: public ControlFlowGraph() {
051: super ();
052: startHandles = new HashMap();
053: endHandles = new HashMap();
054: gotoFixMeUps = new HashMap();
055: ilist = new InstructionList();
056: }
057:
058: /**
059: * Create a control flow graph without connecting it to this
060: * parent graph but sharing protected data structures.
061: * @param parent The cfg one level up.
062: */
063: protected ControlFlowGraph(ControlFlowGraph parent) {
064: super (parent);
065: startHandles = parent.startHandles;
066: endHandles = parent.endHandles;
067: gotoFixMeUps = parent.gotoFixMeUps;
068: ilist = parent.ilist;
069: }
070:
071: /**
072: * Create a control flow graph, connecting it to this graph as
073: * its parent by inserting it along the directed edge e (the
074: * Entry first, followed by the subgraph Exit.
075: *
076: * @param e Edge along which the subgraph is to be inserted.
077: * @param n Number of extra edges on the ComplexConnector in
078: * the subgraph's Entry vertex (must be at least 1).
079: */
080: public Directed subgraph(final Edge e, final int n) {
081: return super .connectSubgraph(new ControlFlowGraph(this ), e, n);
082: }
083:
084: /**
085: * Insert a code vertex along an edge, retargeting the edge to
086: * the vertex inserted. The vertex is created by this method.
087: *
088: * @param e Edge along which the vertex is inserted.
089: * @return The CodeVertex created.
090: */
091: public CodeVertex insertCodeVertex(Edge e) {
092: return (CodeVertex) super .insertVertex(new CodeVertex(this ), e);
093: }
094:
095: /**
096: * Insert a pre-existing CodeVertex along an edge. The edge
097: * and the vertex must be in the same graph.
098: *
099: * @param v CodeVertex being inserted.
100: * @param e Edge in which it is to be inserted.
101: */
102: public CodeVertex insertCodeVertex(CodeVertex v, Edge e) {
103: return (CodeVertex) super.insertVertex(v, e);
104: }
105: }
|