| <!DOCTYPE html> |
| <!-- |
| Copyright 2015 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| |
| <link rel='import' href='/tracing/extras/importer/trace_code_entry.html'> |
| |
| <script> |
| 'use strict'; |
| |
| tr.exportTo('tr.e.importer', function() { |
| // This code is a tracification of: |
| // devtools/front_end/timeline/TimelineJSProfile.js |
| function TraceCodeMap() { |
| this.banks_ = new Map(); |
| } |
| |
| TraceCodeMap.prototype = { |
| addEntry: function(addressHex, size, name, scriptId) { |
| var entry = new tr.e.importer.TraceCodeEntry( |
| this.getAddress_(addressHex), size, name, scriptId); |
| |
| this.addEntry_(addressHex, entry); |
| }, |
| |
| moveEntry: function(oldAddressHex, newAddressHex, size) { |
| var entry = this.getBank_(oldAddressHex) |
| .removeEntry(this.getAddress_(oldAddressHex)); |
| if (!entry) |
| return; |
| |
| entry.address = this.getAddress_(newAddressHex); |
| entry.size = size; |
| this.addEntry_(newAddressHex, entry); |
| }, |
| |
| lookupEntry: function(addressHex) { |
| return this.getBank_(addressHex) |
| .lookupEntry(this.getAddress_(addressHex)); |
| }, |
| |
| addEntry_: function(addressHex, entry) { |
| // FIXME: Handle bank spanning addresses ... |
| this.getBank_(addressHex).addEntry(entry); |
| }, |
| |
| getAddress_: function(addressHex) { |
| // 13 hex digits === 52 bits, double mantissa fits 53 bits. |
| var bankSizeHexDigits = 13; |
| addressHex = addressHex.slice(2); // cut 0x prefix. |
| return parseInt(addressHex.slice(-bankSizeHexDigits), 16); |
| }, |
| |
| getBank_: function(addressHex) { |
| addressHex = addressHex.slice(2); // cut 0x prefix. |
| |
| // 13 hex digits === 52 bits, double mantissa fits 53 bits. |
| var bankSizeHexDigits = 13; |
| var maxHexDigits = 16; |
| var bankName = addressHex.slice(-maxHexDigits, -bankSizeHexDigits); |
| var bank = this.banks_.get(bankName); |
| if (!bank) { |
| bank = new TraceCodeBank(); |
| this.banks_.set(bankName, bank); |
| } |
| return bank; |
| } |
| }; |
| |
| function TraceCodeBank() { |
| this.entries_ = []; |
| } |
| |
| TraceCodeBank.prototype = { |
| removeEntry: function(address) { |
| // findLowIndexInSortedArray returns 1 for empty. Just handle the |
| // empty list and bail early. |
| if (this.entries_.length === 0) |
| return undefined; |
| |
| var index = tr.b.math.findLowIndexInSortedArray( |
| this.entries_, function(entry) { return entry.address; }, address); |
| var entry = this.entries_[index]; |
| if (!entry || entry.address !== address) |
| return undefined; |
| |
| this.entries_.splice(index, 1); |
| return entry; |
| }, |
| |
| lookupEntry: function(address) { |
| var index = tr.b.math.findHighIndexInSortedArray( |
| this.entries_, function(e) { return address - e.address; }) - 1; |
| var entry = this.entries_[index]; |
| return entry && |
| address < entry.address + entry.size ? entry : undefined; |
| }, |
| |
| addEntry: function(newEntry) { |
| // findLowIndexInSortedArray returns 1 for empty list. Just push the |
| // new address as it's the only item. |
| if (this.entries_.length === 0) |
| this.entries_.push(newEntry); |
| |
| var endAddress = newEntry.address + newEntry.size; |
| var lastIndex = tr.b.math.findLowIndexInSortedArray( |
| this.entries_, function(entry) { return entry.address; }, endAddress); |
| var index; |
| for (index = lastIndex - 1; index >= 0; --index) { |
| var entry = this.entries_[index]; |
| var entryEndAddress = entry.address + entry.size; |
| if (entryEndAddress <= newEntry.address) |
| break; |
| } |
| ++index; |
| this.entries_.splice(index, lastIndex - index, newEntry); |
| } |
| }; |
| |
| return { |
| TraceCodeMap, |
| }; |
| }); |
| |
| </script> |