From 0f8964efbe30a1b46d2e68c77d863f8d285d4cd5 Mon Sep 17 00:00:00 2001 From: Greg Tatum Date: Tue, 3 Aug 2021 15:00:32 -0500 Subject: [PATCH] Create new copies of the threads in dhat importer --- src/profile-logic/import/dhat.js | 89 ++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/src/profile-logic/import/dhat.js b/src/profile-logic/import/dhat.js index 0b1bb53a04..2b65e1bef8 100644 --- a/src/profile-logic/import/dhat.js +++ b/src/profile-logic/import/dhat.js @@ -14,6 +14,8 @@ import { getEmptyThread, getEmptyUnbalancedNativeAllocationsTable, } from 'firefox-profiler/profile-logic/data-structures'; +import { UniqueStringArray } from 'firefox-profiler/utils/unique-string-array'; + import { coerce, ensureExists } from 'firefox-profiler/utils/flow'; /** @@ -150,6 +152,12 @@ type IndexIntoDhatFrames = number; type ReadCount = number; type WriteCount = number; +/** + * The dhat convertor converts to the processed profile format, rather than to the Gecko + * format, as it needs the UnbalancedNativeAllocationsTable type, which is unavailable + * in the Gecko format. In the Gecko format, that data comes in the form of markers, which + * would be awkard to target. + */ export function attemptToConvertDhat(json: mixed): Profile | null { if (!json || typeof json !== 'object') { return null; @@ -173,9 +181,7 @@ export function attemptToConvertDhat(json: mixed): Profile | null { profile.meta.importedFrom = `dhat`; const allocationsTable = getEmptyUnbalancedNativeAllocationsTable(); - const thread = getEmptyThread(); - thread.pid = dhat.pid; - const { funcTable, stringTable, stackTable, frameTable } = thread; + const { funcTable, stringTable, stackTable, frameTable } = getEmptyThread(); const funcKeyToFuncIndex = new Map(); @@ -303,36 +309,53 @@ export function attemptToConvertDhat(json: mixed): Profile | null { allocationsTable.length++; } - const totalBytesThread = { ...thread }; - const maximumBytesThread = { ...thread }; - const bytesAtGmaxThread = { ...thread }; - const endBytesThread = { ...thread }; - - totalBytesThread.nativeAllocations = { - ...allocationsTable, - weight: totalBytes, - }; - maximumBytesThread.nativeAllocations = { - ...allocationsTable, - weight: maximumBytes, - }; - bytesAtGmaxThread.nativeAllocations = { - ...allocationsTable, - weight: bytesAtGmax, - }; - endBytesThread.nativeAllocations = { ...allocationsTable, weight: endBytes }; - - totalBytesThread.name = 'Total Bytes'; - maximumBytesThread.name = 'Maximum Bytes'; - bytesAtGmaxThread.name = 'Bytes at Global Max'; - endBytesThread.name = 'Bytes at End'; - - profile.threads.push( - totalBytesThread, - maximumBytesThread, - bytesAtGmaxThread, - endBytesThread - ); + profile.threads = [ + { name: 'Total Bytes', weight: totalBytes }, + { name: 'Maximum Bytes', weight: maximumBytes }, + { name: 'Bytes at Global Max', weight: bytesAtGmax }, + { name: 'Bytes at End', weight: endBytes }, + ].map(({ name, weight }) => { + const thread = getEmptyThread(); + + thread.pid = dhat.pid; + thread.name = name; + thread.stringTable = new UniqueStringArray(stringTable.serializeToArray()); + + thread.funcTable.name = funcTable.name.slice(); + thread.funcTable.isJS = funcTable.isJS.slice(); + thread.funcTable.relevantForJS = funcTable.relevantForJS.slice(); + thread.funcTable.resource = funcTable.resource.slice(); + thread.funcTable.fileName = funcTable.fileName.slice(); + thread.funcTable.lineNumber = funcTable.lineNumber.slice(); + thread.funcTable.columnNumber = funcTable.columnNumber.slice(); + thread.funcTable.length = funcTable.length; + + thread.frameTable.address = frameTable.address.slice(); + thread.frameTable.line = frameTable.line.slice(); + thread.frameTable.column = frameTable.column.slice(); + thread.frameTable.category = frameTable.category.slice(); + thread.frameTable.subcategory = frameTable.subcategory.slice(); + thread.frameTable.innerWindowID = frameTable.innerWindowID.slice(); + thread.frameTable.implementation = frameTable.implementation.slice(); + thread.frameTable.func = frameTable.func.slice(); + thread.frameTable.length = frameTable.length; + + thread.stackTable.frame = stackTable.frame.slice(); + thread.stackTable.category = stackTable.category.slice(); + thread.stackTable.category = stackTable.category.slice(); + thread.stackTable.prefix = stackTable.prefix.slice(); + thread.stackTable.length = stackTable.length; + + thread.nativeAllocations = { + time: allocationsTable.time.slice(), + stack: allocationsTable.stack.slice(), + weight, + weightType: 'bytes', + length: allocationsTable.length, + }; + + return thread; + }); return profile; }