[jboss-cvs] JBoss Profiler SVN: r462 - in branches/JBossProfiler2: src/main/org/jboss/profiler/agent and 1 other directory.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sat Aug 16 04:13:41 EDT 2008
Author: jesper.pedersen
Date: 2008-08-16 04:13:41 -0400 (Sat, 16 Aug 2008)
New Revision: 462
Added:
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThread.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThreadImpl.java
Modified:
branches/JBossProfiler2/build.xml
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java
branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Profiler.java
Log:
Introduce ProfilerThread - profile PerThread instead of PerVM
Modified: branches/JBossProfiler2/build.xml
===================================================================
--- branches/JBossProfiler2/build.xml 2008-06-30 12:30:50 UTC (rev 461)
+++ branches/JBossProfiler2/build.xml 2008-08-16 08:13:41 UTC (rev 462)
@@ -353,7 +353,6 @@
<exclude name="**/richfaces-api.jar"/>
<exclude name="**/richfaces-impl.jar"/>
<exclude name="**/richfaces-ui.jar"/>
- <exclude name="**/servlet.jar"/>
</fileset>
</copy>
<copy todir="${dist.dir}">
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java 2008-06-30 12:30:50 UTC (rev 461)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/JavassistTransformer.java 2008-08-16 08:13:41 UTC (rev 462)
@@ -112,12 +112,12 @@
if (include) {
constructor.insertBeforeBody("{ " +
- "org.jboss.profiler.agent.Profiler.allocation(\"" + className +"\");" +
- "org.jboss.profiler.agent.Profiler.start(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
+ "org.jboss.profiler.agent.Profiler.getProfilerThread(Thread.currentThread()).allocation(\"" + className +"\");" +
+ "org.jboss.profiler.agent.Profiler.getProfilerThread(Thread.currentThread()).start(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
" }");
constructor.insertAfter("{ " +
- "org.jboss.profiler.agent.Profiler.end(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
+ "org.jboss.profiler.agent.Profiler.getProfilerThread(Thread.currentThread()).end(\"" + className + "\", \"" + constructor.getLongName() + "\");" +
" }", true);
}
}
@@ -155,12 +155,23 @@
if (include) {
method.insertBefore("{ " +
- "org.jboss.profiler.agent.Profiler.start(\"" + className + "\", \"" + method.getLongName() + "\");" +
+ "org.jboss.profiler.agent.Profiler.getProfilerThread(Thread.currentThread()).start(\"" + className + "\", \"" + method.getLongName() + "\");" +
" }");
method.insertAfter("{ " +
- "org.jboss.profiler.agent.Profiler.end(\"" + className + "\", \"" + method.getLongName() + "\");" +
+ "org.jboss.profiler.agent.Profiler.getProfilerThread(Thread.currentThread()).end(\"" + className + "\", \"" + method.getLongName() + "\");" +
" }", true);
}
+
+ /*
+ TODO
+
+ Implement support for beginWait/endWait for the following methods:
+
+ java.lang.Object#wait()
+ java.lang.Thread#join()
+ java.lang.Thread#sleep()
+ java.lang.Thread#yield()
+ */
}
}
Modified: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Profiler.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Profiler.java 2008-06-30 12:30:50 UTC (rev 461)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/Profiler.java 2008-08-16 08:13:41 UTC (rev 462)
@@ -42,8 +42,12 @@
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* The profiler
@@ -54,18 +58,9 @@
/** The class name */
public static final String CLASSNAME = "org/jboss/profiler/agent/Profiler";
- /** The threads map */
- private static Map<Long, ThreadInfo> threadMap;
+ /** The profiler threads map */
+ private static ConcurrentMap<Long, ProfilerThreadImpl> profilerThreadMap;
- /** The active frame for all threads */
- private static Map<Long, FrameInfo> activeFrameMap;
-
- /** The frame number map */
- private static Map<Long, Long> frameNumberMap;
-
- /** The allocation map */
- private static Map<String, AllocationInfo> allocationMap;
-
/** The from date */
private static Date from;
@@ -79,7 +74,7 @@
private static Object lock = new Object();
/** Running */
- private static boolean running = false;
+ private static AtomicBoolean running = new AtomicBoolean(false);
/**
* Constructor
@@ -92,14 +87,10 @@
*/
public static void startProfiler() {
synchronized (lock) {
- threadMap = new HashMap<Long, ThreadInfo>();
- activeFrameMap = new HashMap<Long, FrameInfo>();
- allocationMap = new HashMap<String, AllocationInfo>();
+ profilerThreadMap = new ConcurrentHashMap<Long, ProfilerThreadImpl>();
from = new Date();
if (!Agent.isMemoryStore()) {
- frameNumberMap = new HashMap<Long, Long>();
-
Calendar c = Calendar.getInstance();
DecimalFormat df = new DecimalFormat("00");
DecimalFormat df3 = new DecimalFormat("000");
@@ -123,7 +114,7 @@
root.mkdirs();
}
- running = true;
+ running.set(true);
}
}
@@ -132,30 +123,78 @@
*/
public static void stopProfiler() {
synchronized (lock) {
- if (running) {
- for (Long threadId: threadMap.keySet()) {
- ThreadInfo ti = threadMap.get(threadId);
-
- if (ti.getFrames().size() > 0) {
- FrameInfo fi = ti.getRecentFrame();
- fi.close();
- }
+ if (running.get()) {
+ for (ProfilerThreadImpl pti : profilerThreadMap.values()) {
+ pti.closeFrames();
}
Date to = new Date();
List<ClassInfo> classList = ClassUtil.getClasses();
if (Agent.isMemoryStore()) {
- Snapshot snapshot = new Snapshot(new ArrayList<ThreadInfo>(threadMap.values()),
- new ArrayList<AllocationInfo>(allocationMap.values()),
+ List<ThreadInfo> threadInfos = new ArrayList<ThreadInfo>();
+ Map<String, AllocationInfo> allocationInfos = new HashMap<String, AllocationInfo>();
+
+ for (ProfilerThreadImpl pti : profilerThreadMap.values()) {
+ threadInfos.add(pti.getThreadInfo());
+
+ Map<String, AllocationInfo> ptiAllocationMap = pti.getAllocationMap();
+
+ Iterator it = ptiAllocationMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry)it.next();
+
+ String className = (String)entry.getKey();
+ AllocationInfo ptiAllocation = (AllocationInfo)entry.getValue();
+
+ AllocationInfo ai = allocationInfos.get(className);
+
+ if (ai == null) {
+ ai = new AllocationInfo(className);
+ allocationInfos.put(className, ai);
+ }
+
+ for (long l = 0; l < ptiAllocation.getCount(); l++) {
+ ai.increase();
+ }
+ }
+ }
+
+ Snapshot snapshot = new Snapshot(threadInfos,
+ new ArrayList<AllocationInfo>(allocationInfos.values()),
classList,
from,
to);
snapshots.add(snapshot);
} else {
try {
+ Map<String, AllocationInfo> allocationInfos = new HashMap<String, AllocationInfo>();
+
+ for (ProfilerThreadImpl pti : profilerThreadMap.values()) {
+ Map<String, AllocationInfo> ptiAllocationMap = pti.getAllocationMap();
+
+ Iterator it = ptiAllocationMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry)it.next();
+
+ String className = (String)entry.getKey();
+ AllocationInfo ptiAllocation = (AllocationInfo)entry.getValue();
+
+ AllocationInfo ai = allocationInfos.get(className);
+
+ if (ai == null) {
+ ai = new AllocationInfo(className);
+ allocationInfos.put(className, ai);
+ }
+
+ for (long l = 0; l < ptiAllocation.getCount(); l++) {
+ ai.increase();
+ }
+ }
+ }
+
Snapshot snapshot = new Snapshot(null,
- new ArrayList<AllocationInfo>(allocationMap.values()),
+ new ArrayList<AllocationInfo>(allocationInfos.values()),
classList,
from,
to);
@@ -167,7 +206,7 @@
}
}
- running = false;
+ running.set(false);
}
}
@@ -180,7 +219,7 @@
Snapshot snapshot = null;
boolean wasRunning = false;
- if (running) {
+ if (running.get()) {
stopProfiler();
wasRunning = true;
}
@@ -255,248 +294,33 @@
* @return True if running; otherwise false
*/
public static boolean isRunning() {
- synchronized (lock) {
- return running;
- }
+ return running.get();
}
/**
- * Register start time for a method
- * @param className The class name
- * @param methodName The method name
+ * Get the profiler thread
+ * @param thread The thread
+ * @return The profiler thread
*/
- public static void start(String className, String methodName) {
- long start = System.nanoTime();
-
- if (!Agent.isEnabled() || !Agent.isCPU() || !running) {
- return;
- }
-
- synchronized (lock) {
- Thread thread = Thread.currentThread();
- long threadId = thread.getId();
-
- MethodInfo mi = new MethodInfo(methodName, className);
-
- FrameInfo parent = (FrameInfo)activeFrameMap.get(threadId);
- FrameInfo fi = null;
-
- if (parent != null) {
- fi = (FrameInfo)parent.getChild(mi);
-
- if (fi == null) {
- fi = new FrameInfo(mi, parent);
- }
- } else {
- fi = new FrameInfo(mi, null);
- ThreadInfo ti = threadMap.get(threadId);
- if (ti == null) {
- List<String> groups = new ArrayList<String>();
-
- ThreadGroup tg = thread.getThreadGroup();
- while (tg != null) {
- groups.add(tg.getName());
- tg = tg.getParent();
- }
-
- ti = new ThreadInfo(threadId, thread.getName(), thread.getPriority(), thread.isDaemon(), groups);
- threadMap.put(threadId, ti);
-
- if (!Agent.isMemoryStore()) {
- File directory = new File(root, Long.toString(threadId));
-
- try {
- ThreadHelper.save(ti, directory);
- } catch (Exception e) {
- System.err.println(e.getMessage());
- e.printStackTrace(System.err);
- }
- }
- }
- ti.add(fi);
+ public static ProfilerThread getProfilerThread(Thread thread) {
+ ProfilerThreadImpl result = profilerThreadMap.get(Long.valueOf(thread.getId()));
+ if (result == null) {
+ // ProfilerThreadImpl does not yet exist
+ ProfilerThreadImpl newResult = new ProfilerThreadImpl(thread);
+ result = profilerThreadMap.putIfAbsent(Long.valueOf(thread.getId()), newResult);
+ if (result == null) {
+ // put succeeded, use new value
+ result = newResult;
}
-
- activeFrameMap.put(threadId, fi);
-
- fi.setOverhead(System.nanoTime() - start);
- fi.setBeginTime(System.nanoTime());
}
+ return result;
}
-
- /**
- * Register end time for a method
- * @param className The class name
- * @param methodName The method name
- */
- public static void end(String className, String methodName) {
- long start = System.nanoTime();
-
- if (!Agent.isEnabled() || !Agent.isCPU() || !running) {
- return;
- }
- synchronized (lock) {
- long threadId = Thread.currentThread().getId();
- FrameInfo fi = findFrame(threadId, className, methodName);
-
- if (fi == null) {
- return;
- }
-
- fi.setOverhead(System.nanoTime() - start);
- fi.setEndTime(System.nanoTime());
-
- if (fi.getParent() != null) {
- activeFrameMap.put(threadId, fi.getParent());
- } else {
- activeFrameMap.put(threadId, null);
-
- if (!Agent.isMemoryStore()) {
- Long l = frameNumberMap.get(threadId);
- if (l == null) {
- l = Long.valueOf(0);
- }
-
- File directory = new File(root, Long.toString(threadId));
-
- try {
- FrameHelper.save(fi, l, directory);
-
- ThreadInfo ti = threadMap.get(threadId);
- ti.getFrames().clear();
-
- frameNumberMap.put(threadId, Long.valueOf(l.longValue() + 1));
- } catch (Exception e) {
- System.err.println(e.getMessage());
- e.printStackTrace(System.err);
- }
- }
- }
- }
- }
-
/**
- * Register start wait time for a method
- * @param className The class name
- * @param methodName The method name
+ * Get the root directory
+ * @return The root directory
*/
- public static void beginWait(String className, String methodName) {
- long start = System.nanoTime();
-
- if (!Agent.isEnabled() || !Agent.isCPU() || !running) {
- return;
- }
-
- synchronized (lock) {
- FrameInfo fi = findFrame(Thread.currentThread().getId(), className, methodName);
-
- if (fi == null) {
- return;
- }
-
- fi.setOverhead(System.nanoTime() - start);
- fi.setBeginWaitTime(System.nanoTime());
- }
+ static File getRoot() {
+ return root;
}
-
- /**
- * Register end wait time for a method
- * @param className The class name
- * @param methodName The method name
- */
- public static void endWait(String className, String methodName) {
- long start = System.nanoTime();
-
- if (!Agent.isEnabled() || !Agent.isCPU() || !running) {
- return;
- }
-
- synchronized (lock) {
- FrameInfo fi = findFrame(Thread.currentThread().getId(), className, methodName);
-
- if (fi == null) {
- return;
- }
-
- fi.setOverhead(System.nanoTime() - start);
- fi.setEndWaitTime(System.nanoTime());
- }
- }
-
- /**
- * Unwind exception
- * @param className The class name
- * @param methodName The method name
- * @param exception The exception
- */
- public static void unwind(String className, String methodName, String exception) {
- if (!Agent.isEnabled() || !Agent.isCPU() || !running) {
- return;
- }
-
- synchronized (lock) {
- long threadId = Thread.currentThread().getId();
- FrameInfo fi = findFrame(threadId, className, methodName);
-
- if (fi == null) {
- return;
- }
-
- activeFrameMap.put(threadId, fi);
- }
- }
-
- /**
- * Class allocation
- * @param className The class being allocated
- */
- public static void allocation(String className) {
- if (!Agent.isEnabled() || !Agent.isMemory() || !running) {
- return;
- }
-
- synchronized (lock) {
- long threadId = Thread.currentThread().getId();
- FrameInfo fi = (FrameInfo)activeFrameMap.get(threadId);
-
- // Constructor delegation
- if (fi != null && fi.getMethod().getClassName().equals(className)
- && "<init>".equals(fi.getMethod().getMethodName())) {
- return;
- }
-
- AllocationInfo ai = allocationMap.get(className);
-
- if (ai == null) {
- ai = new AllocationInfo(className);
- allocationMap.put(className, ai);
- }
-
- ai.increase();
- }
- }
-
- /**
- * Find the frame which contains the call
- * @param threadId The thread id
- * @param className The class name
- * @param methodName The method name
- * @return The frame; null if not found
- */
- private static final FrameInfo findFrame(long threadId, String className, String methodName) {
- FrameInfo fi = (FrameInfo)activeFrameMap.get(threadId);
-
- while (fi != null) {
- if (fi.getMethod().getClassName().equals(className)
- && fi.getMethod().getMethodName().equals(methodName)) {
- // Found the first frame
- return fi;
- } else {
- fi.setEndTime(System.nanoTime());
- fi = fi.getParent();
- }
- }
-
- return fi;
- }
}
Added: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThread.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThread.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThread.java 2008-08-16 08:13:41 UTC (rev 462)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007-2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.profiler.agent;
+
+/**
+ * A profiler thread
+ * @author Jesper Pedersen <jesper.pedersen at jboss.org>
+ */
+public interface ProfilerThread {
+
+ /**
+ * Register start time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void start(String className, String methodName);
+
+ /**
+ * Register end time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void end(String className, String methodName);
+
+ /**
+ * Register start wait time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void beginWait(String className, String methodName);
+
+ /**
+ * Register end wait time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void endWait(String className, String methodName);
+
+ /**
+ * Unwind exception
+ * @param className The class name
+ * @param methodName The method name
+ * @param exception The exception
+ */
+ public void unwind(String className, String methodName, String exception);
+
+ /**
+ * Class allocation
+ * @param className The class being allocated
+ */
+ public void allocation(String className);
+}
Added: branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThreadImpl.java
===================================================================
--- branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThreadImpl.java (rev 0)
+++ branches/JBossProfiler2/src/main/org/jboss/profiler/agent/ProfilerThreadImpl.java 2008-08-16 08:13:41 UTC (rev 462)
@@ -0,0 +1,315 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007-2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.profiler.agent;
+
+import org.jboss.profiler.shared.AllocationInfo;
+import org.jboss.profiler.shared.ClassInfo;
+import org.jboss.profiler.shared.FrameHelper;
+import org.jboss.profiler.shared.FrameInfo;
+import org.jboss.profiler.shared.MethodInfo;
+import org.jboss.profiler.shared.Snapshot;
+import org.jboss.profiler.shared.SnapshotHelper;
+import org.jboss.profiler.shared.ThreadHelper;
+import org.jboss.profiler.shared.ThreadInfo;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The profiler thread implementation
+ * @author Jesper Pedersen <jesper.pedersen at jboss.org>
+ */
+public class ProfilerThreadImpl implements ProfilerThread {
+
+ /** The thread id */
+ private long threadId;
+
+ /** The thread info */
+ private ThreadInfo ti;
+
+ /** The active frame */
+ private FrameInfo activeFrame;
+
+ /** The frame number */
+ private long frameNumber;
+
+ /** The allocation map */
+ private Map<String, AllocationInfo> allocationMap;
+
+ /**
+ * Constructor
+ * @param thread The thread
+ */
+ ProfilerThreadImpl(Thread thread) {
+ threadId = thread.getId();
+
+ List<String> groups = new ArrayList<String>();
+
+ ThreadGroup tg = thread.getThreadGroup();
+ while (tg != null) {
+ groups.add(tg.getName());
+ tg = tg.getParent();
+ }
+
+ ti = new ThreadInfo(threadId, thread.getName(), thread.getPriority(), thread.isDaemon(), groups);
+
+ activeFrame = null;
+ frameNumber = 0;
+ allocationMap = new HashMap<String, AllocationInfo>();
+
+ if (!Agent.isMemoryStore()) {
+ File directory = new File(Profiler.getRoot(), Long.toString(threadId));
+
+ try {
+ ThreadHelper.save(ti, directory);
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ /**
+ * Register start time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void start(String className, String methodName) {
+ long start = System.nanoTime();
+
+ if (!Agent.isEnabled() || !Agent.isCPU() || !Profiler.isRunning()) {
+ return;
+ }
+
+ MethodInfo mi = new MethodInfo(methodName, className);
+
+ FrameInfo parent = activeFrame;
+ FrameInfo fi = null;
+
+ if (parent != null) {
+ fi = (FrameInfo)parent.getChild(mi);
+
+ if (fi == null) {
+ fi = new FrameInfo(mi, parent);
+ }
+ } else {
+ fi = new FrameInfo(mi, null);
+ ti.add(fi);
+ }
+
+ activeFrame = fi;
+
+ fi.setOverhead(System.nanoTime() - start);
+ fi.setBeginTime(System.nanoTime());
+ }
+
+ /**
+ * Register end time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void end(String className, String methodName) {
+ long start = System.nanoTime();
+
+ if (!Agent.isEnabled() || !Agent.isCPU() || !Profiler.isRunning()) {
+ return;
+ }
+
+ FrameInfo fi = findFrame(className, methodName);
+
+ if (fi == null) {
+ return;
+ }
+
+ fi.setOverhead(System.nanoTime() - start);
+ fi.setEndTime(System.nanoTime());
+
+ if (fi.getParent() != null) {
+ activeFrame = fi.getParent();
+ } else {
+ activeFrame = null;
+
+ if (!Agent.isMemoryStore()) {
+ File directory = new File(Profiler.getRoot(), Long.toString(threadId));
+
+ try {
+ FrameHelper.save(fi, frameNumber, directory);
+
+ ti.getFrames().clear();
+
+ frameNumber += 1;
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+ }
+
+ /**
+ * Register start wait time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void beginWait(String className, String methodName) {
+ long start = System.nanoTime();
+
+ if (!Agent.isEnabled() || !Agent.isCPU() || !Profiler.isRunning()) {
+ return;
+ }
+
+ FrameInfo fi = findFrame(className, methodName);
+
+ if (fi == null) {
+ return;
+ }
+
+ fi.setOverhead(System.nanoTime() - start);
+ fi.setBeginWaitTime(System.nanoTime());
+ }
+
+ /**
+ * Register end wait time for a method
+ * @param className The class name
+ * @param methodName The method name
+ */
+ public void endWait(String className, String methodName) {
+ long start = System.nanoTime();
+
+ if (!Agent.isEnabled() || !Agent.isCPU() || !Profiler.isRunning()) {
+ return;
+ }
+
+ FrameInfo fi = findFrame(className, methodName);
+
+ if (fi == null) {
+ return;
+ }
+
+ fi.setOverhead(System.nanoTime() - start);
+ fi.setEndWaitTime(System.nanoTime());
+ }
+
+ /**
+ * Unwind exception
+ * @param className The class name
+ * @param methodName The method name
+ * @param exception The exception
+ */
+ public void unwind(String className, String methodName, String exception) {
+ if (!Agent.isEnabled() || !Agent.isCPU() || !Profiler.isRunning()) {
+ return;
+ }
+
+ FrameInfo fi = findFrame(className, methodName);
+
+ if (fi == null) {
+ return;
+ }
+
+ activeFrame = fi;
+ }
+
+ /**
+ * Class allocation
+ * @param className The class being allocated
+ */
+ public void allocation(String className) {
+ if (!Agent.isEnabled() || !Agent.isMemory() || !Profiler.isRunning()) {
+ return;
+ }
+
+ FrameInfo fi = activeFrame;
+
+ // Constructor delegation
+ if (fi != null && fi.getMethod().getClassName().equals(className)
+ && "<init>".equals(fi.getMethod().getMethodName())) {
+ return;
+ }
+
+ AllocationInfo ai = allocationMap.get(className);
+
+ if (ai == null) {
+ ai = new AllocationInfo(className);
+ allocationMap.put(className, ai);
+ }
+
+ ai.increase();
+ }
+
+ /**
+ * Close the frames
+ */
+ void closeFrames() {
+ if (ti.getFrames().size() > 0) {
+ FrameInfo fi = ti.getRecentFrame();
+ fi.close();
+ }
+ }
+
+ /**
+ * Get the thead info
+ * @return The thread info
+ */
+ ThreadInfo getThreadInfo() {
+ return ti;
+ }
+
+ Map<String, AllocationInfo> getAllocationMap() {
+ return allocationMap;
+ }
+
+ /**
+ * Find the frame which contains the call
+ * @param threadId The thread id
+ * @param className The class name
+ * @param methodName The method name
+ * @return The frame; null if not found
+ */
+ private FrameInfo findFrame(String className, String methodName) {
+ FrameInfo fi = activeFrame;
+
+ while (fi != null) {
+ if (fi.getMethod().getClassName().equals(className)
+ && fi.getMethod().getMethodName().equals(methodName)) {
+ // Found the first frame
+ return fi;
+ } else {
+ fi.setEndTime(System.nanoTime());
+ fi = fi.getParent();
+ }
+ }
+
+ return fi;
+ }
+}
More information about the jboss-cvs-commits
mailing list