blob: 53180d4199b272114869dca013b5f060d4cbdcbe [file] [log] [blame]
<!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>