KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > toolkits > graph > Block


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1999-2000 Patrice Pominville, Raja Vallee-Rai
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 package soot.toolkits.graph;
28
29 import soot.util.*;
30 import java.util.*;
31 import soot.*;
32 import soot.baf.*;
33
34
35
36
37 /**
38  * Represents BasicBlocks that partition
39  * a method body. It is implemented as view on an
40  * underlying Body instance; as a consequence, changes made on a Block
41  * will be automatically reflected in its enclosing method body. Blocks
42  * also exist in the context of a BlockGraph, a CFG for a method where
43  * Block instances are the nodes of the graph. Hence, a Block can be queried
44  * for its successors and predecessors Blocks, as found in this graph.
45  */

46 public class Block
47 {
48     private Unit mHead, mTail;
49     private Body mBody;
50     private List mPreds, mSuccessors;
51     private int mPredCount = 0, mBlockLength = 0, mIndexInMethod = 0;
52     private BlockGraph mBlockGraph;
53
54     /**
55      * Constructs a Block in the context of a BlockGraph, and enclosing Body instances.
56      *
57      *
58      * @param aHead The first unit ir this Block.
59      * @param aTail The last unit in this Block.
60      * @param aBody The Block's enclosing Body instance.
61      * @param aIndexInMethod The index of this Block in the list of
62      * Blocks that partition it's enclosing Body instance.
63      * @param aBlockLength The number of units that makeup this block.
64      * @param aBlockGraph The Graph of Blocks in which this block lives.
65      *
66      * @see Body
67      * @see Chain
68      * @see BlockGraph
69      * @see Unit
70      * @see SootMethod
71      */

72     public Block(Unit aHead, Unit aTail, Body aBody, int aIndexInMethod, int aBlockLength, BlockGraph aBlockGraph)
73     {
74         mHead = aHead;
75         mTail = aTail;
76         mBody = aBody;
77         mIndexInMethod = aIndexInMethod;
78         mBlockLength = aBlockLength;
79         mBlockGraph = aBlockGraph;
80     }
81
82
83
84     /**
85      * Returns the Block's enclosing Body instance.
86      *
87      * @return The block's chain of instructions.
88      * @see soot.jimple.JimpleBody
89      * @see BafBody
90      * @see Body
91      */

92     public Body getBody()
93     {
94         return mBody;
95     }
96        
97     
98     /**
99      * Returns an iterator for the linear chain of Units that make up the block.
100      *
101      * @return An iterator that iterates over the block's units.
102      * @see Chain
103      * @see Unit
104      */

105     public Iterator iterator()
106     {
107         if(mBody != null)
108         {
109             Chain units = mBody.getUnits();
110             return units.iterator(mHead, mTail);
111         } else {
112             return null;
113         }
114     }
115     
116     /**
117      * Inserts a Unit before some other Unit in this block.
118      *
119      *
120      * @param toInsert A Unit to be inserted.
121      * @param point A Unit in the Block's body
122      * before which we wish to insert the Unit.
123      * @see Unit
124      * @see Chain
125      */

126     public void insertBefore(Unit toInsert, Unit point)
127     {
128         if(point == mHead)
129             mHead = toInsert;
130
131         Chain methodBody = mBody.getUnits();
132         methodBody.insertBefore(toInsert, point);
133     }
134
135
136      /**
137      * Inserts a Unit after some other Unit in the Block.
138      *
139      * @param toInsert A Unit to be inserted.
140      * @param point A Unit in the Block after which we wish to
141      * insert the Unit.
142      * @see Unit
143      */

144     public void insertAfter(Unit toInsert, Unit point)
145     {
146         if(point == mTail)
147             mTail = toInsert;
148
149         Chain methodBody = mBody.getUnits();
150         methodBody.insertAfter(toInsert, point);
151     }
152
153
154
155     /**
156      * Removes a Unit occuring before some other Unit in the Block.
157      *
158      * @param item A Unit to be remove from the Block's Unit Chain.
159      * @return True if the item could be found and removed.
160      *
161      */

162     public boolean remove(Unit item)
163     {
164         Chain methodBody = mBody.getUnits();
165         
166         if(item == mHead)
167             mHead = (Unit)methodBody.getSuccOf(item);
168         else if(item == mTail)
169             mTail = (Unit) methodBody.getPredOf(item);
170         
171         return methodBody.remove(item);
172     }
173     
174     /**
175      * Returns the Unit occuring immediatly after some other Unit in the block.
176      *
177      * @param aItem The Unit from which we wish to get it's successor.
178      * @return The successor or null if <code>aItem</code> is the tail
179      * for this Block.
180      *
181      */

182     public Unit getSuccOf(Unit aItem)
183     {
184         Chain methodBody = mBody.getUnits();
185         if(aItem != mTail)
186             return (Unit) methodBody.getSuccOf(aItem);
187         else
188             return null;
189     }
190     
191     /**
192      * Returns the Unit occuring immediatly before some other Unit in the block.
193      *
194      * @param aItem The Unit from which we wish to get it's predecessor.
195      * @return The predecessor or null if <code>aItem</code> is the head
196      * for this Block.
197      */

198     public Unit getPredOf(Unit aItem)
199     {
200         Chain methodBody = mBody.getUnits();
201         if(aItem != mHead)
202             return (Unit) methodBody.getPredOf(aItem);
203         else
204             return null;
205     }
206
207     /**
208      * Set the index of this Block in the list of Blocks that partition
209      * its enclosing Body instance.
210      *
211      * @param aIndexInMethod The index of this Block in the list of
212      * Blocks that partition it's enclosing
213      * Body instance.
214      **/

215     public void setIndexInMethod(int aIndexInMethod)
216     {
217         mIndexInMethod = aIndexInMethod;
218     }
219
220     /**
221      * Returns the index of this Block in the list of Blocks that partition it's
222      * enclosing Body instance.
223      * @return The index of the block in it's enclosing Body instance.
224      */

225     public int getIndexInMethod()
226     {
227         return mIndexInMethod;
228     }
229
230     /**
231      * Returns the first unit in this block.
232      * @return The first unit in this block.
233      */

234     public Unit getHead()
235     {
236         return mHead;
237     }
238     
239     /**
240      * Returns the last unit in this block.
241      * @return The last unit in this block.
242      */

243     public Unit getTail()
244     {
245         return mTail;
246     }
247
248     /**
249      * Sets the list of Blocks that are predecessors of this block in it's enclosing
250      * BlockGraph instance.
251      * @param preds The a List of Blocks that precede this block.
252      *
253      * @see BlockGraph
254      */

255     public void setPreds(List preds)
256     {
257         mPreds = preds;
258         return;
259     }
260
261     /**
262      * Returns the List of Block that are predecessors to this block,
263      * @return A list of predecessor blocks.
264      * @see BlockGraph
265      */

266     public List getPreds()
267     {
268         return mPreds;
269     }
270
271
272
273     /**
274      * Sets the list of Blocks that are successors of this block in it's enclosing
275      * BlockGraph instance.
276      * @param succs The a List of Blocks that succede this block.
277      *
278      * @see BlockGraph
279      */

280     public void setSuccs(List succs)
281     {
282         mSuccessors = succs;
283     }
284
285
286
287     /**
288      * Returns the List of Blocks that are successors to this block,
289      * @return A list of successorblocks.
290      * @see BlockGraph
291      */

292     public List getSuccs()
293     {
294         return mSuccessors;
295     }
296
297
298
299     private Map buildMapForBlock()
300     {
301         Map m = new HashMap();
302         List basicBlocks = mBlockGraph.getBlocks();
303         Iterator it = basicBlocks.iterator();
304         while(it.hasNext()) {
305             Block currentBlock = (Block) it.next();
306             m.put(currentBlock.getHead(), "block" + (new Integer JavaDoc(currentBlock.getIndexInMethod()).toString()));
307         }
308         return m;
309     }
310
311
312     Map allMapToUnnamed = new AllMapTo("???");
313
314     class AllMapTo extends AbstractMap
315     {
316         Object JavaDoc dest;
317         
318         public AllMapTo(Object JavaDoc dest)
319         {
320             this.dest = dest;
321         }
322         
323         public Object JavaDoc get(Object JavaDoc key)
324         {
325             return dest;
326         }
327         
328         public Set entrySet()
329         {
330             throw new UnsupportedOperationException JavaDoc();
331         }
332     }
333
334
335     
336     public String JavaDoc toShortString() {return "Block #" + mIndexInMethod; }
337
338     public String JavaDoc toString()
339     {
340         StringBuffer JavaDoc strBuf = new StringBuffer JavaDoc();
341
342                 
343
344         // print out predecessors.
345

346         strBuf.append("Block " + mIndexInMethod + ":" + System.getProperty("line.separator"));
347         strBuf.append("[preds: ");
348         int count = 0;
349         if(mPreds != null) {
350             Iterator it = mPreds.iterator();
351             while(it.hasNext()) {
352                 
353                 strBuf.append(((Block) it.next()).getIndexInMethod()+ " ");
354             }
355         }
356         strBuf.append("] [succs: ");
357         if(mSuccessors != null) {
358             Iterator it = mSuccessors.iterator();
359             while(it.hasNext()) {
360                 
361                 strBuf.append(((Block) it.next()).getIndexInMethod() + " ");
362             }
363             
364         }
365             
366         strBuf.append("]" + System.getProperty("line.separator"));
367         
368
369         
370         //strBuf.append(" block" + mIndexInMethod + ":" + System.getProperty("line.separator"));
371

372         Chain methodUnits = mBody.getUnits();
373         Iterator basicBlockIt = methodUnits.iterator(mHead, mTail);
374         
375         if(basicBlockIt.hasNext()) {
376             Unit someUnit = (Unit) basicBlockIt.next();
377             strBuf.append(someUnit.toString() + ";" + System.getProperty("line.separator"));
378             while(basicBlockIt.hasNext()){
379                 someUnit = (Unit) basicBlockIt.next();
380                 if(someUnit == mTail)
381                     break;
382                 strBuf.append(someUnit.toString() + ";" + System.getProperty("line.separator"));
383             }
384             someUnit = mTail;
385             if(mTail == null)
386                 strBuf.append("error: null tail found; block length: " + mBlockLength +"" + System.getProperty("line.separator"));
387             else if(mHead != mTail)
388                 strBuf.append(someUnit.toString() + ";" + System.getProperty("line.separator"));
389         
390
391         }
392         // Or, it could be an empty block (e.g. Start or Stop Block) --NU
393
// else
394
// G.v().out.println("No basic blocks found; must be interface class.");
395

396         return strBuf.toString();
397     }
398
399 }
400
Popular Tags