1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package net.sf.jour.instrumentor;
22
23 import org.apache.log4j.Logger;
24
25 import javassist.CannotCompileException;
26 import javassist.*;
27 import javassist.CtConstructor;
28 import javassist.CtMethod;
29 import javassist.CtNewMethod;
30 import javassist.NotFoundException;
31 import javassist.bytecode.CodeAttribute;
32
33 import net.sf.jour.InterceptorException;
34 import net.sf.jour.rt.agent.InstrumentationMap;
35
36 /***
37 * TODO add docs
38 *
39 * Created on 02.12.2004
40 *
41 * Contributing Author(s):
42 *
43 * Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
44 * Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
45 *
46 * @author michaellif
47 * @version $Revision: 1.12 $ ($Author: vlads $) $Date: 2004/12/13 06:19:10 $
48 */
49
50 public class ProfilerInstrumentor extends AbstractInstrumentor implements InstrumentorConsts {
51
52 protected static final Logger log = Logger.getLogger(ProfilerInstrumentor.class);
53
54 /***
55 * DOCUMENT ME!
56 *
57 * @param clazz
58 * DOCUMENT ME!
59 *
60 * @throws InterceptorException
61 * DOCUMENT ME!
62 */
63 public boolean instrumentClass(CtClass clazz) throws InterceptorException {
64 try {
65
66 return false;
67 } catch (Exception e) {
68 e.printStackTrace();
69 throw new InterceptorException("Failed to add finalize() to class " + clazz);
70 }
71 }
72
73 public boolean instrumentMethod(CtClass clazz, CtMethod method) throws InterceptorException {
74 return addEvents(method);
75 }
76
77 public boolean instrumentConstructor(CtClass clazz, CtConstructor constructor)
78 throws InterceptorException {
79
80 return false;
81 }
82
83 public String getMapedEventID(CtBehavior behavior, long id) {
84 StringBuffer code = new StringBuffer();
85 code.append("\n new net.sf.jour.rt.agent.MapedEventID((long)");
86 code.append(id);
87 code.append(")");
88 return code.toString();
89 }
90
91 private boolean addEvents(CtBehavior behavior) throws InterceptorException {
92 try {
93 CodeAttribute ca = behavior.getMethodInfo().getCodeAttribute();
94 if (ca == null) {
95 return false;
96 }
97 if (log.isDebugEnabled()) {
98 log.debug("instrument " + behavior.getDeclaringClass().getName() + "->" + behavior.getName() + behavior.getSignature());
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 final boolean useEmptyEvent = false;
123
124 final boolean useTry = false;
125
126 StringBuffer commonCode = new StringBuffer();
127 if (useTry) {
128 commonCode.append("try {");
129 }
130 commonCode.append("\nif (net.sf.jour.rt.agent.Elog.ON) {\n");
131 commonCode.append("net.sf.jour.rt.agent.Elog.logEvent(");
132 if (useEmptyEvent) {
133 commonCode.append(" new net.sf.jour.rt.agent.EmptyEvent(");
134 } else {
135 commonCode.append(" new net.sf.jour.rt.agent.ProfilerEvent(\n");
136 commonCode.append(" net.sf.jour.rt.agent.ProfilerEvent.");
137 }
138
139
140 long id = InstrumentationMap.instance().getID(behavior.getDeclaringClass().getName(), behavior.getName(), behavior.getSignature());
141
142 StringBuffer commonCodeEnd = new StringBuffer();
143 if (!useEmptyEvent) {
144 commonCodeEnd.append(getMapedEventID(behavior, id));
145 }
146 commonCodeEnd.append("));\n}");
147 if (useTry) {
148 commonCodeEnd.append("} catch(Throwable t) {};");
149 }
150
151 StringBuffer codeBefore = new StringBuffer();
152 StringBuffer codeAfter = new StringBuffer();
153 StringBuffer codeCatch = new StringBuffer();
154
155 codeBefore.append(commonCode.toString());
156 if (!useEmptyEvent) {
157 codeBefore.append("START, null, ");
158 }
159 codeBefore.append(commonCodeEnd.toString());
160
161 codeAfter.append(commonCode.toString());
162 if (!useEmptyEvent) {
163 codeAfter.append("END, null, ");
164 }
165 codeAfter.append(commonCodeEnd.toString());
166
167 codeCatch.append(commonCode.toString());
168 if (!useEmptyEvent) {
169 codeCatch.append("END, $e,");
170 }
171 codeCatch.append(commonCodeEnd.toString());
172 codeCatch.append("throw $e;\n");
173
174 try {
175 behavior.insertBefore(codeBefore.toString());
176 } catch (Exception be) {
177 log.debug(codeBefore);
178 throw be;
179 } catch (Error be) {
180 log.debug(codeBefore);
181 throw be;
182 }
183
184 try {
185 behavior.insertAfter(codeAfter.toString());
186 } catch (Exception be) {
187 log.debug(codeAfter);
188 throw be;
189 } catch (Error ae) {
190 log.debug(codeAfter);
191 throw ae;
192 }
193
194 try {
195 behavior.addCatch(codeCatch.toString(), ClassPool.getDefault().get("java.lang.Throwable"));
196 } catch (Error ce) {
197 log.debug(codeCatch);
198 throw ce;
199 }
200
201 return true;
202
203 } catch (Error e) {
204 log.error("Profiler error", e);
205 throw e;
206 } catch (Exception e) {
207 log.error("Profiler error", e);
208 throw new InterceptorException("Failed to add profiler events to " + behavior.getName());
209 }
210 }
211
212 private boolean addFinalize(CtClass clazz) throws CannotCompileException, NotFoundException {
213 CtMethod finalize;
214 CtMethod[] mArray = clazz.getDeclaredMethods();
215 for (int i = 0; i < mArray.length; i++) {
216 if (mArray[i].getName().equals("finalize")
217 && (mArray[i].getParameterTypes().length == 0)) {
218 return false;
219 }
220 }
221 StringBuffer code = new StringBuffer();
222 code.append("protected void finalize() throws Throwable { super.finalize(); }");
223 finalize = CtNewMethod.make(code.toString(), clazz);
224 clazz.addMethod(finalize);
225 return true;
226 }
227
228 }