Bug 915857 - Check-in merge-profiles.py. r=vladan
authorBenoit Girard <b56girard@gmail.com>
Thu, 12 Sep 2013 16:31:40 -0400
changeset 159822 ed734d586569a814f333c22d5784fc330fcc981c
parent 159821 ac358468967bbc47c6cb790f6be5535041467c96
child 159823 b4c41406c20268bd2ee84e18f83d8fb86f9282b0
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan
bugs915857
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 915857 - Check-in merge-profiles.py. r=vladan
tools/profiler/TableTicker.cpp
tools/profiler/merge-profiles.py
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -96,16 +96,19 @@ JSCustomObject* TableTicker::GetMetaJSCu
   JSCustomObject *meta = b.CreateObject();
 
   b.DefineProperty(meta, "version", 2);
   b.DefineProperty(meta, "interval", interval());
   b.DefineProperty(meta, "stackwalk", mUseStackWalk);
   b.DefineProperty(meta, "jank", mJankOnly);
   b.DefineProperty(meta, "processType", XRE_GetProcessType());
 
+  TimeDuration delta = TimeStamp::Now() - sStartTime;
+  b.DefineProperty(meta, "startTime", PR_Now()/1000.0f - delta.ToMilliseconds());
+
   nsresult res;
   nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &res);
   if (!NS_FAILED(res)) {
     nsAutoCString string;
 
     res = http->GetPlatform(string);
     if (!NS_FAILED(res))
       b.DefineProperty(meta, "platform", string.Data());
new file mode 100755
--- /dev/null
+++ b/tools/profiler/merge-profiles.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python 
+#
+# This script takes b2g process profiles and merged them into a single profile.
+# The meta data is taken from the first profile. The startTime for each profile
+# is used to syncronized the samples. Each thread is moved into the merged
+# profile.
+#
+import json
+import re
+import sys
+
+def MergeProfiles(files):
+    threads = []
+    fileData = []
+    symTable = dict()
+    meta = None
+    libs = None
+    minStartTime = None
+
+    for fname in files:
+        match = re.match('profile_([0-9]+)_(.+)\.sym', fname)
+        if match is None:
+            raise Exception("Filename '" + fname + "' doesn't match expected pattern")
+        pid = match.groups(0)[0]
+        pname = match.groups(0)[1]
+
+        fp = open(fname, "r")
+        fileData = json.load(fp)
+        fp.close()
+
+        if meta is None:
+            meta = fileData['profileJSON']['meta'].copy()
+            libs = fileData['profileJSON']['libs']
+            minStartTime = meta['startTime']
+        else:
+            minStartTime = min(minStartTime, fileData['profileJSON']['meta']['startTime'])
+            meta['startTime'] = minStartTime
+
+        thread = fileData['profileJSON']['threads'][0]
+        thread['name'] = pname + " (" + pid + ")"
+        threads.append(thread)
+
+        # Note that pid + sym, pid + location could be ambigious
+        # if we had pid=11 sym=1 && pid=1 sym=11. To avoid this we format
+        # pidStr with leading zeros.
+        pidStr = "%05d" % (int(pid))
+
+        thread['startTime'] = fileData['profileJSON']['meta']['startTime']
+        samples = thread['samples']
+        for sample in thread['samples']:
+            for frame in sample['frames']:
+                if "location" in frame and frame['location'][0:2] == '0x':
+                    frame['location'] = pidStr + frame['location']
+
+        filesyms = fileData['symbolicationTable']
+        for sym in filesyms.keys():
+            symTable[pidStr + sym] = filesyms[sym]
+
+    # For each process, make the time offsets line up based on the
+    # earliest start
+    for thread in threads:
+        delta = thread['startTime'] - minStartTime
+        for sample in thread['samples']:
+            if "time" in sample:
+                sample['time'] += delta
+
+    result = dict()
+    result['profileJSON'] = dict()
+    result['profileJSON']['meta'] = meta
+    result['profileJSON']['libs'] = libs
+    result['profileJSON']['threads'] = threads
+    result['symbolicationTable'] = symTable
+    result['format'] = "profileJSONWithSymbolicationTable,1"
+
+    json.dump(result, sys.stdout)
+
+
+if len(sys.argv) > 1:
+    MergeProfiles(sys.argv[1:])
+    sys.exit(0)
+
+print "Usage: merge-profile.py profile_<pid1>_<pname1>.sym profile_<pid2>_<pname2>.sym > merged.sym"
+
+
+