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.results.cpu;
042:
043: import org.netbeans.lib.profiler.global.CommonConstants;
044: import org.netbeans.lib.profiler.results.AbstractDataFrameProcessor;
045: import org.netbeans.lib.profiler.results.ProfilingResultListener;
046: import java.util.HashSet;
047: import java.util.Iterator;
048: import java.util.Set;
049: import java.util.logging.Level;
050:
051: /**
052: * This class' main purpose is to parse a chunk of CPU related data received from
053: * the JFluid server agent and dispatch the resulting events to all interested parties
054: * @author Jaroslav Bachorik
055: */
056: public class CPUDataFrameProcessor extends AbstractDataFrameProcessor {
057: //~ Instance fields ----------------------------------------------------------------------------------------------------------
058:
059: private volatile int currentThreadId = -1;
060:
061: //~ Methods ------------------------------------------------------------------------------------------------------------------
062:
063: public void doProcessDataFrame(byte[] buffer) {
064: int position = 0;
065: boolean collectingTwoTimeStamps = (client != null) ? client
066: .getStatus().collectingTwoTimeStamps() : false;
067:
068: while (position < buffer.length) {
069: byte eventType = buffer[position++];
070:
071: if ((eventType & CommonConstants.COMPACT_EVENT_FORMAT_BYTE_MASK) != 0) {
072: char charEvent = (char) ((((int) eventType & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
073:
074: if ((byte) (eventType & CommonConstants.METHOD_EXIT_COMPACT_BYTE_MASK) == CommonConstants.METHOD_EXIT_COMPACT_BYTE_MASK) {
075: fireMethodExitUnstamped(
076: charEvent
077: & CommonConstants.COMPACT_EVENT_METHOD_ID_MASK,
078: currentThreadId,
079: CPUProfilingResultListener.METHODTYPE_NORMAL);
080: } else {
081: fireMethodEntryUnstamped(
082: charEvent
083: & CommonConstants.COMPACT_EVENT_METHOD_ID_MASK,
084: currentThreadId,
085: CPUProfilingResultListener.METHODTYPE_NORMAL);
086: }
087:
088: continue;
089: }
090:
091: if (!((eventType == CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT)
092: || (eventType == CommonConstants.SERVLET_DO_METHOD)
093: || (eventType == CommonConstants.SET_FOLLOWING_EVENTS_THREAD)
094: || (eventType == CommonConstants.NEW_THREAD) || (eventType == CommonConstants.RESET_COLLECTORS))) {
095: int methodId = -1;
096: long timeStamp0 = 0;
097: long timeStamp1 = 0;
098:
099: if ((eventType != CommonConstants.ADJUST_TIME // those events do not carry methodId
100: )
101: && (eventType != CommonConstants.METHOD_ENTRY_WAIT)
102: && (eventType != CommonConstants.METHOD_EXIT_WAIT)
103: && (eventType != CommonConstants.METHOD_ENTRY_MONITOR)
104: && (eventType != CommonConstants.METHOD_EXIT_MONITOR)
105: && (eventType != CommonConstants.METHOD_ENTRY_SLEEP)
106: && (eventType != CommonConstants.METHOD_EXIT_SLEEP)) {
107: methodId = (((int) buffer[position++] & 0xFF) << 8)
108: | ((int) buffer[position++] & 0xFF);
109: }
110:
111: if ((eventType != CommonConstants.METHOD_ENTRY_UNSTAMPED)
112: && (eventType != CommonConstants.METHOD_EXIT_UNSTAMPED)
113: && (eventType != CommonConstants.MARKER_ENTRY_UNSTAMPED)
114: && (eventType != CommonConstants.MARKER_EXIT_UNSTAMPED)) {
115: timeStamp0 = (((long) buffer[position++] & 0xFF) << 48)
116: | (((long) buffer[position++] & 0xFF) << 40)
117: | (((long) buffer[position++] & 0xFF) << 32)
118: | (((long) buffer[position++] & 0xFF) << 24)
119: | (((long) buffer[position++] & 0xFF) << 16)
120: | (((long) buffer[position++] & 0xFF) << 8)
121: | ((long) buffer[position++] & 0xFF);
122:
123: if ((eventType != CommonConstants.METHOD_ENTRY_WAIT)
124: && (eventType != CommonConstants.METHOD_EXIT_WAIT)
125: && (eventType != CommonConstants.METHOD_ENTRY_MONITOR)
126: && (eventType != CommonConstants.METHOD_EXIT_MONITOR)
127: && (eventType != CommonConstants.METHOD_ENTRY_SLEEP)
128: && (eventType != CommonConstants.METHOD_EXIT_SLEEP)) {
129: if (collectingTwoTimeStamps
130: || (eventType < CommonConstants.TWO_TIMESTAMP_EVENTS)) {
131: timeStamp1 = (((long) buffer[position++] & 0xFF) << 48)
132: | (((long) buffer[position++] & 0xFF) << 40)
133: | (((long) buffer[position++] & 0xFF) << 32)
134: | (((long) buffer[position++] & 0xFF) << 24)
135: | (((long) buffer[position++] & 0xFF) << 16)
136: | (((long) buffer[position++] & 0xFF) << 8)
137: | ((long) buffer[position++] & 0xFF);
138: }
139: }
140: }
141:
142: switch (eventType) {
143: case CommonConstants.MARKER_ENTRY_UNSTAMPED: {
144: if (LOGGER.isLoggable(Level.FINEST)) {
145: LOGGER
146: .finest("Marker entry unstamped, tId="
147: + currentThreadId + ", mId="
148: + methodId); // NOI18N
149: }
150:
151: fireMethodEntryUnstamped(
152: methodId,
153: currentThreadId,
154: CPUProfilingResultListener.METHODTYPE_MARKER);
155:
156: break;
157: }
158: case CommonConstants.METHOD_ENTRY_UNSTAMPED: {
159: if (LOGGER.isLoggable(Level.FINEST)) {
160: LOGGER
161: .finest("Method entry unstamped, tId="
162: + currentThreadId + ", mId="
163: + methodId); // NOI18N
164: }
165:
166: fireMethodEntryUnstamped(
167: methodId,
168: currentThreadId,
169: CPUProfilingResultListener.METHODTYPE_NORMAL);
170:
171: break;
172: }
173: case CommonConstants.MARKER_EXIT_UNSTAMPED: {
174: if (LOGGER.isLoggable(Level.FINEST)) {
175: LOGGER
176: .finest("Marker exit unstamped, tId="
177: + currentThreadId + ", mId="
178: + methodId); // NOI18N
179: }
180:
181: fireMethodExitUnstamped(
182: methodId,
183: currentThreadId,
184: CPUProfilingResultListener.METHODTYPE_MARKER);
185:
186: break;
187: }
188: case CommonConstants.METHOD_EXIT_UNSTAMPED: {
189: if (LOGGER.isLoggable(Level.FINEST)) {
190: LOGGER
191: .finest("Method exit unstamped, tId="
192: + currentThreadId + ", mId="
193: + methodId); // NOI18N
194: }
195:
196: fireMethodExitUnstamped(
197: methodId,
198: currentThreadId,
199: CPUProfilingResultListener.METHODTYPE_NORMAL);
200:
201: break;
202: }
203: case CommonConstants.MARKER_ENTRY: {
204: if (LOGGER.isLoggable(Level.FINEST)) {
205: LOGGER
206: .finest("Marker entry , tId="
207: + currentThreadId + ", mId="
208: + methodId); // NOI18N
209: }
210:
211: fireMethodEntry(
212: methodId,
213: currentThreadId,
214: CPUProfilingResultListener.METHODTYPE_MARKER,
215: timeStamp0, timeStamp1);
216:
217: break;
218: }
219: case CommonConstants.ROOT_ENTRY: {
220: if (LOGGER.isLoggable(Level.FINEST)) {
221: LOGGER
222: .finest("Root entry , tId="
223: + currentThreadId + ", mId="
224: + methodId); // NOI18N
225: }
226:
227: fireMethodEntry(methodId, currentThreadId,
228: CPUProfilingResultListener.METHODTYPE_ROOT,
229: timeStamp0, timeStamp1);
230:
231: break;
232: }
233: case CommonConstants.METHOD_ENTRY: {
234: if (LOGGER.isLoggable(Level.FINEST)) {
235: LOGGER
236: .finest("Method entry , tId="
237: + currentThreadId + ", mId="
238: + methodId); // NOI18N
239: }
240:
241: fireMethodEntry(
242: methodId,
243: currentThreadId,
244: CPUProfilingResultListener.METHODTYPE_NORMAL,
245: timeStamp0, timeStamp1);
246:
247: break;
248: }
249: case CommonConstants.MARKER_EXIT: {
250: if (LOGGER.isLoggable(Level.FINEST)) {
251: LOGGER
252: .finest("Marker exit , tId="
253: + currentThreadId + ", mId="
254: + methodId); // NOI18N
255: }
256:
257: fireMethodExit(
258: methodId,
259: currentThreadId,
260: CPUProfilingResultListener.METHODTYPE_MARKER,
261: timeStamp0, timeStamp1);
262:
263: break;
264: }
265: case CommonConstants.ROOT_EXIT: {
266: if (LOGGER.isLoggable(Level.FINEST)) {
267: LOGGER
268: .finest("Root exit , tId="
269: + currentThreadId + ", mId="
270: + methodId); // NOI18N
271: }
272:
273: fireMethodExit(methodId, currentThreadId,
274: CPUProfilingResultListener.METHODTYPE_ROOT,
275: timeStamp0, timeStamp1);
276:
277: break;
278: }
279: case CommonConstants.METHOD_EXIT: {
280: if (LOGGER.isLoggable(Level.FINEST)) {
281: LOGGER
282: .finest("Method exit , tId="
283: + currentThreadId + ", mId="
284: + methodId); // NOI18N
285: }
286:
287: fireMethodExit(
288: methodId,
289: currentThreadId,
290: CPUProfilingResultListener.METHODTYPE_NORMAL,
291: timeStamp0, timeStamp1);
292:
293: break;
294: }
295: case CommonConstants.ADJUST_TIME: {
296: if (LOGGER.isLoggable(Level.FINEST)) {
297: LOGGER.finest("Adjust time , tId="
298: + currentThreadId); // NOI18N
299: }
300:
301: fireAdjustTime(currentThreadId, timeStamp0,
302: timeStamp1);
303:
304: break;
305: }
306: case CommonConstants.METHOD_ENTRY_MONITOR: {
307: if (LOGGER.isLoggable(Level.FINEST)) {
308: LOGGER.finest("Monitor entry , tId="
309: + currentThreadId); // NOI18N
310: }
311:
312: fireMonitorEntry(currentThreadId, timeStamp0,
313: timeStamp1);
314:
315: break;
316: }
317: case CommonConstants.METHOD_EXIT_MONITOR: {
318: if (LOGGER.isLoggable(Level.FINEST)) {
319: LOGGER.finest("Monitor exit , tId="
320: + currentThreadId); // NOI18N
321: }
322:
323: fireMonitorExit(currentThreadId, timeStamp0,
324: timeStamp1);
325:
326: break;
327: }
328: case CommonConstants.METHOD_ENTRY_SLEEP: {
329: if (LOGGER.isLoggable(Level.FINEST)) {
330: LOGGER.finest("Sleep entry , tId="
331: + currentThreadId); // NOI18N
332: }
333:
334: fireSleepEntry(currentThreadId, timeStamp0,
335: timeStamp1);
336:
337: break;
338: }
339: case CommonConstants.METHOD_EXIT_SLEEP: {
340: if (LOGGER.isLoggable(Level.FINEST)) {
341: LOGGER.finest("Sleep exit , tId="
342: + currentThreadId); // NOI18N
343: }
344:
345: fireSleepExit(currentThreadId, timeStamp0,
346: timeStamp1);
347:
348: break;
349: }
350: case CommonConstants.METHOD_ENTRY_WAIT: {
351: if (LOGGER.isLoggable(Level.FINEST)) {
352: LOGGER.finest("Wait entry , tId="
353: + currentThreadId); // NOI18N
354: }
355:
356: fireWaitEntry(currentThreadId, timeStamp0,
357: timeStamp1);
358:
359: break;
360: }
361: case CommonConstants.METHOD_EXIT_WAIT: {
362: if (LOGGER.isLoggable(Level.FINEST)) {
363: LOGGER.finest("Wait exit , tId="
364: + currentThreadId); // NOI18N
365: }
366:
367: fireWaitExit(currentThreadId, timeStamp0,
368: timeStamp1);
369:
370: break;
371: }
372: case CommonConstants.THREADS_SUSPENDED: {
373: if (LOGGER.isLoggable(Level.FINEST)) {
374: LOGGER.finest("Threads suspend"); // NOI18N
375: }
376:
377: fireThreadsSuspend(timeStamp0, timeStamp1);
378:
379: break;
380: }
381: case CommonConstants.THREADS_RESUMED: {
382: if (LOGGER.isLoggable(Level.FINEST)) {
383: LOGGER.finest("Threads resume"); // NOI18N
384: }
385:
386: fireThreadsResumed(timeStamp0, timeStamp1);
387:
388: break;
389: }
390: default: {
391: LOGGER
392: .severe("*** Profiler Engine: internal error: got unknown event type in CPUDataFrameProcessor: "
393: + (int) eventType // NOI18N
394: + " at " + position // NOI18N
395: );
396:
397: break; // NOI18N
398: }
399: }
400: } else {
401: switch (eventType) {
402: case CommonConstants.BUFFEREVENT_PROFILEPOINT_HIT: {
403: int id = (((int) buffer[position++] & 0xFF) << 8)
404: | ((int) buffer[position++] & 0xFF);
405: long timeStamp = (((long) buffer[position++] & 0xFF) << 48)
406: | (((long) buffer[position++] & 0xFF) << 40)
407: | (((long) buffer[position++] & 0xFF) << 32)
408: | (((long) buffer[position++] & 0xFF) << 24)
409: | (((long) buffer[position++] & 0xFF) << 16)
410: | (((long) buffer[position++] & 0xFF) << 8)
411: | ((long) buffer[position++] & 0xFF);
412: int threadId = (((int) buffer[position++] & 0xFF) << 8)
413: | ((int) buffer[position++] & 0xFF);
414: fireProfilingPoint(threadId, id, timeStamp);
415:
416: break;
417: }
418: case CommonConstants.SET_FOLLOWING_EVENTS_THREAD: {
419: if (LOGGER.isLoggable(Level.FINEST)) {
420: LOGGER.finest("Change current thread , tId="
421: + currentThreadId); // NOI18N
422: }
423:
424: currentThreadId = (char) ((((int) buffer[position++] & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
425:
426: break;
427: }
428: case CommonConstants.NEW_THREAD: {
429: int threadId = (char) ((((int) buffer[position++] & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
430: int strLen = ((((int) buffer[position++] & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
431: String threadName = new String(buffer, position,
432: strLen);
433: position += strLen;
434: strLen = ((((int) buffer[position++] & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
435:
436: String threadClassName = new String(buffer,
437: position, strLen);
438: position += strLen;
439:
440: if (LOGGER.isLoggable(Level.FINEST)) {
441: LOGGER.finest("Creating new thread , tId="
442: + threadId); // NOI18N
443: }
444:
445: fireNewThread(threadId, threadName, threadClassName);
446: currentThreadId = threadId;
447:
448: break;
449: }
450: case CommonConstants.SERVLET_DO_METHOD: {
451: if (LOGGER.isLoggable(Level.FINEST)) {
452: LOGGER.finest("Servlet track start , tId="
453: + currentThreadId); // NOI18N
454: }
455:
456: byte requestType = buffer[position++];
457: int strLen = ((((int) buffer[position++] & 0xFF) << 8) | ((int) buffer[position++] & 0xFF));
458: String servletPath = new String(buffer, position,
459: strLen);
460: position += strLen;
461:
462: int sessionId = (((int) buffer[position++] & 0xFF) << 24)
463: | (((int) buffer[position++] & 0xFF) << 16)
464: | (((int) buffer[position++] & 0xFF) << 8)
465: | ((int) buffer[position++] & 0xFF);
466: fireServletRequest(currentThreadId, requestType,
467: servletPath, sessionId);
468:
469: break;
470: }
471: case CommonConstants.RESET_COLLECTORS: {
472: if (LOGGER.isLoggable(Level.FINEST)) {
473: LOGGER.finest("Profiling data reset"); // NOI18N
474: }
475:
476: fireReset();
477:
478: break;
479: }
480: default: {
481: LOGGER
482: .severe("*** Profiler Engine: internal error: got unknown event type in CallGraphBuilder: "
483: + (int) eventType // NOI18N
484: + " at " + position // NOI18N
485: );
486:
487: break; // NOI18N
488: }
489: }
490: }
491: }
492: }
493:
494: private void fireAdjustTime(final int threadId,
495: final long timeStamp0, final long timeStamp1) {
496: foreachListener(new ListenerFunctor() {
497: public void execute(ProfilingResultListener listener) {
498: ((CPUProfilingResultListener) listener).timeAdjust(
499: threadId, timeStamp0, timeStamp1);
500: }
501: });
502: }
503:
504: private void fireMethodEntry(final int methodId,
505: final int threadId, final int methodType,
506: final long timeStamp0, final long timeStamp1) {
507: foreachListener(new ListenerFunctor() {
508: public void execute(ProfilingResultListener listener) {
509: ((CPUProfilingResultListener) listener).methodEntry(
510: methodId, threadId, methodType, timeStamp0,
511: timeStamp1);
512: }
513: });
514: }
515:
516: private void fireMethodEntryUnstamped(final int methodId,
517: final int threadId, final int methodType) {
518: foreachListener(new ListenerFunctor() {
519: public void execute(ProfilingResultListener listener) {
520: ((CPUProfilingResultListener) listener)
521: .methodEntryUnstamped(methodId, threadId,
522: methodType);
523: }
524: });
525: }
526:
527: private void fireMethodExit(final int methodId, final int threadId,
528: final int methodType, final long timeStamp0,
529: final long timeStamp1) {
530: foreachListener(new ListenerFunctor() {
531: public void execute(ProfilingResultListener listener) {
532: ((CPUProfilingResultListener) listener).methodExit(
533: methodId, threadId, methodType, timeStamp0,
534: timeStamp1);
535: }
536: });
537: }
538:
539: private void fireMethodExitUnstamped(final int methodId,
540: final int threadId, final int methodType) {
541: foreachListener(new ListenerFunctor() {
542: public void execute(ProfilingResultListener listener) {
543: ((CPUProfilingResultListener) listener)
544: .methodExitUnstamped(methodId, threadId,
545: methodType);
546: }
547: });
548: }
549:
550: private void fireMonitorEntry(final int threadId,
551: final long timeStamp0, final long timeStamp1) {
552: foreachListener(new ListenerFunctor() {
553: public void execute(ProfilingResultListener listener) {
554: ((CPUProfilingResultListener) listener).monitorEntry(
555: threadId, timeStamp0, timeStamp1);
556: }
557: });
558: }
559:
560: private void fireMonitorExit(final int threadId,
561: final long timeStamp0, final long timeStamp1) {
562: foreachListener(new ListenerFunctor() {
563: public void execute(ProfilingResultListener listener) {
564: ((CPUProfilingResultListener) listener).monitorExit(
565: threadId, timeStamp0, timeStamp1);
566: }
567: });
568: }
569:
570: private void fireNewThread(final int threadId,
571: final String threadName, final String threadClassName) {
572: foreachListener(new ListenerFunctor() {
573: public void execute(ProfilingResultListener listener) {
574: ((CPUProfilingResultListener) listener).newThread(
575: threadId, threadName, threadClassName);
576: }
577: });
578: }
579:
580: private void fireServletRequest(final int threadId,
581: final int requestType, final String servletPath,
582: final int sessionId) {
583: foreachListener(new ListenerFunctor() {
584: public void execute(ProfilingResultListener listener) {
585: ((CPUProfilingResultListener) listener).servletRequest(
586: threadId, requestType, servletPath, sessionId);
587: }
588: });
589: }
590:
591: private void fireSleepEntry(final int threadId,
592: final long timeStamp0, final long timeStamp1) {
593: foreachListener(new ListenerFunctor() {
594: public void execute(ProfilingResultListener listener) {
595: ((CPUProfilingResultListener) listener).sleepEntry(
596: threadId, timeStamp0, timeStamp1);
597: }
598: });
599: }
600:
601: private void fireSleepExit(final int threadId,
602: final long timeStamp0, final long timeStamp1) {
603: foreachListener(new ListenerFunctor() {
604: public void execute(ProfilingResultListener listener) {
605: ((CPUProfilingResultListener) listener).sleepExit(
606: threadId, timeStamp0, timeStamp1);
607: }
608: });
609: }
610:
611: private void fireThreadsResumed(final long timeStamp0,
612: final long timeStamp1) {
613: foreachListener(new ListenerFunctor() {
614: public void execute(ProfilingResultListener listener) {
615: ((CPUProfilingResultListener) listener).threadsSuspend(
616: timeStamp0, timeStamp1);
617: }
618: });
619: }
620:
621: private void fireThreadsSuspend(final long timeStamp0,
622: final long timeStamp1) {
623: foreachListener(new ListenerFunctor() {
624: public void execute(ProfilingResultListener listener) {
625: ((CPUProfilingResultListener) listener).threadsSuspend(
626: timeStamp0, timeStamp1);
627: }
628: });
629: }
630:
631: private void fireWaitEntry(final int threadId,
632: final long timeStamp0, final long timeStamp1) {
633: foreachListener(new ListenerFunctor() {
634: public void execute(ProfilingResultListener listener) {
635: ((CPUProfilingResultListener) listener).waitEntry(
636: threadId, timeStamp0, timeStamp1);
637: }
638: });
639: }
640:
641: private void fireWaitExit(final int threadId,
642: final long timeStamp0, final long timeStamp1) {
643: foreachListener(new ListenerFunctor() {
644: public void execute(ProfilingResultListener listener) {
645: ((CPUProfilingResultListener) listener).waitExit(
646: threadId, timeStamp0, timeStamp1);
647: }
648: });
649: }
650: }
|