The intern_stack function is responsible for retrieving or creating a stack_id based on the provided frame_id and prefix_id. It first generates a key using the frame_id and prefix_id values. If the stack corresponding to the key is found in the stackMap, it is returned. Otherwise, a new stack is created by appending the prefix_id and frame_id to the stackTable. The key and the index of the newly created stack are added to the stackMap for future reference. The _intern_frame function is responsible for retrieving or creating a frame_id based on the provided frame string. If the frame_id corresponding to the frameString is found in the frameMap, it is returned. Otherwise, a new frame is created by appending relevant information to the frameTable and adding the frameString to the string_id through _intern_string. The _intern_string function will gets a matching string, or saves the new string and returns a String ID.
Showing the changes to tools/perf/scripts/python (1 of 1 file). Show all
Unified · Split
| @@ -13,6 +13,7 @@ import os · 12 unmodified lines | ||
| 13 | 13 | import sys |
| 14 | 14 | import json |
| 15 | 15 | import argparse |
| 16 | +from functools import reduce | |
| 16 | 17 | from dataclasses import dataclass, field |
| 17 | 18 | from typing import List, Dict, Optional, NamedTuple, Set, Tuple, Any |
| 18 | 19 | |
| @@ -39,6 +40,10 @@ CATEGORIES = None · 20 unmodified lines | ||
| 39 | 40 | # The product name is used by the profiler UI to show the Operating system and Processor. |
| 40 | 41 | PRODUCT = os.popen('uname -op').read().strip() |
| 41 | 42 | |
| 43 | +# The category index is used by the profiler UI to show the color of the flame graph. | |
| 44 | +USER_CATEGORY_INDEX = 0 | |
| 45 | +KERNEL_CATEGORY_INDEX = 1 | |
| 46 | + | |
| 42 | 47 | # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L156 |
| 43 | 48 | class Frame(NamedTuple): |
| 44 | 49 | string_id: StringID |
| @@ -99,6 +104,55 @@ class Thread: · 54 unmodified lines | ||
| 99 | 104 | stackMap: Dict[Tuple[Optional[int], int], int] = field(default_factory=dict) |
| 100 | 105 | frameMap: Dict[str, int] = field(default_factory=dict) |
| 101 | 106 | |
| 107 | + def _intern_stack(self, frame_id: int, prefix_id: Optional[int]) -> int: | |
| 108 | + """Gets a matching stack, or saves the new stack. Returns a Stack ID.""" | |
| 109 | + key = f"{frame_id}" if prefix_id is None else f"{frame_id},{prefix_id}" | |
| 110 | + # key = (prefix_id, frame_id) | |
| 111 | + stack_id = self.stackMap.get(key) | |
| 112 | + if stack_id is None: | |
| 113 | + # return stack_id | |
| 114 | + stack_id = len(self.stackTable) | |
| 115 | + self.stackTable.append(Stack(prefix_id=prefix_id, frame_id=frame_id)) | |
| 116 | + self.stackMap[key] = stack_id | |
| 117 | + return stack_id | |
| 118 | + | |
| 119 | + def _intern_string(self, string: str) -> int: | |
| 120 | + """Gets a matching string, or saves the new string. Returns a String ID.""" | |
| 121 | + string_id = self.stringMap.get(string) | |
| 122 | + if string_id is not None: | |
| 123 | + return string_id | |
| 124 | + string_id = len(self.stringTable) | |
| 125 | + self.stringTable.append(string) | |
| 126 | + self.stringMap[string] = string_id | |
| 127 | + return string_id | |
| 128 | + | |
| 129 | + def _intern_frame(self, frame_str: str) -> int: | |
| 130 | + """Gets a matching stack frame, or saves the new frame. Returns a Frame ID.""" | |
| 131 | + frame_id = self.frameMap.get(frame_str) | |
| 132 | + if frame_id is not None: | |
| 133 | + return frame_id | |
| 134 | + frame_id = len(self.frameTable) | |
| 135 | + self.frameMap[frame_str] = frame_id | |
| 136 | + string_id = self._intern_string(frame_str) | |
| 137 | + | |
| 138 | + symbol_name_to_category = KERNEL_CATEGORY_INDEX if frame_str.find('kallsyms') != -1 \ | |
| 139 | + or frame_str.find('/vmlinux') != -1 \ | |
| 140 | + or frame_str.endswith('.ko)') \ | |
| 141 | + else USER_CATEGORY_INDEX | |
| 142 | + | |
| 143 | + self.frameTable.append(Frame( | |
| 144 | + string_id=string_id, | |
| 145 | + relevantForJS=False, | |
| 146 | + innerWindowID=0, | |
| 147 | + implementation=None, | |
| 148 | + optimizations=None, | |
| 149 | + line=None, | |
| 150 | + column=None, | |
| 151 | + category=symbol_name_to_category, | |
| 152 | + subcategory=None, | |
| 153 | + )) | |
| 154 | + return frame_id | |
| 155 | + | |
| 102 | 156 | def _to_json_dict(self) -> Dict: |
| 103 | 157 | """Converts current Thread to GeckoThread JSON format.""" |
| 104 | 158 | # Gecko profile format is row-oriented data as List[List], |