1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {Utils} from "../component/trace/base/Utils.js"; 17import {ChartStruct} from "../../trace/bean/FrameChartStruct.js"; 18import {SpHiPerf} from "../component/chart/SpHiPerf.js"; 19 20export class PerfFile { 21 fileId: number = 0; 22 symbol: string = "" 23 path: string = "" 24 fileName: string = "" 25 26 static setFileName(data: PerfFile) { 27 if (data.path) { 28 let number = data.path.lastIndexOf("/"); 29 if (number > 0) { 30 data.fileName = data.path.substring(number + 1) 31 return 32 } 33 } 34 data.fileName = data.path 35 } 36 37 setFileName() { 38 if (this.path) { 39 let number = this.path.lastIndexOf("/"); 40 if (number > 0) { 41 this.fileName = this.path.substring(number + 1) 42 return 43 } 44 } 45 this.fileName = this.path 46 } 47} 48 49export class PerfThread { 50 tid: number = 0; 51 pid: number = 0; 52 threadName: string = ""; 53 processName: string = ""; 54} 55 56export class PerfCall{ 57 sampleId: number = 0; 58 depth: number = 0; 59 name: string = ""; 60} 61 62export class PerfCallChain { 63 tid: number = 0; 64 pid: number = 0; 65 name: string = "" 66 fileName: string = ""; 67 threadState: string = ""; 68 startNS: number = 0; 69 dur: number = 0; 70 sampleId: number = 0; 71 callChainId: number = 0; 72 vaddrInFile: number = 0; 73 fileId: number = 0; 74 symbolId: number = 0; 75 path: string = ""; 76 parentId: string = ""//合并之后区分的id 77 id: string = "" 78 topDownMerageId: string = ""//top down合并使用的id 79 topDownMerageParentId: string = ""//top down合并使用的id 80 bottomUpMerageId: string = ""//bottom up合并使用的id 81 bottomUpMerageParentId: string = ""//bottom up合并使用的id 82 depth: number = 0; 83 canCharge:boolean = true 84 previousNode: PerfCallChain | undefined = undefined;//将list转换为一个链表结构 85 nextNode: PerfCallChain | undefined = undefined; 86 87 static setNextNode(currentNode: PerfCallChain, nextNode: PerfCallChain) { 88 currentNode.nextNode = nextNode 89 nextNode.previousNode = currentNode 90 } 91 92 static setPreviousNode(currentNode: PerfCallChain, prevNode: PerfCallChain) { 93 currentNode.previousNode = prevNode 94 prevNode.nextNode = currentNode 95 } 96 97 static merageCallChain(currentNode: PerfCallChain, callChain: PerfCallChain) { 98 currentNode.startNS = callChain.startNS 99 currentNode.tid = callChain.tid 100 currentNode.pid = callChain.pid 101 currentNode.sampleId = callChain.sampleId 102 currentNode.dur = callChain.dur 103 } 104 105} 106 107export class PerfCallChainMerageData extends ChartStruct { 108 #parentNode: PerfCallChainMerageData | undefined = undefined 109 #total = 0 110 id: string = ""; 111 parentId: string = ""; 112 currentTreeParentNode: PerfCallChainMerageData | undefined = undefined; 113 symbolName: string = ""; 114 symbol: string = "" 115 libName: string = "" 116 path: string = "" 117 self: string = "0s" 118 weight: string = "" 119 weightPercent: string = "" 120 selfDur: number = 0; 121 dur: number = 0; 122 tid: number = 0; 123 pid: number = 0; 124 isStore = 0; 125 canCharge:boolean = true 126 children: PerfCallChainMerageData[] = [] 127 initChildren: PerfCallChainMerageData[] = [] 128 type: number = 0; 129 vaddrInFile: number = 0; 130 isSelected: boolean = false; 131 searchShow: boolean = true; 132 133 set parentNode(data: PerfCallChainMerageData | undefined) { 134 this.currentTreeParentNode = data; 135 this.#parentNode = data; 136 } 137 138 get parentNode() { 139 return this.#parentNode 140 } 141 142 set total(data: number) { 143 this.#total = data; 144 this.weight = `${Utils.timeMsFormat2p(this.dur * (SpHiPerf.stringResult?.fValue || 1))}` 145 this.weightPercent = `${(this.dur / data * 100).toFixed(1)}%` 146 } 147 148 get total() { 149 return this.#total; 150 } 151 152 static merageCallChain(currentNode: PerfCallChainMerageData, callChain: PerfCallChain, isTopDown: boolean) { 153 if (currentNode.symbolName == "") { 154 currentNode.symbol = `${callChain.name} ${callChain.fileName ? `(${callChain.fileName})` : ""}` 155 currentNode.symbolName = callChain.name 156 currentNode.pid = callChain.pid 157 currentNode.tid = callChain.tid 158 currentNode.libName = callChain.fileName 159 currentNode.vaddrInFile = callChain.vaddrInFile; 160 currentNode.canCharge = callChain.canCharge 161 if (callChain.path) { 162 currentNode.path = callChain.path 163 } 164 } 165 if (callChain[isTopDown ? "nextNode" : "previousNode"] == undefined) { 166 currentNode.selfDur++; 167 currentNode.self = Utils.timeMsFormat2p(currentNode.selfDur) 168 } 169 currentNode.dur++; 170 currentNode.count++; 171 } 172} 173 174export class PerfSample { 175 sampleId: number = 0; 176 time: number = 0; 177 timeString: string = ""; 178 core: number = 0; 179 coreName: string = ""; 180 state: string = ""; 181 pid: number = 0; 182 processName: string = ""; 183 tid: number = 0; 184 threadName: string = ""; 185 depth: number = 0; 186 addr: string = ""; 187 fileId: number = 0; 188 symbolId: number = 0; 189 backtrace: Array<string> = []; 190} 191 192export class PerfStack { 193 symbol: string = ""; 194 symbolId: number = 0; 195 path: string = ""; 196 fileId: number = 0; 197 type: number = 0; 198 vaddrInFile: number = 0; 199} 200 201export class PerfCmdLine { 202 report_value: string = ""; 203}