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