001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.instrumentation;
042:
043: import org.netbeans.lib.profiler.global.CommonConstants;
044: import org.netbeans.lib.profiler.instrumentation.ConstantPoolExtension.CPEntry;
045: import org.netbeans.lib.profiler.instrumentation.ConstantPoolExtension.PackedCPFragment;
046:
047: /**
048: * A repository containing semi-prepared constant pool fragments for all kinds of instrumentation used in JFluid.
049: *
050: * @author Tomas Hurka
051: * @author Misha Dmitriev
052: */
053: public class CPExtensionsRepository implements JavaClassConstants,
054: CommonConstants {
055: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
056:
057: // These indices, adjusted properly for the base constant pool length for a given class, should be used as cpool indices
058: // of various methods injected into the target app methods.
059: public static int normalContents_MethodEntryMethodIdx;
060:
061: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
062:
063: // These indices, adjusted properly for the base constant pool length for a given class, should be used as cpool indices
064: // of various methods injected into the target app methods.
065: public static int normalContents_MethodExitMethodIdx;
066: public static int normalContents_ProfilePointHitMethodIdx;
067: public static int rootContents_RootEntryMethodIdx;
068: public static int rootContents_MarkerEntryMethodIdx;
069: public static int rootContents_MarkerExitMethodIdx;
070: public static int miContents_HandleReflectInvokeMethodIdx;
071: public static int miContents_HandleServletDoMethodIdx;
072: public static int codeRegionContents_CodeRegionEntryMethodIdx;
073: public static int codeRegionContents_CodeRegionExitMethodIdx;
074: public static int memoryProfContents_ProfilePointHitMethodIdx;
075: public static int memoryProfContents_TraceObjAllocMethodIdx; // Make sure it's the same for Obj Allocation and Obj Liveness, otherwise will have to change dependent code
076:
077: //------------------------------------ Private implementation -----------------------------------------------
078:
079: // Names and signatures of methods, calls to which we inject into TA code
080: private static final String PROFRUNTIME_CPU_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeCPU"; // NOI18N
081: private static final String PROFRUNTIME_CPUFULL_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeCPUFullInstr"; // NOI18N
082: private static final String PROFRUNTIME_CPUSAMPLED_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeCPUSampledInstr"; // NOI18N
083: private static final String PROFRUNTIME_CPUCODEREGION_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeCPUCodeRegion"; // NOI18N
084: private static final String PROFRUNTIME_OBJALLOC_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeObjAlloc"; // NOI18N
085: private static final String PROFRUNTIME_OBJLIVENESS_CLASS_NAME = "org/netbeans/lib/profiler/server/ProfilerRuntimeObjLiveness"; // NOI18N
086: private static final String ROOT_ENTRY_METHOD_NAME = "rootMethodEntry"; // NOI18N
087: private static final String MARKER_ENTRY_METHOD_NAME = "markerMethodEntry"; // NOI18N
088: private static final String MARKER_EXIT_METHOD_NAME = "markerMethodExit"; // NOI18N
089: private static final String METHOD_ENTRY_METHOD_NAME = "methodEntry"; // NOI18N
090: private static final String METHOD_EXIT_METHOD_NAME = "methodExit"; // NOI18N
091: private static final String HANDLE_REFLECT_INVOKE_METHOD_NAME = "handleJavaLangReflectMethodInvoke"; // NOI18N
092: private static final String CODE_REGION_ENTRY_METHOD_NAME = "codeRegionEntry"; // NOI18N
093: private static final String CODE_REGION_EXIT_METHOD_NAME = "codeRegionExit"; // NOI18N
094: private static final String TRACE_OBJ_ALLOC_METHOD_NAME = "traceObjAlloc"; // NOI18N
095: private static final String PROFILE_POINT_HIT = "profilePointHit"; // NOI18N
096: private static final String HANDLE_SERVLET_DO_METHOD_NAME = "handleServletDoMethod"; // NOI18N
097: private static final String VOID_VOID_SIGNATURE = "()V"; // NOI18N
098: private static final String CHAR_VOID_SIGNATURE = "(C)V"; // NOI18N
099: private static final String VOID_OBJECT_SIGNATURE = "(Ljava/lang/Object;)V"; // NOI18N
100: private static final String OBJECT_CHAR_VOID_SIGNATURE = "(Ljava/lang/Object;C)V"; // NOI18N
101: private static final String REFLECT_METHOD_VOID_SIGNATURE = "(Ljava/lang/reflect/Method;)V"; // NOI18N
102: private static final String OBJECT_CHAR_BOOLEAN_VOID_SIGNATURE = "(Ljava/lang/Object;CZ)V"; // NOI18N
103: private static final String JAVA_LANG_THROWABLE_NAME = "java/lang/Throwable"; // NOI18N
104:
105: // Predefined constant pools for various kinds of instrumentation
106: private static PackedCPFragment[] standardCPFragments;
107:
108: static {
109: initCommonAddedContents();
110: }
111:
112: //~ Methods ------------------------------------------------------------------------------------------------------------------
113:
114: public static PackedCPFragment getStandardCPFragment(
115: int injectionType) {
116: return standardCPFragments[injectionType];
117: }
118:
119: // Create standard added cpool contents for each injection kind defined by JFluid.
120: private static void initCommonAddedContents() {
121: standardCPFragments = new PackedCPFragment[INJ_MAXNUMBER];
122:
123: // Initialize the "normal" recursive instrumentation added constant pool contents
124: CPEntry[] entries = new CPEntry[12];
125: int i = -1;
126: entries[++i] = new CPEntry(CHAR_VOID_SIGNATURE);
127:
128: int charVoidSignatureIdx = i;
129: entries[++i] = new CPEntry(CONSTANT_Class);
130:
131: int profilerRuntimeClassRefIdx = i;
132: entries[++i] = new CPEntry(PROFRUNTIME_CPUFULL_CLASS_NAME);
133:
134: int profilerRuntimeClassNameIdx = i;
135: entries[profilerRuntimeClassRefIdx].setIndex1(i);
136: entries[++i] = new CPEntry(CONSTANT_Methodref);
137: entries[i].setIndex1(profilerRuntimeClassRefIdx);
138:
139: int methodEntryMethodRefIdx = i;
140: entries[++i] = new CPEntry(CONSTANT_NameAndType);
141: entries[methodEntryMethodRefIdx].setIndex2(i);
142:
143: int methodEntryNameAndTypeIdx = i;
144: entries[++i] = new CPEntry(METHOD_ENTRY_METHOD_NAME);
145: entries[methodEntryNameAndTypeIdx].setIndex1(i);
146: entries[methodEntryNameAndTypeIdx]
147: .setIndex2(charVoidSignatureIdx);
148:
149: entries[++i] = new CPEntry(CONSTANT_Methodref);
150: entries[i].setIndex1(profilerRuntimeClassRefIdx);
151:
152: int methodExitMethodRefIdx = i;
153: entries[++i] = new CPEntry(CONSTANT_NameAndType);
154: entries[methodExitMethodRefIdx].setIndex2(i);
155:
156: int methodExitNameAndTypeIdx = i;
157: entries[++i] = new CPEntry(METHOD_EXIT_METHOD_NAME);
158: entries[methodExitNameAndTypeIdx].setIndex1(i);
159: entries[methodExitNameAndTypeIdx]
160: .setIndex2(charVoidSignatureIdx);
161:
162: entries[++i] = new CPEntry(CONSTANT_Methodref);
163: entries[i].setIndex1(profilerRuntimeClassRefIdx);
164:
165: int profilePointHitMethodRefIdx = i;
166: entries[++i] = new CPEntry(CONSTANT_NameAndType);
167: entries[profilePointHitMethodRefIdx].setIndex2(i);
168:
169: int profilePointHitNameAndTypeIdx = i;
170: entries[++i] = new CPEntry(PROFILE_POINT_HIT);
171: entries[profilePointHitNameAndTypeIdx].setIndex1(i);
172: entries[profilePointHitNameAndTypeIdx]
173: .setIndex2(charVoidSignatureIdx);
174: normalContents_ProfilePointHitMethodIdx = profilePointHitMethodRefIdx;
175:
176: standardCPFragments[INJ_RECURSIVE_NORMAL_METHOD] = new PackedCPFragment(
177: entries);
178: normalContents_MethodEntryMethodIdx = methodEntryMethodRefIdx;
179: normalContents_MethodExitMethodIdx = methodExitMethodRefIdx;
180:
181: // Create cpool contents for "sampled instrumentation" code injection, by replacing just
182: // the instrumentation class name
183: entries[profilerRuntimeClassNameIdx] = new CPEntry(
184: PROFRUNTIME_CPUSAMPLED_CLASS_NAME);
185: standardCPFragments[INJ_RECURSIVE_SAMPLED_NORMAL_METHOD] = new PackedCPFragment(
186: entries);
187:
188: // Additional constant pool contents for rootEntry(char methodId) injection
189: entries = new CPEntry[3];
190: i = -1;
191: entries[++i] = new CPEntry(CONSTANT_Methodref);
192: entries[i].setIndex1(profilerRuntimeClassRefIdx + 0x10000);
193:
194: int rootEntryMethodRefIdx = i;
195: entries[++i] = new CPEntry(CONSTANT_NameAndType);
196: entries[rootEntryMethodRefIdx].setIndex2(i);
197:
198: int rootEntryNameAndTypeIdx = i;
199: entries[++i] = new CPEntry(ROOT_ENTRY_METHOD_NAME);
200: entries[rootEntryNameAndTypeIdx].setIndex1(i);
201: entries[rootEntryNameAndTypeIdx]
202: .setIndex2(charVoidSignatureIdx + 0x10000);
203:
204: standardCPFragments[INJ_RECURSIVE_ROOT_METHOD] = new PackedCPFragment(
205: entries);
206: rootContents_RootEntryMethodIdx = rootEntryMethodRefIdx;
207:
208: // rootEntry() injection for sampled instrumentation is the same as for full instrumentation
209: standardCPFragments[INJ_RECURSIVE_SAMPLED_ROOT_METHOD] = new PackedCPFragment(
210: entries);
211:
212: // Additional constant pool contents for markerMethodEntry(char methodId) and markerMethodExit(char methodId) injection
213: entries = new CPEntry[6];
214: i = -1;
215: entries[++i] = new CPEntry(CONSTANT_Methodref);
216: entries[i].setIndex1(profilerRuntimeClassRefIdx + 0x10000);
217:
218: int markerEntryMethodRefIdx = i;
219: entries[++i] = new CPEntry(CONSTANT_NameAndType);
220: entries[markerEntryMethodRefIdx].setIndex2(i);
221:
222: int markerEntryNameAndTypeIdx = i;
223: entries[++i] = new CPEntry(MARKER_ENTRY_METHOD_NAME);
224: entries[markerEntryNameAndTypeIdx].setIndex1(i);
225: entries[markerEntryNameAndTypeIdx]
226: .setIndex2(charVoidSignatureIdx + 0x10000);
227:
228: entries[++i] = new CPEntry(CONSTANT_Methodref);
229: entries[i].setIndex1(profilerRuntimeClassRefIdx + 0x10000);
230:
231: int markerExitMethodRefIdx = i;
232: entries[++i] = new CPEntry(CONSTANT_NameAndType);
233: entries[markerExitMethodRefIdx].setIndex2(i);
234:
235: int markerExitNameAndTypeIdx = i;
236: entries[++i] = new CPEntry(MARKER_EXIT_METHOD_NAME);
237: entries[markerExitNameAndTypeIdx].setIndex1(i);
238: entries[markerExitNameAndTypeIdx]
239: .setIndex2(charVoidSignatureIdx + 0x10000);
240:
241: standardCPFragments[INJ_RECURSIVE_MARKER_METHOD] = new PackedCPFragment(
242: entries);
243: rootContents_MarkerEntryMethodIdx = markerEntryMethodRefIdx;
244: rootContents_MarkerExitMethodIdx = markerExitMethodRefIdx;
245:
246: // markerMethodEntry() injection for sampled instrumentation is the same as for full instrumentation
247: standardCPFragments[INJ_RECURSIVE_SAMPLED_MARKER_METHOD] = new PackedCPFragment(
248: entries);
249:
250: // Now initialize the constant pool contents added to class java.lang.reflect.Method, to support invoke() instrumentation
251: entries = new CPEntry[6];
252: i = -1;
253: entries[++i] = new CPEntry(REFLECT_METHOD_VOID_SIGNATURE);
254:
255: int methodSignatureIdx = i;
256: entries[++i] = new CPEntry(CONSTANT_Class);
257: profilerRuntimeClassRefIdx = i;
258: entries[++i] = new CPEntry(PROFRUNTIME_CPU_CLASS_NAME);
259: entries[profilerRuntimeClassRefIdx].setIndex1(i);
260: entries[++i] = new CPEntry(CONSTANT_Methodref);
261: entries[i].setIndex1(profilerRuntimeClassRefIdx);
262:
263: int methodRefIdx = i;
264: entries[++i] = new CPEntry(CONSTANT_NameAndType);
265: entries[methodRefIdx].setIndex2(i);
266:
267: int nameAndTypeIdx = i;
268: entries[++i] = new CPEntry(HANDLE_REFLECT_INVOKE_METHOD_NAME);
269: entries[nameAndTypeIdx].setIndex1(i);
270: entries[nameAndTypeIdx].setIndex2(methodSignatureIdx);
271:
272: standardCPFragments[INJ_REFLECT_METHOD_INVOKE] = new PackedCPFragment(
273: entries);
274: miContents_HandleReflectInvokeMethodIdx = methodRefIdx;
275:
276: // Now initialize the constant pool contents added to class javax.servlet.http.HttpServlet ,
277: // to support doGet(), doPost(), doPut(), doDelete() servlet tracking
278: entries = new CPEntry[6];
279: i = -1;
280: entries[++i] = new CPEntry(VOID_OBJECT_SIGNATURE);
281:
282: int servetSignatureIdx = i;
283: entries[++i] = new CPEntry(CONSTANT_Class);
284: profilerRuntimeClassRefIdx = i;
285: entries[++i] = new CPEntry(PROFRUNTIME_CPU_CLASS_NAME);
286: entries[profilerRuntimeClassRefIdx].setIndex1(i);
287: entries[++i] = new CPEntry(CONSTANT_Methodref);
288: entries[i].setIndex1(profilerRuntimeClassRefIdx);
289:
290: int servletRefIdx = i;
291: entries[++i] = new CPEntry(CONSTANT_NameAndType);
292: entries[servletRefIdx].setIndex2(i);
293:
294: int servletNameAndTypeIdx = i;
295: entries[++i] = new CPEntry(HANDLE_SERVLET_DO_METHOD_NAME);
296: entries[servletNameAndTypeIdx].setIndex1(i);
297: entries[servletNameAndTypeIdx].setIndex2(servetSignatureIdx);
298:
299: standardCPFragments[INJ_SERVLET_DO_METHOD] = new PackedCPFragment(
300: entries);
301: miContents_HandleServletDoMethodIdx = servletRefIdx;
302:
303: // Initialize the constant pool contents used for code region profiling.
304: entries = new CPEntry[9];
305: i = -1;
306: entries[++i] = new CPEntry(VOID_VOID_SIGNATURE);
307:
308: int voidVoidSignatureIdx = i;
309: entries[++i] = new CPEntry(CONSTANT_Class);
310: profilerRuntimeClassRefIdx = i;
311: entries[++i] = new CPEntry(PROFRUNTIME_CPUCODEREGION_CLASS_NAME);
312: entries[profilerRuntimeClassRefIdx].setIndex1(i);
313: entries[++i] = new CPEntry(CONSTANT_Methodref);
314: entries[i].setIndex1(profilerRuntimeClassRefIdx);
315:
316: int codeRegionEntryMethodRefIdx = i;
317: entries[++i] = new CPEntry(CONSTANT_NameAndType);
318: entries[codeRegionEntryMethodRefIdx].setIndex2(i);
319:
320: int codeRegionEntryNameAndTypeIdx = i;
321: entries[++i] = new CPEntry(CODE_REGION_ENTRY_METHOD_NAME);
322: entries[codeRegionEntryNameAndTypeIdx].setIndex1(i);
323: entries[codeRegionEntryNameAndTypeIdx]
324: .setIndex2(voidVoidSignatureIdx);
325:
326: entries[++i] = new CPEntry(CONSTANT_Methodref);
327: entries[i].setIndex1(profilerRuntimeClassRefIdx);
328:
329: int codeRegionExitMethodRefIdx = i;
330: entries[++i] = new CPEntry(CONSTANT_NameAndType);
331: entries[codeRegionExitMethodRefIdx].setIndex2(i);
332:
333: int codeRegionExitNameAndTypeIdx = i;
334: entries[++i] = new CPEntry(CODE_REGION_EXIT_METHOD_NAME);
335: entries[codeRegionExitNameAndTypeIdx].setIndex1(i);
336: entries[codeRegionExitNameAndTypeIdx]
337: .setIndex2(voidVoidSignatureIdx);
338:
339: standardCPFragments[INJ_CODE_REGION] = new PackedCPFragment(
340: entries);
341: codeRegionContents_CodeRegionEntryMethodIdx = codeRegionEntryMethodRefIdx;
342: codeRegionContents_CodeRegionExitMethodIdx = codeRegionExitMethodRefIdx;
343:
344: // Initialize the constant pool contents used for object allocation profiling
345: entries = new CPEntry[10];
346: i = -1;
347: entries[++i] = new CPEntry(OBJECT_CHAR_VOID_SIGNATURE);
348:
349: int objCharVoidSignatureIdx = i;
350: entries[++i] = new CPEntry(CHAR_VOID_SIGNATURE);
351:
352: int charVoidSignatureIdx2 = i;
353: entries[++i] = new CPEntry(CONSTANT_Class);
354: profilerRuntimeClassRefIdx = i;
355: entries[++i] = new CPEntry(PROFRUNTIME_OBJALLOC_CLASS_NAME);
356: entries[profilerRuntimeClassRefIdx].setIndex1(i);
357: entries[++i] = new CPEntry(CONSTANT_Methodref);
358: entries[i].setIndex1(profilerRuntimeClassRefIdx);
359:
360: int objAllocTraceMethodRefIdx = i;
361: entries[++i] = new CPEntry(CONSTANT_NameAndType);
362: entries[objAllocTraceMethodRefIdx].setIndex2(i);
363:
364: int objAllocTraceNameAndTypeIdx = i;
365: entries[++i] = new CPEntry(TRACE_OBJ_ALLOC_METHOD_NAME);
366: entries[objAllocTraceNameAndTypeIdx].setIndex1(i);
367: entries[objAllocTraceNameAndTypeIdx]
368: .setIndex2(objCharVoidSignatureIdx);
369:
370: entries[++i] = new CPEntry(CONSTANT_Methodref);
371: entries[i].setIndex1(profilerRuntimeClassRefIdx);
372:
373: int memPprofilePointHitMethodRefIdx = i;
374: entries[++i] = new CPEntry(CONSTANT_NameAndType);
375: entries[memPprofilePointHitMethodRefIdx].setIndex2(i);
376:
377: int memProfilePointHitNameAndTypeIdx = i;
378: entries[++i] = new CPEntry(PROFILE_POINT_HIT);
379: entries[memProfilePointHitNameAndTypeIdx].setIndex1(i);
380: entries[memProfilePointHitNameAndTypeIdx]
381: .setIndex2(charVoidSignatureIdx2);
382: memoryProfContents_ProfilePointHitMethodIdx = memPprofilePointHitMethodRefIdx;
383:
384: standardCPFragments[INJ_OBJECT_ALLOCATIONS] = new PackedCPFragment(
385: entries);
386: memoryProfContents_TraceObjAllocMethodIdx = objAllocTraceMethodRefIdx;
387:
388: // Initialize the constant pool contents used for object liveness profiling
389: entries = new CPEntry[10];
390: i = -1;
391: entries[++i] = new CPEntry(OBJECT_CHAR_VOID_SIGNATURE);
392: objCharVoidSignatureIdx = i;
393: entries[++i] = new CPEntry(CHAR_VOID_SIGNATURE);
394: entries[++i] = new CPEntry(CONSTANT_Class);
395: profilerRuntimeClassRefIdx = i;
396: entries[++i] = new CPEntry(PROFRUNTIME_OBJLIVENESS_CLASS_NAME);
397: entries[profilerRuntimeClassRefIdx].setIndex1(i);
398: entries[++i] = new CPEntry(CONSTANT_Methodref);
399: entries[i].setIndex1(profilerRuntimeClassRefIdx);
400: objAllocTraceMethodRefIdx = i;
401: entries[++i] = new CPEntry(CONSTANT_NameAndType);
402: entries[objAllocTraceMethodRefIdx].setIndex2(i);
403: objAllocTraceNameAndTypeIdx = i;
404: entries[++i] = new CPEntry(TRACE_OBJ_ALLOC_METHOD_NAME);
405: entries[objAllocTraceNameAndTypeIdx].setIndex1(i);
406: entries[objAllocTraceNameAndTypeIdx]
407: .setIndex2(objCharVoidSignatureIdx);
408:
409: entries[++i] = new CPEntry(CONSTANT_Methodref);
410: entries[i].setIndex1(profilerRuntimeClassRefIdx);
411: entries[++i] = new CPEntry(CONSTANT_NameAndType);
412: entries[memPprofilePointHitMethodRefIdx].setIndex2(i);
413: entries[++i] = new CPEntry(PROFILE_POINT_HIT);
414: entries[memProfilePointHitNameAndTypeIdx].setIndex1(i);
415: entries[memProfilePointHitNameAndTypeIdx]
416: .setIndex2(charVoidSignatureIdx2);
417:
418: standardCPFragments[INJ_OBJECT_LIVENESS] = new PackedCPFragment(
419: entries);
420:
421: /*memoryProfContents_TraceObjAllocMethodIdx = objAllocTraceMethodRefIdx; // Same as above */
422: }
423: }
|