OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 "use strict"; | 5 "use strict"; |
6 | 6 |
7 class DisassemblyView extends TextView { | 7 class DisassemblyView extends TextView { |
8 constructor(id, broker) { | 8 constructor(id, broker) { |
9 super(id, broker, null, false); | 9 super(id, broker, null, false); |
10 | 10 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 initializeContent(data, rememberedSelection) { | 152 initializeContent(data, rememberedSelection) { |
153 this.data = data; | 153 this.data = data; |
154 super.initializeContent(data, rememberedSelection); | 154 super.initializeContent(data, rememberedSelection); |
155 } | 155 } |
156 | 156 |
157 initializeCode(sourceText, sourcePosition) { | 157 initializeCode(sourceText, sourcePosition) { |
158 let view = this; | 158 let view = this; |
159 view.pos_start = -1; | 159 view.pos_start = -1; |
160 view.addr_event_counts = null; | 160 view.addr_event_counts = null; |
161 view.total_event_counts = null; | 161 view.total_event_counts = null; |
| 162 view.max_event_counts = null; |
162 view.pos_lines = new Array(); | 163 view.pos_lines = new Array(); |
163 // Comment lines for line 0 include sourcePosition already, only need to | 164 // Comment lines for line 0 include sourcePosition already, only need to |
164 // add sourcePosition for lines > 0. | 165 // add sourcePosition for lines > 0. |
165 view.pos_lines[0] = sourcePosition; | 166 view.pos_lines[0] = sourcePosition; |
166 if (sourceText != "") { | 167 if (sourceText != "") { |
167 let base = sourcePosition; | 168 let base = sourcePosition; |
168 let current = 0; | 169 let current = 0; |
169 let source_lines = sourceText.split("\n"); | 170 let source_lines = sourceText.split("\n"); |
170 for (let i = 1; i < source_lines.length; i++) { | 171 for (let i = 1; i < source_lines.length; i++) { |
171 // Add 1 for newline character that is split off. | 172 // Add 1 for newline character that is split off. |
172 current += source_lines[i-1].length + 1; | 173 current += source_lines[i-1].length + 1; |
173 view.pos_lines[i] = base + current; | 174 view.pos_lines[i] = base + current; |
174 } | 175 } |
175 } | 176 } |
176 } | 177 } |
177 | 178 |
178 initializePerfProfile(eventCounts) { | 179 initializePerfProfile(eventCounts) { |
179 let view = this; | 180 let view = this; |
180 if (eventCounts !== undefined) { | 181 if (eventCounts !== undefined) { |
181 view.addr_event_counts = eventCounts; | 182 view.addr_event_counts = eventCounts; |
182 | 183 |
183 view.total_event_counts = {}; | 184 view.total_event_counts = {}; |
184 for (var ev_name in view.addr_event_counts) { | 185 view.max_event_counts = {}; |
| 186 for (let ev_name in view.addr_event_counts) { |
185 let keys = Object.keys(view.addr_event_counts[ev_name]); | 187 let keys = Object.keys(view.addr_event_counts[ev_name]); |
186 let values = keys.map(key => view.addr_event_counts[ev_name][key]); | 188 let values = keys.map(key => view.addr_event_counts[ev_name][key]); |
187 view.total_event_counts[ev_name] = values.reduce((a, b) => a + b); | 189 view.total_event_counts[ev_name] = values.reduce((a, b) => a + b); |
| 190 view.max_event_counts[ev_name] = values.reduce((a, b) => Math.max(a, b))
; |
188 } | 191 } |
189 } | 192 } |
190 else { | 193 else { |
191 view.addr_event_counts = null; | 194 view.addr_event_counts = null; |
192 view.total_event_counts = null; | 195 view.total_event_counts = null; |
| 196 view.max_event_counts = null; |
193 } | 197 } |
194 } | 198 } |
195 | 199 |
196 // Shorten decimals and remove trailing zeroes for readability. | 200 // Shorten decimals and remove trailing zeroes for readability. |
197 humanize(num) { | 201 humanize(num) { |
198 return num.toFixed(3).replace(/\.?0+$/, "") + "%"; | 202 return num.toFixed(3).replace(/\.?0+$/, "") + "%"; |
199 } | 203 } |
200 | 204 |
| 205 // Interpolate between the given start and end values by a fraction of val/max
. |
| 206 interpolate(val, max, start, end) { |
| 207 return start + (end - start) * (val / max); |
| 208 } |
| 209 |
201 processLine(line) { | 210 processLine(line) { |
202 let view = this; | 211 let view = this; |
203 let func = function(match, p1, p2, p3) { | 212 let func = function(match, p1, p2, p3) { |
204 let nums = p2.split(":"); | 213 let nums = p2.split(":"); |
205 let li = Number(nums[0]); | 214 let li = Number(nums[0]); |
206 let pos = Number(nums[1]); | 215 let pos = Number(nums[1]); |
207 if(li === 0) | 216 if(li === 0) |
208 pos -= view.pos_lines[0]; | 217 pos -= view.pos_lines[0]; |
209 li++; | 218 li++; |
210 return p1 + li + ":" + pos + p3; | 219 return p1 + li + ":" + pos + p3; |
211 }; | 220 }; |
212 line = line.replace(view.SOURCE_POSITION_HEADER_REGEX, func); | 221 line = line.replace(view.SOURCE_POSITION_HEADER_REGEX, func); |
213 let fragments = super.processLine(line); | 222 let fragments = super.processLine(line); |
214 | 223 |
215 // Add profiling data per instruction if available. | 224 // Add profiling data per instruction if available. |
216 if (view.total_event_counts) { | 225 if (view.total_event_counts) { |
217 let event_selector = document.getElementById('event-selector'); | 226 let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); |
218 if (event_selector.length !== 0) { | 227 if (matches) { |
219 let event = event_selector.value; | 228 let newFragments = []; |
220 let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line); | 229 for (let event in view.addr_event_counts) { |
221 if (matches) { | |
222 let count = view.addr_event_counts[event][matches[1]]; | 230 let count = view.addr_event_counts[event][matches[1]]; |
223 let str = ""; | 231 let str = " "; |
224 let css_cls = undefined; | 232 let css_cls = "prof"; |
225 if(count !== undefined) { | 233 if(count !== undefined) { |
226 let perc = count / view.total_event_counts[event] * 100; | 234 let perc = count / view.total_event_counts[event] * 100; |
227 | 235 |
228 str = "(" + view.humanize(perc) + ") "; | 236 let col = { r: 255, g: 255, b: 255 }; |
| 237 for (let i = 0; i < PROF_COLS.length; i++) { |
| 238 if (perc === PROF_COLS[i].perc) { |
| 239 col = PROF_COLS[i].col; |
| 240 break; |
| 241 } |
| 242 else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc)
{ |
| 243 let col1 = PROF_COLS[i].col; |
| 244 let col2 = PROF_COLS[i + 1].col; |
229 | 245 |
230 css_cls = "prof-low"; | 246 let val = perc - PROF_COLS[i].perc; |
231 if(perc > PROF_HIGH) | 247 let max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc; |
232 css_cls = "prof-high"; | 248 |
233 else if(perc > PROF_MED) | 249 col.r = Math.round(view.interpolate(val, max, col1.r, col2.r)); |
234 css_cls = "prof-med"; | 250 col.g = Math.round(view.interpolate(val, max, col1.g, col2.g)); |
| 251 col.b = Math.round(view.interpolate(val, max, col1.b, col2.b)); |
| 252 break; |
| 253 } |
| 254 } |
| 255 |
| 256 str = UNICODE_BLOCK; |
| 257 |
| 258 let fragment = view.createFragment(str, css_cls); |
| 259 fragment.title = event + ": " + view.humanize(perc) + " (" + count +
")"; |
| 260 fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b
+ ")"; |
| 261 |
| 262 newFragments.push(fragment); |
235 } | 263 } |
236 // Pad extra spaces to keep alignment for all instructions. | 264 else |
237 str = (" ".repeat(10) + str).slice(-10); | 265 newFragments.push(view.createFragment(str, css_cls)); |
238 | 266 |
239 fragments.splice(0, 0, view.createFragment(str, css_cls)); | |
240 } | 267 } |
| 268 fragments = newFragments.concat(fragments); |
241 } | 269 } |
242 } | 270 } |
243 return fragments; | 271 return fragments; |
244 } | 272 } |
245 } | 273 } |
OLD | NEW |