1   /* SortedBlocks.java */
2   
3   package org.quilt.cl;
4   
5   import java.util.*;
6   import org.quilt.graph.*;
7   
8   /***
9    * Manages an index into the bytecode vertices in a method's control flow 
10   * graph.  The vertices (blocks) are indexed by their position in the 
11   * original code.  The blocks may be from different graphs in a set of 
12   * nested graphs.
13   *
14   * @author < a href="jdd@dixons.org">Jim Dixon</a>
15   */
16  public class SortedBlocks {
17  
18      private ControlFlowGraph  graph;    // control flow graph for a method
19      private SortedMap blox;     // index of vertices by position
20  
21      /*** Creates an empty map. */
22      public SortedBlocks () {
23          blox = new TreeMap();
24      }
25      
26      /*** 
27       * Add a vertex at its bytecode position.  * It is an
28       * error if there is already a vertex at this position.
29       *
30       * XXX SHOULD THROW EXCEPTION IN SUCH A CASE.
31       *
32       * @param  v    CodeVertex to be inserted
33       * @return True if the operation succeeds, false if something is
34       *                  already present at that position.
35       */
36      public boolean add (final CodeVertex v) {
37          int pos = -1;
38          if (v == null) {
39              throw new IllegalArgumentException (
40                      "attempt to add null vertex");
41          }
42          pos = v.getPosition();
43          if (pos < 0) {
44              throw new IllegalArgumentException (
45                      "vertex has invalid position");
46          }
47          Integer p = new Integer(pos);
48          if (blox.containsKey (p) ) {
49              return false;               // operation failed
50          } else {
51              blox.put (p, v);
52              return true;
53          }
54      }
55  
56      /*** 
57       * Find or create a code vertex starting at a given position.
58       *
59       * @param pos Byte offset in the original bytecode.
60       * @param e   If the vertex must be created, Edge into which it
61       *              gets inserted.  Otherwise, edge target becomes
62       *              the existing vertex.
63       */
64      public CodeVertex find ( final int pos, ControlFlowGraph currGraph, 
65                                                              Edge e) {
66          Integer p = new Integer(pos);
67          if (blox.containsKey (p) ) {
68              CodeVertex v = (CodeVertex) blox.get(p);
69              ControlFlowGraph vGraph = (ControlFlowGraph)v.getGraph();
70              Entry x;
71              if ( vGraph == currGraph ) {
72                  e.setTarget(v);         // point the edge at this vertex
73              } else if ( (x = currGraph.closestEntry(vGraph)) != null) {
74                  // if v is in a lower level graph, connect the edge
75                  // to the netwise closest Entry
76                  e.setTarget(x);
77              } else {
78                  // if v is in any graph which is not this graph or a 
79                  // child, we get there through the current graph's Exit 
80                  e.setTarget(currGraph.getExit());
81              }
82              return v;
83          } else {
84              return add (pos, e);
85          }
86      }
87      /***
88       * Add a vertex at bytecode offset pos along edge e.  No other 
89       * vertex with that bytecode offset may exist.
90       *
91       * @param pos Bytecode offset.
92       * @param e   Edge along which the Vertex will be created
93       * @return    Reference to the Vertex created.
94       */
95      public CodeVertex add (final int pos, final Edge e) {
96  //      // DEBUG
97  //      System.out.println(
98  //          "- - - - - - - - - - - - - - - - - - - - - - - - - \n"
99  //          + "SortedBlocks.add: pos " + pos + " along edge " + e);
100 //      // END
101         Integer p = new Integer(pos);
102         Vertex source_ = e.getSource();
103         CodeVertex v;
104         if ( source_ instanceof Exit) {
105             v = ((ControlFlowGraph)e.getTarget().getGraph())
106                                                 .insertCodeVertex(e);
107         } else {
108             v = ((ControlFlowGraph)source_.getGraph())
109                                                 .insertCodeVertex(e);
110         }
111         v.setPos(pos);
112 //      v.getConnector().setData ( new ConnData() );
113         blox.put (p, v);
114 //      // DEBUG
115 //      System.out.println(
116 //          "    after insertion edge becomes " + e
117 //          + "\n- - - - - - - - - - - - - - - - - - - - - - - - - ");
118 //      // END
119         return v;
120     }
121     /*** Does a vertex exist with this bytecode offset? */
122     public boolean exists (final int pos) {
123         Integer p = new Integer(pos);
124         return blox.containsKey(p);
125     }
126     /*** 
127      * Find the code vertex starting at a given bytecode offset.
128      * The vertex must exist.  XXX Should throw an exception if
129      * it doesn't.
130      *
131      * @param pos Bytecode offset of first instruction in the block.
132      * @return    The matching vertex.
133      */
134     public CodeVertex get (final int pos) {
135         Integer p = new Integer (pos);
136         if (!blox.containsKey (p) ) {
137             throw new GraphBuildException ( 
138                     "INTERNAL ERROR - no vertex at " + pos);
139         }
140         return (CodeVertex) blox.get(p);
141     }
142     /***
143      * How many code vertices are currently in the index?
144      *
145      * @return The number of vertices in the index.
146      */
147     public int size() {
148         return blox.size();
149     }
150 
151     /*** 
152      * Standard toString(), XXX needs some work.
153      *
154      * @return Roughly formatted table of vertices.
155      */
156     public String toString() {
157         // the vertices are keyed by position
158         Iterator vertices = blox.keySet().iterator();
159         String s = "vertex  position / instructions\n";
160         while (vertices.hasNext()) {
161             Integer position = (Integer) vertices.next();
162             CodeVertex v = (CodeVertex) blox.get( position );
163             s += "  " + v.getIndex()
164                + "     " + position + "\n"
165                + v      // possibly problems here ...
166                ;
167         }
168         return s;
169     } 
170 }
This page was automatically generated by Maven