Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium 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 | 5 |
| 6 WebInspector.TimelineJSProfileProcessor = { }; | 6 WebInspector.TimelineJSProfileProcessor = { }; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * @param {!ProfilerAgent.CPUProfile} jsProfile | 9 * @param {!ProfilerAgent.CPUProfile} jsProfile |
| 10 * @param {!WebInspector.TracingModel.Thread} thread | 10 * @param {!WebInspector.TracingModel.Thread} thread |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 | 197 |
| 198 WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, on InstantEvent); | 198 WebInspector.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, on InstantEvent); |
| 199 return jsFrameEvents; | 199 return jsFrameEvents; |
| 200 } | 200 } |
| 201 | 201 |
| 202 /** | 202 /** |
| 203 * @constructor | 203 * @constructor |
| 204 */ | 204 */ |
| 205 WebInspector.TimelineJSProfileProcessor.CodeMap = function() | 205 WebInspector.TimelineJSProfileProcessor.CodeMap = function() |
| 206 { | 206 { |
| 207 /** @type {!Array<!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry>} * / | 207 /** @type {!Map<string, !WebInspector.TimelineJSProfileProcessor.CodeMap.Ban k>} */ |
| 208 this._entries = []; | 208 this._banks = new Map(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 /** | 211 /** |
| 212 * @constructor | 212 * @constructor |
| 213 * @param {number} address | 213 * @param {number} address |
| 214 * @param {number} size | 214 * @param {number} size |
| 215 * @param {!ConsoleAgent.CallFrame} callFrame | 215 * @param {!ConsoleAgent.CallFrame} callFrame |
| 216 */ | 216 */ |
| 217 WebInspector.TimelineJSProfileProcessor.CodeMap.Entry = function(address, size, callFrame) | 217 WebInspector.TimelineJSProfileProcessor.CodeMap.Entry = function(address, size, callFrame) |
| 218 { | 218 { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 232 } | 232 } |
| 233 | 233 |
| 234 WebInspector.TimelineJSProfileProcessor.CodeMap.prototype = { | 234 WebInspector.TimelineJSProfileProcessor.CodeMap.prototype = { |
| 235 /** | 235 /** |
| 236 * @param {string} addressHex | 236 * @param {string} addressHex |
| 237 * @param {number} size | 237 * @param {number} size |
| 238 * @param {!ConsoleAgent.CallFrame} callFrame | 238 * @param {!ConsoleAgent.CallFrame} callFrame |
| 239 */ | 239 */ |
| 240 addEntry: function(addressHex, size, callFrame) | 240 addEntry: function(addressHex, size, callFrame) |
| 241 { | 241 { |
| 242 var address = this._addressStringToNumber(addressHex); | 242 var entry = new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry(th is._getAddress(addressHex), size, callFrame); |
| 243 this._addEntry(new WebInspector.TimelineJSProfileProcessor.CodeMap.Entry (address, size, callFrame)); | 243 this._addEntry(addressHex, entry); |
| 244 }, | 244 }, |
| 245 | 245 |
| 246 /** | 246 /** |
| 247 * @param {string} oldAddressHex | 247 * @param {string} oldAddressHex |
| 248 * @param {string} newAddressHex | 248 * @param {string} newAddressHex |
| 249 * @param {number} size | 249 * @param {number} size |
| 250 */ | 250 */ |
| 251 moveEntry: function(oldAddressHex, newAddressHex, size) | 251 moveEntry: function(oldAddressHex, newAddressHex, size) |
| 252 { | 252 { |
| 253 var oldAddress = this._addressStringToNumber(oldAddressHex); | 253 var entry = this._getBank(oldAddressHex).removeEntry(this._getAddress(ol dAddressHex)); |
| 254 var newAddress = this._addressStringToNumber(newAddressHex); | 254 if (!entry) { |
| 255 var index = this._entries.lowerBound(oldAddress, WebInspector.TimelineJS ProfileProcessor.CodeMap.comparator); | 255 console.error("Entry at address " + oldAddressHex + " not found"); |
| 256 var entry = this._entries[index]; | |
| 257 if (!entry || entry.address !== oldAddress) | |
| 258 return; | 256 return; |
| 259 this._entries.splice(index, 1); | 257 } |
| 260 entry.address = newAddress; | 258 entry.address = this._getAddress(newAddressHex); |
| 261 entry.size = size; | 259 entry.size = size; |
| 262 this._addEntry(entry); | 260 this._addEntry(newAddressHex, entry); |
| 263 }, | 261 }, |
| 264 | 262 |
| 265 /** | 263 /** |
| 266 * @param {string} addressHex | 264 * @param {string} addressHex |
| 267 * @return {?ConsoleAgent.CallFrame} | 265 * @return {?ConsoleAgent.CallFrame} |
| 268 */ | 266 */ |
| 269 lookupEntry: function(addressHex) | 267 lookupEntry: function(addressHex) |
| 270 { | 268 { |
| 271 var address = this._addressStringToNumber(addressHex); | 269 return this._getBank(addressHex).lookupEntry(this._getAddress(addressHex )); |
| 270 }, | |
| 271 | |
| 272 /** | |
| 273 * @param {string} addressHex | |
| 274 * @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} entry | |
| 275 */ | |
| 276 _addEntry: function(addressHex, entry) | |
| 277 { | |
| 278 // FIXME: deal with entries that span across [multiple] banks. | |
| 279 this._getBank(addressHex).addEntry(entry); | |
| 280 }, | |
| 281 | |
| 282 /** | |
| 283 * @param {string} addressHex | |
| 284 * @return {!WebInspector.TimelineJSProfileProcessor.CodeMap.Bank} | |
| 285 */ | |
| 286 _getBank: function(addressHex) | |
| 287 { | |
| 288 addressHex = addressHex.slice(2); // cut 0x prefix. | |
| 289 // 13 hex digits == 52 bits, double mantissa fits 53 bits. | |
| 290 var /** @const */ bankSizeHexDigits = 13; | |
|
yurys
2015/06/22 16:33:00
Please extract these constants so that they are no
alph
2015/06/23 16:06:28
I'd like to keep them as constants for the sake of
| |
| 291 var /** @const */ maxHexDigits = 16; | |
| 292 var bankName = addressHex.slice(-maxHexDigits, -bankSizeHexDigits); | |
| 293 var bank = this._banks.get(bankName); | |
| 294 if (!bank) { | |
| 295 bank = new WebInspector.TimelineJSProfileProcessor.CodeMap.Bank(); | |
| 296 this._banks.set(bankName, bank); | |
| 297 } | |
| 298 return bank; | |
| 299 }, | |
| 300 | |
| 301 /** | |
| 302 * @param {string} addressHex | |
| 303 * @return {number} | |
| 304 */ | |
| 305 _getAddress: function(addressHex) | |
| 306 { | |
| 307 // 13 hex digits == 52 bits, double mantissa fits 53 bits. | |
| 308 var /** @const */ bankSizeHexDigits = 13; | |
| 309 addressHex = addressHex.slice(2); // cut 0x prefix. | |
| 310 return parseInt(addressHex.slice(-bankSizeHexDigits), 16); | |
| 311 } | |
| 312 } | |
| 313 | |
| 314 /** | |
| 315 * @constructor | |
| 316 */ | |
| 317 WebInspector.TimelineJSProfileProcessor.CodeMap.Bank = function() | |
| 318 { | |
| 319 /** @type {!Array<!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry>} * / | |
| 320 this._entries = []; | |
| 321 } | |
| 322 | |
| 323 WebInspector.TimelineJSProfileProcessor.CodeMap.Bank.prototype = { | |
| 324 /** | |
| 325 * @param {number} address | |
| 326 * @return {?WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} | |
| 327 */ | |
| 328 removeEntry: function(address) | |
| 329 { | |
| 330 var index = this._entries.lowerBound(address, WebInspector.TimelineJSPro fileProcessor.CodeMap.comparator); | |
| 331 var entry = this._entries[index]; | |
| 332 if (!entry || entry.address !== address) | |
| 333 return null; | |
| 334 this._entries.splice(index, 1); | |
| 335 return entry; | |
| 336 }, | |
| 337 | |
| 338 /** | |
| 339 * @param {number} address | |
| 340 * @return {?ConsoleAgent.CallFrame} | |
| 341 */ | |
| 342 lookupEntry: function(address) | |
| 343 { | |
| 272 var index = this._entries.upperBound(address, WebInspector.TimelineJSPro fileProcessor.CodeMap.comparator) - 1; | 344 var index = this._entries.upperBound(address, WebInspector.TimelineJSPro fileProcessor.CodeMap.comparator) - 1; |
| 273 var entry = this._entries[index]; | 345 var entry = this._entries[index]; |
| 274 return entry && address < entry.address + entry.size ? entry.callFrame : null; | 346 return entry && address < entry.address + entry.size ? entry.callFrame : null; |
| 275 }, | 347 }, |
| 276 | 348 |
| 277 /** | 349 /** |
| 278 * @param {string} addressHex | |
| 279 * @return {number} | |
| 280 */ | |
| 281 _addressStringToNumber: function(addressHex) | |
| 282 { | |
| 283 // TODO(alph): The addressHex may represent addresses from 0 to 2^64-1, | |
| 284 // whereas address is a double type that has exact representation for | |
| 285 // integers up to 2^53. So it might lose up to 11 bits at the end. | |
| 286 // Do something about it, e.g. introduce banks, or just find and subtrac t a base. | |
| 287 return parseInt(addressHex, 16); | |
| 288 }, | |
| 289 | |
| 290 /** | |
| 291 * @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} newEntry | 350 * @param {!WebInspector.TimelineJSProfileProcessor.CodeMap.Entry} newEntry |
| 292 */ | 351 */ |
| 293 _addEntry: function(newEntry) | 352 addEntry: function(newEntry) |
| 294 { | 353 { |
| 295 var endAddress = newEntry.address + newEntry.size; | 354 var endAddress = newEntry.address + newEntry.size; |
| 296 var lastIndex = this._entries.lowerBound(endAddress, WebInspector.Timeli neJSProfileProcessor.CodeMap.comparator); | 355 var lastIndex = this._entries.lowerBound(endAddress, WebInspector.Timeli neJSProfileProcessor.CodeMap.comparator); |
| 297 var index; | 356 var index; |
| 298 for (index = lastIndex - 1; index >= 0; --index) { | 357 for (index = lastIndex - 1; index >= 0; --index) { |
| 299 var entry = this._entries[index]; | 358 var entry = this._entries[index]; |
| 300 var entryEndAddress = entry.address + entry.size; | 359 var entryEndAddress = entry.address + entry.size; |
| 301 if (entryEndAddress <= newEntry.address) | 360 if (entryEndAddress <= newEntry.address) |
| 302 break; | 361 break; |
| 303 } | 362 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); | 444 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); |
| 386 sampleEvent.ordinal = e.ordinal; | 445 sampleEvent.ordinal = e.ordinal; |
| 387 sampleEvent.args = {"data": {"stackTrace": stack }}; | 446 sampleEvent.args = {"data": {"stackTrace": stack }}; |
| 388 samples.push(sampleEvent); | 447 samples.push(sampleEvent); |
| 389 break; | 448 break; |
| 390 } | 449 } |
| 391 } | 450 } |
| 392 | 451 |
| 393 return samples; | 452 return samples; |
| 394 } | 453 } |
| OLD | NEW |