View Javadoc

1   // StackDepthVisitor.java, created Fri Jan 11 16:49:00 2002 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Compiler.BytecodeAnalysis;
5   
6   import java.util.Stack;
7   import joeq.Class.jq_InstanceField;
8   import joeq.Class.jq_Method;
9   import joeq.Class.jq_StaticField;
10  import joeq.Class.jq_Type;
11  import jwutil.util.Assert;
12  
13  /***
14   * A simple visitor that keeps track of the bytecode stack depth.
15   * 
16   * @author  John Whaley <jwhaley@alum.mit.edu>
17   * @version $Id: StackDepthVisitor.java 2282 2005-05-28 11:14:27Z joewhaley $
18   */
19  public class StackDepthVisitor extends BytecodeVisitor {
20  
21      protected int currentStackDepth;
22      protected final ControlFlowGraph cfg;
23      
24      /*** Creates new StackDepthVisitor */
25      public StackDepthVisitor(jq_Method method, ControlFlowGraph cfg) {
26          super(method);
27          this.cfg = cfg;
28      }
29  
30      public void go() {
31          // initialize all to -1
32          int n = cfg.getNumberOfBasicBlocks();
33          for (int i=0; i<n; ++i) {
34              BasicBlock bb = cfg.getBasicBlock(i);
35              bb.startingStackDepth = -1;
36          }
37          // start at the entry
38          Stack w = new Stack();
39          BasicBlock bb = cfg.getEntry();
40          bb.startingStackDepth = 0;
41          w.push(bb);
42          while (!w.isEmpty()) {
43              bb = (BasicBlock)w.pop();
44              currentStackDepth = bb.startingStackDepth;
45              visitBasicBlock(bb);
46              for (int i=0; i<bb.getNumberOfSuccessors(); ++i) {
47                  BasicBlock bb2 = bb.getSuccessor(i);
48                  if (bb2.startingStackDepth == -1) {
49                      bb2.startingStackDepth = currentStackDepth;
50                      w.push(bb2);
51                  } else {
52                      Assert._assert(bb2.startingStackDepth == currentStackDepth);
53                  }
54              }
55              ExceptionHandlerIterator ei = bb.getExceptionHandlers();
56              while (ei.hasNext()) {
57                  ExceptionHandler e = ei.nextEH();
58                  BasicBlock bb2 = e.getEntry();
59                  if (bb2.startingStackDepth == -1) {
60                      bb2.startingStackDepth = 1;
61                      w.push(bb2);
62                  } else {
63                      Assert._assert(bb2.startingStackDepth == 1);
64                  }
65              }
66          }
67      }
68      
69      public void visitBasicBlock(BasicBlock bb) {
70          if (TRACE) out.println("Visiting "+bb);
71          for (i_end=bb.getStart()-1; ; ) {
72              i_start = i_end+1;
73              if (isEndOfBB(bb)) break;
74              this.visitBytecode();
75          }
76      }
77      
78      private boolean isEndOfBB(BasicBlock bb) {
79          return i_start > bb.getEnd();
80      }
81      
82      public void visitACONST(Object s) {
83          super.visitACONST(s);
84          ++currentStackDepth;
85      }
86      public void visitICONST(int c) {
87          super.visitICONST(c);
88          ++currentStackDepth;
89      }
90      public void visitLCONST(long c) {
91          super.visitLCONST(c);
92          currentStackDepth+=2;
93      }
94      public void visitFCONST(float c) {
95          super.visitFCONST(c);
96          ++currentStackDepth;
97      }
98      public void visitDCONST(double c) {
99          super.visitDCONST(c);
100         currentStackDepth+=2;
101     }
102     public void visitILOAD(int i) {
103         super.visitILOAD(i);
104         ++currentStackDepth;
105     }
106     public void visitLLOAD(int i) {
107         super.visitLLOAD(i);
108         currentStackDepth+=2;
109     }
110     public void visitFLOAD(int i) {
111         super.visitFLOAD(i);
112         ++currentStackDepth;
113     }
114     public void visitDLOAD(int i) {
115         super.visitDLOAD(i);
116         currentStackDepth+=2;
117     }
118     public void visitALOAD(int i) {
119         super.visitALOAD(i);
120         ++currentStackDepth;
121     }
122     public void visitISTORE(int i) {
123         super.visitISTORE(i);
124         --currentStackDepth;
125     }
126     public void visitLSTORE(int i) {
127         super.visitLSTORE(i);
128         currentStackDepth-=2;
129     }
130     public void visitFSTORE(int i) {
131         super.visitFSTORE(i);
132         --currentStackDepth;
133     }
134     public void visitDSTORE(int i) {
135         super.visitDSTORE(i);
136         currentStackDepth-=2;
137     }
138     public void visitASTORE(int i) {
139         super.visitASTORE(i);
140         --currentStackDepth;
141     }
142     public void visitIALOAD() {
143         super.visitIALOAD();
144         --currentStackDepth;
145     }
146     public void visitFALOAD() {
147         super.visitFALOAD();
148         --currentStackDepth;
149     }
150     public void visitAALOAD() {
151         super.visitAALOAD();
152         --currentStackDepth;
153     }
154     public void visitBALOAD() {
155         super.visitBALOAD();
156         --currentStackDepth;
157     }
158     public void visitCALOAD() {
159         super.visitCALOAD();
160         --currentStackDepth;
161     }
162     public void visitSALOAD() {
163         super.visitSALOAD();
164         --currentStackDepth;
165     }
166     public void visitIASTORE() {
167         super.visitIASTORE();
168         currentStackDepth-=3;
169     }
170     public void visitLASTORE() {
171         super.visitLASTORE();
172         currentStackDepth-=4;
173     }
174     public void visitFASTORE() {
175         super.visitFASTORE();
176         currentStackDepth-=3;
177     }
178     public void visitDASTORE() {
179         super.visitDASTORE();
180         currentStackDepth-=4;
181     }
182     public void visitAASTORE() {
183         super.visitAASTORE();
184         currentStackDepth-=3;
185     }
186     public void visitBASTORE() {
187         super.visitBASTORE();
188         currentStackDepth-=3;
189     }
190     public void visitCASTORE() {
191         super.visitCASTORE();
192         currentStackDepth-=3;
193     }
194     public void visitSASTORE() {
195         super.visitSASTORE();
196         currentStackDepth-=3;
197     }
198     public void visitPOP() {
199         super.visitPOP();
200         --currentStackDepth;
201     }
202     public void visitPOP2() {
203         super.visitPOP2();
204         currentStackDepth-=2;
205     }
206     public void visitDUP() {
207         super.visitDUP();
208         ++currentStackDepth;
209     }
210     public void visitDUP_x1() {
211         super.visitDUP_x1();
212         ++currentStackDepth;
213     }
214     public void visitDUP_x2() {
215         super.visitDUP_x2();
216         ++currentStackDepth;
217     }
218     public void visitDUP2() {
219         super.visitDUP2();
220         currentStackDepth+=2;
221     }
222     public void visitDUP2_x1() {
223         super.visitDUP2_x1();
224         currentStackDepth+=2;
225     }
226     public void visitDUP2_x2() {
227         super.visitDUP2_x2();
228         currentStackDepth+=2;
229     }
230     public void visitIBINOP(byte op) {
231         super.visitIBINOP(op);
232         --currentStackDepth;
233     }
234     public void visitLBINOP(byte op) {
235         super.visitLBINOP(op);
236         currentStackDepth-=2;
237     }
238     public void visitFBINOP(byte op) {
239         super.visitFBINOP(op);
240         --currentStackDepth;
241     }
242     public void visitDBINOP(byte op) {
243         super.visitDBINOP(op);
244         currentStackDepth-=2;
245     }
246     public void visitISHIFT(byte op) {
247         super.visitISHIFT(op);
248         --currentStackDepth;
249     }
250     public void visitLSHIFT(byte op) {
251         super.visitLSHIFT(op);
252         --currentStackDepth;
253     }
254     public void visitI2L() {
255         super.visitI2L();
256         ++currentStackDepth;
257     }
258     public void visitI2D() {
259         super.visitI2D();
260         ++currentStackDepth;
261     }
262     public void visitL2I() {
263         super.visitL2I();
264         --currentStackDepth;
265     }
266     public void visitL2F() {
267         super.visitL2F();
268         --currentStackDepth;
269     }
270     public void visitF2L() {
271         super.visitF2L();
272         ++currentStackDepth;
273     }
274     public void visitF2D() {
275         super.visitF2D();
276         ++currentStackDepth;
277     }
278     public void visitD2I() {
279         super.visitD2I();
280         --currentStackDepth;
281     }
282     public void visitD2F() {
283         super.visitD2F();
284         --currentStackDepth;
285     }
286     public void visitLCMP2() {
287         super.visitLCMP2();
288         currentStackDepth-=3;
289     }
290     public void visitFCMP2(byte op) {
291         super.visitFCMP2(op);
292         --currentStackDepth;
293     }
294     public void visitDCMP2(byte op) {
295         super.visitDCMP2(op);
296         currentStackDepth-=3;
297     }
298     public void visitIF(byte op, int target) {
299         super.visitIF(op, target);
300         --currentStackDepth;
301     }
302     public void visitIFREF(byte op, int target) {
303         super.visitIFREF(op, target);
304         --currentStackDepth;
305     }
306     public void visitIFCMP(byte op, int target) {
307         super.visitIFCMP(op, target);
308         currentStackDepth-=2;
309     }
310     public void visitIFREFCMP(byte op, int target) {
311         super.visitIFREFCMP(op, target);
312         currentStackDepth-=2;
313     }
314     public void visitJSR(int target) {
315         super.visitJSR(target);
316         ++currentStackDepth;
317     }
318     public void visitTABLESWITCH(int default_target, int low, int high, int[] targets) {
319         super.visitTABLESWITCH(default_target, low, high, targets);
320         --currentStackDepth;
321     }
322     public void visitLOOKUPSWITCH(int default_target, int[] values, int[] targets) {
323         super.visitLOOKUPSWITCH(default_target, values, targets);
324         --currentStackDepth;
325     }
326     public void visitIRETURN() {
327         super.visitIRETURN();
328         currentStackDepth=0;
329     }
330     public void visitLRETURN() {
331         super.visitLRETURN();
332         currentStackDepth=0;
333     }
334     public void visitFRETURN() {
335         super.visitFRETURN();
336         currentStackDepth=0;
337     }
338     public void visitDRETURN() {
339         super.visitDRETURN();
340         currentStackDepth=0;
341     }
342     public void visitARETURN() {
343         super.visitARETURN();
344         currentStackDepth=0;
345     }
346     public void visitVRETURN() {
347         super.visitVRETURN();
348         currentStackDepth=0;
349     }
350     public void visitIGETSTATIC(jq_StaticField f) {
351         super.visitIGETSTATIC(f);
352         ++currentStackDepth;
353     }
354     public void visitLGETSTATIC(jq_StaticField f) {
355         super.visitLGETSTATIC(f);
356         currentStackDepth+=2;
357     }
358     public void visitFGETSTATIC(jq_StaticField f) {
359         super.visitFGETSTATIC(f);
360         ++currentStackDepth;
361     }
362     public void visitDGETSTATIC(jq_StaticField f) {
363         super.visitDGETSTATIC(f);
364         currentStackDepth+=2;
365     }
366     public void visitAGETSTATIC(jq_StaticField f) {
367         super.visitAGETSTATIC(f);
368         ++currentStackDepth;
369     }
370     public void visitZGETSTATIC(jq_StaticField f) {
371         super.visitZGETSTATIC(f);
372         ++currentStackDepth;
373     }
374     public void visitBGETSTATIC(jq_StaticField f) {
375         super.visitBGETSTATIC(f);
376         ++currentStackDepth;
377     }
378     public void visitCGETSTATIC(jq_StaticField f) {
379         super.visitCGETSTATIC(f);
380         ++currentStackDepth;
381     }
382     public void visitSGETSTATIC(jq_StaticField f) {
383         super.visitSGETSTATIC(f);
384         ++currentStackDepth;
385     }
386     public void visitIPUTSTATIC(jq_StaticField f) {
387         super.visitIPUTSTATIC(f);
388         --currentStackDepth;
389     }
390     public void visitLPUTSTATIC(jq_StaticField f) {
391         super.visitLPUTSTATIC(f);
392         currentStackDepth-=2;
393     }
394     public void visitFPUTSTATIC(jq_StaticField f) {
395         super.visitFPUTSTATIC(f);
396         --currentStackDepth;
397     }
398     public void visitDPUTSTATIC(jq_StaticField f) {
399         super.visitDPUTSTATIC(f);
400         currentStackDepth-=2;
401     }
402     public void visitAPUTSTATIC(jq_StaticField f) {
403         super.visitAPUTSTATIC(f);
404         --currentStackDepth;
405     }
406     public void visitZPUTSTATIC(jq_StaticField f) {
407         super.visitZPUTSTATIC(f);
408         --currentStackDepth;
409     }
410     public void visitBPUTSTATIC(jq_StaticField f) {
411         super.visitBPUTSTATIC(f);
412         --currentStackDepth;
413     }
414     public void visitCPUTSTATIC(jq_StaticField f) {
415         super.visitCPUTSTATIC(f);
416         --currentStackDepth;
417     }
418     public void visitSPUTSTATIC(jq_StaticField f) {
419         super.visitSPUTSTATIC(f);
420         --currentStackDepth;
421     }
422     public void visitLGETFIELD(jq_InstanceField f) {
423         super.visitLGETFIELD(f);
424         ++currentStackDepth;
425     }
426     public void visitDGETFIELD(jq_InstanceField f) {
427         super.visitDGETFIELD(f);
428         ++currentStackDepth;
429     }
430     public void visitIPUTFIELD(jq_InstanceField f) {
431         super.visitIPUTFIELD(f);
432         currentStackDepth-=2;
433     }
434     public void visitLPUTFIELD(jq_InstanceField f) {
435         super.visitLPUTFIELD(f);
436         currentStackDepth-=3;
437     }
438     public void visitFPUTFIELD(jq_InstanceField f) {
439         super.visitFPUTFIELD(f);
440         currentStackDepth-=2;
441     }
442     public void visitDPUTFIELD(jq_InstanceField f) {
443         super.visitDPUTFIELD(f);
444         currentStackDepth-=3;
445     }
446     public void visitAPUTFIELD(jq_InstanceField f) {
447         super.visitAPUTFIELD(f);
448         currentStackDepth-=2;
449     }
450     public void visitBPUTFIELD(jq_InstanceField f) {
451         super.visitBPUTFIELD(f);
452         currentStackDepth-=2;
453     }
454     public void visitCPUTFIELD(jq_InstanceField f) {
455         super.visitCPUTFIELD(f);
456         currentStackDepth-=2;
457     }
458     public void visitSPUTFIELD(jq_InstanceField f) {
459         super.visitSPUTFIELD(f);
460         currentStackDepth-=2;
461     }
462     public void visitZPUTFIELD(jq_InstanceField f) {
463         super.visitZPUTFIELD(f);
464         currentStackDepth-=2;
465     }
466     public void visitIINVOKE(byte op, jq_Method f) {
467         super.visitIINVOKE(op, f);
468         currentStackDepth-=f.getParamWords()-1;
469     }
470     public void visitLINVOKE(byte op, jq_Method f) {
471         super.visitLINVOKE(op, f);
472         currentStackDepth-=f.getParamWords()-2;
473     }
474     public void visitFINVOKE(byte op, jq_Method f) {
475         super.visitFINVOKE(op, f);
476         currentStackDepth-=f.getParamWords()-1;
477     }
478     public void visitDINVOKE(byte op, jq_Method f) {
479         super.visitDINVOKE(op, f);
480         currentStackDepth-=f.getParamWords()-2;
481     }
482     public void visitAINVOKE(byte op, jq_Method f) {
483         super.visitAINVOKE(op, f);
484         currentStackDepth-=f.getParamWords()-1;
485     }
486     public void visitVINVOKE(byte op, jq_Method f) {
487         super.visitVINVOKE(op, f);
488         currentStackDepth-=f.getParamWords();
489     }
490     public void visitNEW(jq_Type f) {
491         super.visitNEW(f);
492         ++currentStackDepth;
493     }
494     public void visitATHROW() {
495         super.visitATHROW();
496         currentStackDepth=0;
497     }
498     public void visitMONITOR(byte op) {
499         super.visitMONITOR(op);
500         --currentStackDepth;
501     }
502     public void visitMULTINEWARRAY(jq_Type f, char dim) {
503         super.visitMULTINEWARRAY(f, dim);
504         currentStackDepth-=dim-1;
505     }
506 
507 }