View Javadoc

1   /*
2    *
3    */
4   package org.softevo.jdynpur.runtime;
5   
6   import org.objectweb.asm.Label;
7   import org.objectweb.asm.MethodAdapter;
8   import org.objectweb.asm.MethodVisitor;
9   import org.objectweb.asm.Opcodes;
10  
11  public class ObjectCreationTracingVisitor extends MethodAdapter implements Opcodes {
12  
13  	/**
14  	 * The class is in this state if, during bytecode processing, we did not
15  	 * recently encounter a new instruction.
16  	 */
17  	public static final int ST_DEFAULT = 0;
18  
19  	/**
20  	 * Last visited instruction was a new instruction.
21  	 */
22  	public static final int ST_NEW = 1;
23  
24  	/**
25  	 * Last but one instruction was new, last instruction <code>dup_x1</code>.
26  	 */
27  	public static final int ST_DUPX1 = 2;
28  
29  	/**
30  	 * Current state of the visitor.
31  	 */
32  	private int state = ST_DEFAULT;
33  
34  	protected int newInstructionCounter = 0;
35  
36  	public ObjectCreationTracingVisitor(MethodVisitor visitor) {
37  		super(visitor);
38  	}
39  
40  	@Override
41  	public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {
42  		handleStateReset();
43  		super.visitFieldInsn(arg0, arg1, arg2, arg3);
44  	}
45  
46  	@Override
47  	public void visitIincInsn(int arg0, int arg1) {
48  		handleStateReset();
49  		super.visitIincInsn(arg0, arg1);
50  	}
51  
52  	@Override
53  	public void visitInsn(int opCode) {
54  		if (state == ST_NEW) {
55  			if (opCode == DUP_X1) {
56  				state = ST_DUPX1;
57  			} else {
58  				handleStateReset();
59  				super.visitInsn(opCode);
60  			}
61  		} else if (state == ST_DUPX1) {
62  			if (opCode == SWAP) {
63  				super.visitInsn(DUP_X1);
64  				super.visitInsn(DUP_X1);
65  				super.visitInsn(SWAP);
66  				state = ST_DEFAULT;
67  			} else {
68  				handleStateReset();
69  				super.visitInsn(opCode);
70  			}
71  		} else {
72  			// default case!
73  			super.visitInsn(opCode);
74  		}
75  	}
76  
77  	@Override
78  	public void visitIntInsn(int arg0, int arg1) {
79  		handleStateReset();
80  		super.visitIntInsn(arg0, arg1);
81  	}
82  
83  	@Override
84  	public void visitJumpInsn(int arg0, Label arg1) {
85  		handleStateReset();
86  		super.visitJumpInsn(arg0, arg1);
87  	}
88  
89  	@Override
90  	public void visitLdcInsn(Object arg0) {
91  		handleStateReset();
92  		super.visitLdcInsn(arg0);
93  	}
94  
95  	@Override
96  	public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {
97  		handleStateReset();
98  		super.visitLookupSwitchInsn(arg0, arg1, arg2);
99  	}
100 
101 	@Override
102 	public void visitMethodInsn(int access, String className, String methodName, String desc) {
103 		handleStateReset();
104 		super.visitMethodInsn(access, className, methodName, desc);
105 		if (methodName.equals("<init>")) {
106 			if (newInstructionCounter > 0) {
107 				newInstructionCounter--;
108 				super.visitMethodInsn(INVOKESTATIC, OnTheFlyInstrumenter.TRACECLASSNAME, "objectCreated",
109 															"(Ljava/lang/Object;)V");
110 			}
111 		}
112 	}
113 
114 	@Override
115 	public void visitMultiANewArrayInsn(String arg0, int arg1) {
116 		handleStateReset();
117 		super.visitMultiANewArrayInsn(arg0, arg1);
118 	}
119 
120 	@Override
121 	public void visitTableSwitchInsn(int arg0, int arg1, Label arg2, Label[] arg3) {
122 		handleStateReset();
123 		super.visitTableSwitchInsn(arg0, arg1, arg2, arg3);
124 	}
125 
126 	@Override
127 	public void visitTypeInsn(int opCode, String typeDesc) {
128 		if (opCode == NEW) {
129 			newInstructionCounter++;
130 			handleStateReset();
131 			state = ST_NEW;
132 		} else {
133 			handleStateReset();
134 		}
135 		super.visitTypeInsn(opCode, typeDesc);
136 	}
137 
138 	@Override
139 	public void visitVarInsn(int arg0, int arg1) {
140 		handleStateReset();
141 		super.visitVarInsn(arg0, arg1);
142 	}
143 
144 	protected void handleStateReset() {
145 		if (state == ST_NEW) {
146 			super.visitInsn(DUP);
147 		} else if (state == ST_DUPX1) {
148 			super.visitInsn(DUP);
149 			super.visitInsn(DUP_X1);
150 		}
151 		state = ST_DEFAULT;
152 	}
153 
154 	protected void superVisitMethodInsn(int access, String className, String methodName, String desc) {
155 		super.visitMethodInsn(access, className, methodName, desc);
156 	}
157 	
158 	/*
159 	 * @Override public void visitLabel(Label label) { System.out.println("visit
160 	 * label called"); if (labels.getDupLabels().contains(label)) {
161 	 * System.out.println("dup"); super.visitInsn(DUP); } else if
162 	 * (labels.getDupX1Labels().contains(label)) { System.out.println("dup_x1");
163 	 * super.visitInsn(DUP_X1); } else if
164 	 * (labels.getConstructorLabels().contains(label)) {
165 	 * System.out.println("constructor");
166 	 * super.visitMethodInsn(INVOKESTATIC,OnTheFlyInstrumenter.TRACECLASSNAME,
167 	 * "objectCreated", "(Ljava/lang/Object;)V"); } else {
168 	 * super.visitLabel(label); } }
169 	 */
170 
171 }