changeset 935:6354acecccb7

profilers: perfasm, recover when multiple compiler threads are writing to the same hotspot.log.
author shade
date Tue, 29 Jul 2014 10:01:18 -0700
parents 98a3cd8c58ef
children 5d6eee917c11
files jmh-core/src/main/java/org/openjdk/jmh/profile/LinuxPerfAsmProfiler.java
diffstat 1 files changed, 33 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/profile/LinuxPerfAsmProfiler.java	Sun Jul 27 17:51:14 2014 -0700
+++ b/jmh-core/src/main/java/org/openjdk/jmh/profile/LinuxPerfAsmProfiler.java	Tue Jul 29 10:01:18 2014 -0700
@@ -63,6 +63,8 @@
 import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class LinuxPerfAsmProfiler extends LinuxPerfUtil implements ExternalProfiler {
 
@@ -610,24 +612,47 @@
 
     Assembly readAssembly(File stdOut) {
         try {
+            Pattern pWriterThread = Pattern.compile("(.*)<writer thread='(.*)'>(.*)");
+
             List<ASMLine> lines = new ArrayList<ASMLine>();
             SortedMap<Long, Integer> addressMap = new TreeMap<Long, Integer>();
             SortedMap<Long, String> methodMap = new TreeMap<Long, String>();
 
-            String method = null;
+            Map<Long, String> writerToMethod = new HashMap<Long, String>();
+            Long writerId = -1L;
+
             String line;
             BufferedReader br = new BufferedReader(new FileReader(stdOut));
             while ((line = br.readLine()) != null) {
-                if (line.trim().isEmpty()) continue;
-                String[] elements = line.trim().split(" ");
+                String trim = line.trim();
+
+                if (trim.isEmpty()) continue;
+                String[] elements = trim.split(" ");
 
                 ASMLine asmLine = new ASMLine(line);
-                if (line.contains("{method}")) {
+
+                // Parse the writer threads IDs:
+                //    <writer thread='140703710570240'/>
+                if (line.contains("<writer thread=")) {
+                    Matcher m = pWriterThread.matcher(line);
+                    if (m.matches()) {
+                        try {
+                            writerId = Long.valueOf(m.group(2));
+                        } catch (NumberFormatException e) {
+                            // something is wrong, try to recover
+                        }
+                    }
+                } else if (line.contains("{method}")) {
                     if (elements.length == 7) {
-                        method = (elements[6].replace("/", ".") + "::" + elements[3]).replace("'", "");
+                        String method = (elements[6].replace("/", ".") + "::" + elements[3]).replace("'", "");
                         method = method.replace("&apos;", "");
                         method = method.replace("&lt;", "<");
                         method = method.replace("&gt;", ">");
+                        writerToMethod.put(writerId, method);
+                    } else {
+                        // {method} line is corrupted, other writer had possibly interjected;
+                        // honestly say we can't figure the method name out instead of lying.
+                        writerToMethod.put(writerId, "<name unparseable>");
                     }
                 } else if (elements.length >= 1 && elements[0].startsWith("0x")) {
                     // Seems to be line with address.
@@ -636,9 +661,11 @@
                         int idx = lines.size();
                         addressMap.put(addr, idx);
 
+                        // Record the starting address for the method, if any,
+                        String method = writerToMethod.get(writerId);
                         if (method != null) {
                             methodMap.put(addr, method);
-                            method = null;
+                            writerToMethod.remove(writerId);
                         }
 
                         asmLine = new ASMLine(addr, line);