1// Copyright 2020 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4import {formatBytes} from '../helper.mjs'; 5import {LogEntry} from './log.mjs'; 6 7class CodeString { 8 constructor(string) { 9 if (typeof string !== 'string') { 10 throw new Error('Expected string'); 11 } 12 this.string = string; 13 } 14 15 get isCode() { 16 return true; 17 } 18 19 toString() { 20 return this.string; 21 } 22} 23 24export class DeoptLogEntry extends LogEntry { 25 constructor( 26 type, time, entry, deoptReason, deoptLocation, scriptOffset, 27 instructionStart, codeSize, inliningId) { 28 super(type, time); 29 this._entry = entry; 30 this._reason = deoptReason; 31 this._location = deoptLocation; 32 this._scriptOffset = scriptOffset; 33 this._instructionStart = instructionStart; 34 this._codeSize = codeSize; 35 this._inliningId = inliningId; 36 this.fileSourcePosition = undefined; 37 } 38 39 get reason() { 40 return this._reason; 41 } 42 43 get location() { 44 return this._location; 45 } 46 47 get entry() { 48 return this._entry; 49 } 50 51 get code() { 52 return this._entry?.logEntry; 53 } 54 55 get functionName() { 56 return this._entry.functionName; 57 } 58 59 static get propertyNames() { 60 return [ 61 'type', 'reason', 'functionName', 'sourcePosition', 62 'functionSourcePosition', 'script', 'code' 63 ]; 64 } 65} 66 67class CodeLikeLogEntry extends LogEntry { 68 constructor(type, time, profilerEntry) { 69 super(type, time); 70 this._entry = profilerEntry; 71 profilerEntry.logEntry = this; 72 this._relatedEntries = []; 73 } 74 75 get entry() { 76 return this._entry; 77 } 78 79 add(entry) { 80 this._relatedEntries.push(entry); 81 } 82 83 relatedEntries() { 84 return this._relatedEntries; 85 } 86} 87 88export class CodeLogEntry extends CodeLikeLogEntry { 89 constructor(type, time, kindName, kind, profilerEntry) { 90 super(type, time, profilerEntry); 91 this._kind = kind; 92 this._kindName = kindName; 93 this._feedbackVector = undefined; 94 } 95 96 get kind() { 97 return this._kind; 98 } 99 100 get isBuiltinKind() { 101 return this._kindName === 'Builtin'; 102 } 103 104 get isBytecodeKind() { 105 return this._kindName === 'Unopt'; 106 } 107 108 get kindName() { 109 return this._kindName; 110 } 111 112 get functionName() { 113 return this._entry.functionName ?? this._entry.getRawName(); 114 } 115 116 get size() { 117 return this._entry.size; 118 } 119 120 get source() { 121 return this._entry?.getSourceCode() ?? ''; 122 } 123 124 get code() { 125 return this._entry?.source?.disassemble; 126 } 127 128 get variants() { 129 const entries = Array.from(this.entry?.func?.codeEntries ?? []); 130 return entries.map(each => each.logEntry); 131 } 132 133 get feedbackVector() { 134 return this._feedbackVector; 135 } 136 137 setFeedbackVector(fbv) { 138 if (this._feedbackVector) { 139 throw new Error('Double setting FeedbackVector'); 140 } 141 this._feedbackVector = fbv; 142 } 143 144 toString() { 145 return `Code(${this.type})`; 146 } 147 148 get toolTipDict() { 149 const dict = super.toolTipDict; 150 dict.size = formatBytes(dict.size); 151 dict.source = new CodeString(dict.source); 152 dict.code = new CodeString(dict.code); 153 return dict; 154 } 155 156 static get propertyNames() { 157 return [ 158 'functionName', 'sourcePosition', 'kindName', 'size', 'type', 'kind', 159 'script', 'source', 'code', 'feedbackVector', 'variants' 160 ]; 161 } 162} 163 164export class FeedbackVectorEntry extends LogEntry { 165 constructor( 166 timestamp, codeEntry, fbvAddress, length, optimizationMarker, 167 optimizationTier, invocationCount, profilerTicks, string) { 168 super('FeedbackVector', timestamp); 169 this._length = length; 170 this._code = codeEntry; 171 this._string = string; 172 this._optimizationMarker = optimizationMarker; 173 this._optimizationTier = optimizationTier; 174 this._invocationCount = invocationCount; 175 this._profilerTicks = profilerTicks; 176 } 177 178 toString() { 179 return `FeedbackVector(l=${this.length})` 180 } 181 182 get length() { 183 return this._length; 184 } 185 186 get code() { 187 return this._code; 188 } 189 190 get string() { 191 return this._string; 192 } 193 194 get optimizationMarker() { 195 return this._optimizationMarker; 196 } 197 198 get optimizationTier() { 199 return this._optimizationTier; 200 } 201 202 get invocationCount() { 203 return this._invocationCount; 204 } 205 206 get profilerTicks() { 207 return this._profilerTicks; 208 } 209 210 static get propertyNames() { 211 return [ 212 'length', 'length', 'code', 'optimizationMarker', 'optimizationTier', 213 'invocationCount', 'profilerTicks', 'string' 214 ]; 215 } 216} 217 218export class SharedLibLogEntry extends CodeLikeLogEntry { 219 constructor(profilerEntry) { 220 super('SHARED_LIB', 0, profilerEntry); 221 } 222 223 get name() { 224 return this._entry.name; 225 } 226 227 toString() { 228 return `SharedLib`; 229 } 230 231 static get propertyNames() { 232 return ['name']; 233 } 234} 235