Bumping gaia.json for 1 gaia revision(s) a=gaia-bump
[gecko.git] / tools / profiler / merge-profiles.py
blob399cdce27a7d6798a3b543adfc78c021225c9567
1 #!/usr/bin/env python
3 # This script takes b2g process profiles and merged them into a single profile.
4 # The meta data is taken from the first profile. The startTime for each profile
5 # is used to syncronized the samples. Each thread is moved into the merged
6 # profile.
8 import json
9 import re
10 import sys
12 def MergeProfiles(files):
13 threads = []
14 fileData = []
15 symTable = dict()
16 meta = None
17 libs = None
18 videoUrl = None
19 minStartTime = None
21 for fname in files:
22 if fname.startswith("--video="):
23 videoUrl = fname[8:]
24 continue
26 match = re.match('profile_([0-9]+)_(.+)\.sym', fname)
27 if match is None:
28 raise Exception("Filename '" + fname + "' doesn't match expected pattern")
29 pid = match.groups(0)[0]
30 pname = match.groups(0)[1]
32 fp = open(fname, "r")
33 fileData = json.load(fp)
34 fp.close()
36 if meta is None:
37 meta = fileData['profileJSON']['meta'].copy()
38 libs = fileData['profileJSON']['libs']
39 minStartTime = meta['startTime']
40 else:
41 minStartTime = min(minStartTime, fileData['profileJSON']['meta']['startTime'])
42 meta['startTime'] = minStartTime
44 for thread in fileData['profileJSON']['threads']:
45 thread['name'] = thread['name'] + " (" + pname + ":" + pid + ")"
46 threads.append(thread)
48 # Note that pid + sym, pid + location could be ambigious
49 # if we had pid=11 sym=1 && pid=1 sym=11.
50 pidStr = pid + ":"
52 thread['startTime'] = fileData['profileJSON']['meta']['startTime']
53 samples = thread['samples']
54 for sample in thread['samples']:
55 for frame in sample['frames']:
56 if "location" in frame and frame['location'][0:2] == '0x':
57 oldLoc = frame['location']
58 newLoc = pidStr + oldLoc
59 frame['location'] = newLoc
60 # Default to the unprefixed symbol if no translation is available
61 symTable[newLoc] = oldLoc
63 filesyms = fileData['symbolicationTable']
64 for sym in filesyms.keys():
65 symTable[pidStr + sym] = filesyms[sym]
67 # For each thread, make the time offsets line up based on the
68 # earliest start
69 for thread in threads:
70 delta = thread['startTime'] - minStartTime
71 for sample in thread['samples']:
72 if "time" in sample:
73 sample['time'] += delta
74 for marker in thread['markers']:
75 marker['time'] += delta
77 result = dict()
78 result['profileJSON'] = dict()
79 result['profileJSON']['meta'] = meta
80 result['profileJSON']['libs'] = libs
81 result['profileJSON']['threads'] = threads
82 result['symbolicationTable'] = symTable
83 result['format'] = "profileJSONWithSymbolicationTable,1"
84 if videoUrl:
85 result['profileJSON']['meta']['videoCapture'] = {"src": videoUrl}
87 json.dump(result, sys.stdout)
90 if len(sys.argv) > 1:
91 MergeProfiles(sys.argv[1:])
92 sys.exit(0)
94 print "Usage: merge-profile.py profile_<pid1>_<pname1>.sym profile_<pid2>_<pname2>.sym > merged.sym"