mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Requires servo/servo#37045 for deps and config. Testing: No need for tests to test tests. Fixes: servo/servo#37041 --------- Signed-off-by: zefr0x <zer0-x.7ty50@aleeas.com>
155 lines
4.3 KiB
Python
155 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright 2018 The Servo Project Developers. See the COPYRIGHT
|
|
# file at the top-level directory of this distribution.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
# option. This file may not be copied, modified, or distributed
|
|
# except according to those terms.
|
|
|
|
# Script to take raw sample output from Servo sampling profiler and
|
|
# output a [processed profile]. Based largely on [this script] and
|
|
# [this documentation].
|
|
#
|
|
# [processed profile]: https://github.com/firefox-devtools/profiler/blob/main/docs-developer/processed-profile-format.md
|
|
# [this script]: https://github.com/firefox-devtools/profiler/blob/main/src/profile-logic/import/linux-perf.js
|
|
# [this documentation]: https://github.com/firefox-devtools/profiler/blob/main/src/types/profile.js
|
|
|
|
from collections import defaultdict
|
|
import json
|
|
import sys
|
|
|
|
|
|
class StringTable:
|
|
def __init__(self):
|
|
self.table = {}
|
|
self.idx = 0
|
|
|
|
def get(self, s):
|
|
assert s
|
|
if s not in self.table:
|
|
self.table[s] = self.idx
|
|
self.idx += 1
|
|
return self.table[s]
|
|
|
|
def length(self):
|
|
return len(list(self.table.keys()))
|
|
|
|
def contents(self):
|
|
return sorted(list(self.table.keys()), key=self.table.__getitem__)
|
|
|
|
|
|
with open(sys.argv[1]) as f:
|
|
profile = json.load(f)
|
|
rate = profile["rate"]
|
|
samples = profile["data"]
|
|
startTime = profile["start"]
|
|
|
|
frames = {}
|
|
stacks = {}
|
|
|
|
thread_data = defaultdict(list)
|
|
thread_order = {}
|
|
for sample in samples:
|
|
if sample["name"]:
|
|
name = sample["name"]
|
|
else:
|
|
name = "%s %d %d" % (sample["type"], sample["namespace"], sample["index"])
|
|
thread_data[name].append((sample["time"], sample["frames"]))
|
|
if name not in thread_order:
|
|
thread_order[name] = (sample["namespace"], sample["index"])
|
|
|
|
tid = 0
|
|
threads = []
|
|
for name, raw_samples in sorted(iter(thread_data.items()), key=lambda x: thread_order[x[0]]):
|
|
string_table = StringTable()
|
|
tid += 1
|
|
|
|
stackMap = {}
|
|
stacks = []
|
|
frameMap = {}
|
|
frames = []
|
|
|
|
samples = []
|
|
|
|
for sample in raw_samples:
|
|
prefix = None
|
|
for frame in sample[1]:
|
|
if not frame["name"]:
|
|
continue
|
|
if frame["name"] not in frameMap:
|
|
frameMap[frame["name"]] = len(frames)
|
|
frame_index = string_table.get(frame["name"])
|
|
frames.append([frame_index])
|
|
frame = frameMap[frame["name"]]
|
|
|
|
stack_key = "%d,%d" % (frame, prefix) if prefix else str(frame)
|
|
if stack_key not in stackMap:
|
|
stackMap[stack_key] = len(stacks)
|
|
stacks.append([frame, prefix])
|
|
stack = stackMap[stack_key]
|
|
prefix = stack
|
|
samples.append([stack, sample[0]])
|
|
|
|
threads.append(
|
|
{
|
|
"tid": tid,
|
|
"name": name,
|
|
"markers": {
|
|
"schema": {
|
|
"name": 0,
|
|
"time": 1,
|
|
"data": 2,
|
|
},
|
|
"data": [],
|
|
},
|
|
"samples": {
|
|
"schema": {
|
|
"stack": 0,
|
|
"time": 1,
|
|
"responsiveness": 2,
|
|
"rss": 2,
|
|
"uss": 4,
|
|
"frameNumber": 5,
|
|
},
|
|
"data": samples,
|
|
},
|
|
"frameTable": {
|
|
"schema": {
|
|
"location": 0,
|
|
"implementation": 1,
|
|
"optimizations": 2,
|
|
"line": 3,
|
|
"category": 4,
|
|
},
|
|
"data": frames,
|
|
},
|
|
"stackTable": {
|
|
"schema": {
|
|
"frame": 0,
|
|
"prefix": 1,
|
|
},
|
|
"data": stacks,
|
|
},
|
|
"stringTable": string_table.contents(),
|
|
}
|
|
)
|
|
|
|
|
|
output = {
|
|
"meta": {
|
|
"interval": rate,
|
|
"processType": 0,
|
|
"product": "Servo",
|
|
"stackwalk": 1,
|
|
"startTime": startTime,
|
|
"version": 4,
|
|
"presymbolicated": True,
|
|
},
|
|
"libs": [],
|
|
"threads": threads,
|
|
}
|
|
|
|
print(json.dumps(output))
|