1
2
3
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
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
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 }