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 | import sys | 13 | import sys |
| 14 | import json | 14 | import json |
| 15 | import argparse | 15 | import argparse |
| 16 | from functools import reduce | ||
| 16 | from dataclasses import dataclass, field | 17 | from dataclasses import dataclass, field |
| 17 | from typing import List, Dict, Optional, NamedTuple, Set, Tuple, Any | 18 | from typing import List, Dict, Optional, NamedTuple, Set, Tuple, Any |
| 18 | 19 | ||
| @@ -39,6 +40,10 @@ CATEGORIES = None · 20 unmodified lines | |||
| 39 | # The product name is used by the profiler UI to show the Operating system and Processor. | 40 | # The product name is used by the profiler UI to show the Operating system and Processor. |
| 40 | PRODUCT = os.popen('uname -op').read().strip() | 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 | # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L156 | 47 | # https://github.com/firefox-devtools/profiler/blob/53970305b51b9b472e26d7457fee1d66cd4e2737/src/types/gecko-profile.js#L156 |
| 43 | class Frame(NamedTuple): | 48 | class Frame(NamedTuple): |
| 44 | string_id: StringID | 49 | string_id: StringID |
| @@ -99,6 +104,55 @@ class Thread: · 54 unmodified lines | |||
| 99 | stackMap: Dict[Tuple[Optional[int], int], int] = field(default_factory=dict) | 104 | stackMap: Dict[Tuple[Optional[int], int], int] = field(default_factory=dict) |
| 100 | frameMap: Dict[str, int] = field(default_factory=dict) | 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 | def _to_json_dict(self) -> Dict: | 156 | def _to_json_dict(self) -> Dict: |
| 103 | """Converts current Thread to GeckoThread JSON format.""" | 157 | """Converts current Thread to GeckoThread JSON format.""" |
| 104 | # Gecko profile format is row-oriented data as List[List], | 158 | # Gecko profile format is row-oriented data as List[List], |