History

perf scripts python: Add classes and conversion functions

This commit introduces new classes and conversion functions to facilitate the representation of Gecko profile information. The new classes Frame, Stack, Sample, and Thread are added to handle specific components of the profile data, also link to the origin docs has been commented out. Additionally, Inside the Thread class _to_json_dict() method has been created that converts the current thread data into the corresponding format expected by the GeckoThread JSON schema, as per the Gecko profile format specification.

Anup Sharma committed 3 years ago

Commit 5aacd7f1 parent 0a02e441 file · +132 −1Browse files

Showing the changes to tools/perf/scripts/python (1 of 1 file). Show all

Unified · Split

tools/perf/scripts/python/gecko.py+132−1
@@ -11,7 +11,8 @@ · 10 unmodified lines
1111
1212 import os
1313 import sys
14−from typing import Dict
14+from dataclasses import dataclass, field
15+from typing import List, Dict, Optional, NamedTuple, Set, Tuple, Any
1516
1617 # Add the Perf-Trace-Util library to the Python path
1718 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
@@ -20,9 +21,139 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ · 2 unmodified lines
2021 from perf_trace_context import *
2122 from Core import *
2223
24+StringID = int
25+StackID = int
26+FrameID = int
27+CategoryID = int
28+Milliseconds = float
29+
2330 # start_time is intialiazed only once for the all event traces.
2431 start_time = None
2532
33+# https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L156
34+class Frame(NamedTuple):
35+ string_id: StringID
36+ relevantForJS: bool
37+ innerWindowID: int
38+ implementation: None
39+ optimizations: None
40+ line: None
41+ column: None
42+ category: CategoryID
43+ subcategory: int
44+
45+# https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L216
46+class Stack(NamedTuple):
47+ prefix_id: Optional[StackID]
48+ frame_id: FrameID
49+
50+# https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L90
51+class Sample(NamedTuple):
52+ stack_id: Optional[StackID]
53+ time_ms: Milliseconds
54+ responsiveness: int
55+
56+@dataclass
57+class Thread:
58+ """A builder for a profile of the thread.
59+
60+ Attributes:
61+ comm: Thread command-line (name).
62+ pid: process ID of containing process.
63+ tid: thread ID.
64+ samples: Timeline of profile samples.
65+ frameTable: interned stack frame ID -> stack frame.
66+ stringTable: interned string ID -> string.
67+ stringMap: interned string -> string ID.
68+ stackTable: interned stack ID -> stack.
69+ stackMap: (stack prefix ID, leaf stack frame ID) -> interned Stack ID.
70+ frameMap: Stack Frame string -> interned Frame ID.
71+ comm: str
72+ pid: int
73+ tid: int
74+ samples: List[Sample] = field(default_factory=list)
75+ frameTable: List[Frame] = field(default_factory=list)
76+ stringTable: List[str] = field(default_factory=list)
77+ stringMap: Dict[str, int] = field(default_factory=dict)
78+ stackTable: List[Stack] = field(default_factory=list)
79+ stackMap: Dict[Tuple[Optional[int], int], int] = field(default_factory=dict)
80+ frameMap: Dict[str, int] = field(default_factory=dict)
81+ """
82+ comm: str
83+ pid: int
84+ tid: int
85+ samples: List[Sample] = field(default_factory=list)
86+ frameTable: List[Frame] = field(default_factory=list)
87+ stringTable: List[str] = field(default_factory=list)
88+ stringMap: Dict[str, int] = field(default_factory=dict)
89+ stackTable: List[Stack] = field(default_factory=list)
90+ stackMap: Dict[Tuple[Optional[int], int], int] = field(default_factory=dict)
91+ frameMap: Dict[str, int] = field(default_factory=dict)
92+
93+ def _to_json_dict(self) -> Dict:
94+ """Converts current Thread to GeckoThread JSON format."""
95+ # Gecko profile format is row-oriented data as List[List],
96+ # And a schema for interpreting each index.
97+ # Schema:
98+ # https://github.com/firefox-devtools/profiler/blob/main/docs-developer/gecko-profile-format.md
99+ # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L230
100+ return {
101+ "tid": self.tid,
102+ "pid": self.pid,
103+ "name": self.comm,
104+ # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L51
105+ "markers": {
106+ "schema": {
107+ "name": 0,
108+ "startTime": 1,
109+ "endTime": 2,
110+ "phase": 3,
111+ "category": 4,
112+ "data": 5,
113+ },
114+ "data": [],
115+ },
116+
117+ # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L90
118+ "samples": {
119+ "schema": {
120+ "stack": 0,
121+ "time": 1,
122+ "responsiveness": 2,
123+ },
124+ "data": self.samples
125+ },
126+
127+ # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L156
128+ "frameTable": {
129+ "schema": {
130+ "location": 0,
131+ "relevantForJS": 1,
132+ "innerWindowID": 2,
133+ "implementation": 3,
134+ "optimizations": 4,
135+ "line": 5,
136+ "column": 6,
137+ "category": 7,
138+ "subcategory": 8,
139+ },
140+ "data": self.frameTable,
141+ },
142+
143+ # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L216
144+ "stackTable": {
145+ "schema": {
146+ "prefix": 0,
147+ "frame": 1,
148+ },
149+ "data": self.stackTable,
150+ },
151+ "stringTable": self.stringTable,
152+ "registerTime": 0,
153+ "unregisterTime": None,
154+ "processType": "default",
155+ }
156+
26157 # Uses perf script python interface to parse each
27158 # event and store the data in the thread builder.
28159 def process_event(param_dict: Dict) -> None: