[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