mirror of
https://github.com/jlfwong/speedscope.git
synced 2024-10-06 15:17:07 +03:00
Merge 0235594002
into 0121cf9342
This commit is contained in:
commit
911638f6e7
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ufwb version="1.17">
|
||||
<grammar name="INDEX grammar" start="id:10" author="Jamie Wong" fileextension="index">
|
||||
<grammar name="INDEX grammar" start="id:43" author="Jamie Wong" fileextension="index">
|
||||
<description>Grammar for INDEX files</description>
|
||||
<structure name="integeruniquer.index file" id="10" encoding="ISO_8859-1:1987" endian="big" signed="no">
|
||||
<binary name="Header" id="12" length="32"/>
|
||||
<structure name="Entry" id="16" length="8" repeatmax="-1">
|
||||
<number name="ByteOffset" id="15" type="integer" length="4" endian="little"/>
|
||||
<number name="MegabyteOffset" id="18" type="integer" length="4" endian="little"/>
|
||||
<structure name="integeruniquer.index file" id="43" encoding="ISO_8859-1:1987" endian="big" signed="no">
|
||||
<binary name="Header" id="44" length="32"/>
|
||||
<structure name="Entry" id="45" length="8" repeatmax="-1">
|
||||
<number name="ByteOffset" id="46" fillcolor="FFB598" type="integer" length="4" endian="little"/>
|
||||
<number name="MegabyteOffset" id="47" fillcolor="A0FF7B" type="integer" length="4" endian="little"/>
|
||||
</structure>
|
||||
</structure>
|
||||
</grammar>
|
||||
|
@ -1,21 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ufwb version="1.17">
|
||||
<grammar name="time-sample bulkstore" start="id:1" author="Jamie Wong" fileextension="bin" uti="com.apple.macbinary-archive">
|
||||
<grammar name="time-sample bulkstore" start="id:17" author="Jamie Wong" fileextension="bin" uti="com.apple.macbinary-archive">
|
||||
<description>Grammar for BIN files</description>
|
||||
<structure name="time-sample bulkstore" id="1" length="0" encoding="ISO_8859-1:1987" endian="little" signed="no">
|
||||
<structure name="Header" id="2" length="Size" endian="little">
|
||||
<binary name="???0" id="3" length="4"/>
|
||||
<number name="???1" id="4" type="integer" length="4"/>
|
||||
<number name="???2" id="5" type="integer" length="4"/>
|
||||
<number name="Size" id="6" type="integer" length="4"/>
|
||||
<number name="BytesPerEntry" id="7" type="integer" length="2"/>
|
||||
<number name="???4" id="8" type="integer" length="4"/>
|
||||
<number name="???5" id="9" type="integer" length="4"/>
|
||||
<structure name="time-sample bulkstore" id="17" length="0" encoding="ISO_8859-1:1987" endian="little" signed="no">
|
||||
<structure name="Header" id="18" length="Size" endian="little">
|
||||
<binary name="???0" id="19" length="4"/>
|
||||
<number name="???1" id="20" type="integer" length="4"/>
|
||||
<number name="???2" id="21" type="integer" length="4"/>
|
||||
<number name="Size" id="22" type="integer" length="4"/>
|
||||
<number name="BytesPerEntry" id="23" type="integer" length="2"/>
|
||||
<number name="???4" id="24" type="integer" length="4"/>
|
||||
<number name="???5" id="25" type="integer" length="4"/>
|
||||
</structure>
|
||||
<structure name="Data" id="11" length="BytesPerEntry" repeatmax="-1">
|
||||
<number name="Timestamp" id="12" fillcolor="33FF70" type="integer" length="6" endian="little"/>
|
||||
<binary name="<Binary Fill Bytes>" id="13" unused="yes" length="23"/>
|
||||
<number name="Backtrace ID" id="14" fillcolor="FF8284" type="integer" length="4" endian="little"/>
|
||||
<structure name="Data" id="27" length="BytesPerEntry" repeatmax="-1">
|
||||
<number name="Timestamp" id="28" fillcolor="33FF70" type="integer" length="6" endian="little"/>
|
||||
<number name="Thread ID" id="33" fillcolor="65A0FF" type="integer" length="4"/>
|
||||
<binary name="<Binary Fill Bytes>" id="29" unused="yes" fillcolor="C0C0C0" length="19"/>
|
||||
<number name="Backtrace ID" id="30" fillcolor="FF8284" type="integer" length="4" endian="little"/>
|
||||
</structure>
|
||||
</structure>
|
||||
</grammar>
|
||||
|
@ -286,13 +286,21 @@ async function getRawSampleList(core: TraceDirectoryTree): Promise<Sample[]> {
|
||||
while (true) {
|
||||
// Schema as of Instruments 8.3.3 is a 6 byte timestamp, followed by a bunch
|
||||
// of stuff we don't care about, followed by a 4 byte backtrace ID
|
||||
const timestampBytes = 48 / 8
|
||||
const timestamp = bulkstore.readUint48()
|
||||
if (timestamp === 0) break
|
||||
|
||||
const threadIDBytes = 32 / 8
|
||||
const threadID = bulkstore.readUint32()
|
||||
|
||||
bulkstore.skip(bytesPerEntry - 6 - 4 - 4)
|
||||
// Skip the stuff we don't care about. We can do this because we know how
|
||||
// many bytes there shuold be per entry from the header of the file, and
|
||||
// we know how many bytes we're reading for each of the fields we do care
|
||||
// about.
|
||||
const backtraceIDBytes = 32 / 8
|
||||
bulkstore.skip(bytesPerEntry - timestampBytes - threadIDBytes - backtraceIDBytes)
|
||||
const backtraceID = bulkstore.readUint32()
|
||||
|
||||
samples.push({timestamp, threadID, backtraceID})
|
||||
}
|
||||
return samples
|
||||
@ -516,15 +524,38 @@ export function importThreadFromInstrumentsTrace(args: {
|
||||
const profile = new StackListProfileBuilder(lastOf(samples)!.timestamp)
|
||||
profile.setName(`${fileName} - thread ${threadID}`)
|
||||
|
||||
// Each sample's stack is identified by a single number. This number might be
|
||||
// a an address, or an index into the integer array list. If it's an index
|
||||
// into the integer arrays list, then the integer array it corresponds to
|
||||
// might itself contain either addresses or indices into the integer array.
|
||||
function appendRecursive(k: number, stack: FrameInfo[]) {
|
||||
const frame = addressToFrameMap.get(k)
|
||||
// First try: let's see if the number is an address and we have
|
||||
// an associated stack frame for the address.
|
||||
const address = k
|
||||
const frame = addressToFrameMap.get(address)
|
||||
if (frame) {
|
||||
stack.push(frame)
|
||||
} else if (k in arrays) {
|
||||
for (let addr of arrays[k]) {
|
||||
return
|
||||
}
|
||||
|
||||
// Second try: let's see if the number is an index into the integer array
|
||||
// list. We'll re-interpret the index as a 32 bit integer here by ignoring
|
||||
// the upper 32 bits of the integer.
|
||||
//
|
||||
// TODO(jlfwong): This seems pretty dubious. Is there a more correct wait to
|
||||
// differentiate between an address and a number? I wonder if there's either
|
||||
// some metadata somewhere that we need or if there's something in the byte
|
||||
// sequence that indicates what kind of number it is.
|
||||
const arrayIndex = k & 0xffffffff
|
||||
if (arrayIndex in arrays) {
|
||||
for (let addr of arrays[arrayIndex]) {
|
||||
appendRecursive(addr, stack)
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
// Fallback case: we'll say we can't find the address, and just
|
||||
// display the address instead of frame information.
|
||||
const rawAddressFrame: FrameInfo = {
|
||||
key: k,
|
||||
name: `0x${zeroPad(k.toString(16), 16)}`,
|
||||
@ -532,7 +563,6 @@ export function importThreadFromInstrumentsTrace(args: {
|
||||
addressToFrameMap.set(k, rawAddressFrame)
|
||||
stack.push(rawAddressFrame)
|
||||
}
|
||||
}
|
||||
|
||||
let lastTimestamp: null | number = null
|
||||
for (let sample of samples) {
|
||||
|
Loading…
Reference in New Issue
Block a user