Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Unified Diff: tracing/tracing/extras/importer/heap_dump_trace_event_importer.html

Issue 2635023002: [tracing] Support new heap dump format (Closed)
Patch Set: fix bug''fix bug Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tracing/tracing/extras/importer/heap_dump_trace_event_importer.html
diff --git a/tracing/tracing/extras/importer/heap_dump_trace_event_importer.html b/tracing/tracing/extras/importer/heap_dump_trace_event_importer.html
index e11e40313f0e369e517640e1ed1fb1862d6b7e64..e22671b6359bbcba0bdecc47e9f52d107b2a1feb 100644
--- a/tracing/tracing/extras/importer/heap_dump_trace_event_importer.html
+++ b/tracing/tracing/extras/importer/heap_dump_trace_event_importer.html
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<!--
-Copyright 2016 The Chromium Authors. All rights reserved.
+Copyright 2017 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.
-->
@@ -16,169 +16,72 @@ found in the LICENSE file.
tr.exportTo('tr.e.importer', function() {
/**
* @constructor
- * @param {!tr.model.Model} model The model we are currently building.
- * @param {!tr.model.ProcessMemoryDump} processMemoryDump
- * The parent memory dump for this heap dump.
- * @param {!Map|undefined} processObjectTypeNameMap
- * A map from raw heap dump 'type' ids to human-readable names.
- * @param {!string} idPrefix Process-specific prefix to prepend to a stack
- * trace id before looking it up in the model.
- * @param {!string} dumpId
- * Raw heap dump id, used only for nice error messages.
*/
function HeapDumpTraceEventImporter(
- model, processMemoryDump, processObjectTypeNameMap, idPrefix, dumpId) {
- this.model_ = model;
- this.processObjectTypeNameMap_ = processObjectTypeNameMap;
- this.idPrefix_ = idPrefix;
- this.processMemoryDump_ = processMemoryDump;
- this.pid_ = this.processMemoryDump_.process.pid;
- this.dumpId_ = dumpId;
+ heapProfileExpander,
+ stackFrames,
+ processMemoryDump,
+ idPrefix,
+ model) {
+ this.expander = heapProfileExpander;
+ this.stackFrames = stackFrames;
+ this.processMemoryDump = processMemoryDump;
+ this.idPrefix = idPrefix;
+ this.model = model;
}
HeapDumpTraceEventImporter.prototype = {
- /**
- * Parse rawHeapDump and add entries to heapDump.
- *
- * @param {!{!entries:(!Array<!Object>|undefined)}} rawHeapDump
- * The data we're going to parse.
- * @param {!string} allocatorName e.g. malloc.
- * @return {!tr.model.HeapDump} on success or undefined on an error.
- */
- parseRawHeapDump(rawHeapDump, allocatorName) {
- const model = this.model_;
- const processMemoryDump = this.processMemoryDump_;
- const heapDump = new tr.model.HeapDump(processMemoryDump, allocatorName);
- const entries = rawHeapDump.entries;
- if (entries === undefined || entries.length === 0) {
- this.model_.importWarning({
- type: 'memory_dump_parse_error',
- message: 'No heap entries in a ' + allocatorName +
- ' heap dump for PID=' + this.pid_ +
- ' and dump ID=' + this.dumpId_ + '.'
- });
+ getLeafStackFrame(stackFrameId) {
+ // Root.
+ if (stackFrameId === '') return undefined;
+ const parentId = this.idPrefix + stackFrameId;
+ const id = parentId + ':self';
- return undefined;
+ // In the new format all values are 'self' values,
+ // we distingiush these from the totals in the UI via
+ // artificial '<self>' stack frames.
+ if (!this.stackFrames[id]) {
+ const parentStackFrame = this.stackFrames[parentId];
+ const stackFrame = new tr.model.StackFrame(
+ parentStackFrame, id, '<self>',
+ undefined /* colorId */);
+ this.model.addStackFrame(stackFrame);
}
+ return this.stackFrames[id];
+ },
- // The old format always starts with a {size: <total>} entry.
- // See https://goo.gl/WYStil
- // TODO(petrcermak): Remove support for the old format once the new
- // format has been around long enough.
- const isOldFormat = entries[0].bt === undefined;
- if (!isOldFormat && this.processObjectTypeNameMap_ === undefined) {
- // Mapping from object type IDs to names must be provided in the new
- // format.
- return undefined;
+ parseEntry(entry, heapDump) {
+ const size = entry.size;
+ const count = entry.count;
+ const leafStackFrame = this.getLeafStackFrame(entry.node.id);
+ const objectTypeName = entry.type.name;
+ const valuesAreTotals = false;
+ if (objectTypeName === undefined) {
+ this.model_.importWarning({
+ type: 'memory_dump_parse_error',
+ message: 'Missing object type name (ID ' + typeId + ')',
+ });
}
+ heapDump.addEntry(
+ leafStackFrame, objectTypeName, size, count, valuesAreTotals);
+ },
- for (let i = 0; i < entries.length; i++) {
- const entry = entries[i];
- const size = parseInt(entry.size, 16);
- const leafStackFrameIndex = entry.bt;
- let leafStackFrame;
-
- // There are two possible mappings from leaf stack frame indices
- // (provided in the trace) to the corresponding stack frames
- // depending on the format.
- if (isOldFormat) {
- // Old format:
- // Undefined index -> / (root)
- // Defined index for /A/B -> /A/B/<self>
- if (leafStackFrameIndex === undefined) {
- leafStackFrame = undefined; /* root */
- } else {
- // Get the leaf stack frame corresponding to the provided index.
- let leafStackFrameId = this.idPrefix_ + leafStackFrameIndex;
- if (leafStackFrameIndex === '') {
- leafStackFrame = undefined; /* root */
- } else {
- leafStackFrame = model.stackFrames[leafStackFrameId];
- if (leafStackFrame === undefined) {
- this.model_.importWarning({
- type: 'memory_dump_parse_error',
- message: 'Missing leaf stack frame (ID ' +
- leafStackFrameId + ') of heap entry ' + i + ' (size ' +
- size + ') in a ' + allocatorName +
- ' heap dump for PID=' + this.pid_ + '.'
- });
- continue;
- }
- }
-
- // Inject an artificial <self> leaf stack frame.
- leafStackFrameId += ':self';
- if (model.stackFrames[leafStackFrameId] !== undefined) {
- // The frame might already exist if there are multiple process
- // memory dumps (for the same process) in the trace.
- leafStackFrame = model.stackFrames[leafStackFrameId];
- } else {
- leafStackFrame = new tr.model.StackFrame(
- leafStackFrame, leafStackFrameId, '<self>',
- undefined /* colorId */);
- model.addStackFrame(leafStackFrame);
- }
- }
- } else {
- // New format:
- // Undefined index -> (invalid value)
- // Defined index for /A/B -> /A/B
- if (leafStackFrameIndex === undefined) {
- this.model_.importWarning({
- type: 'memory_dump_parse_error',
- message: 'Missing stack frame ID of heap entry ' + i +
- ' (size ' + size + ') in a ' + allocatorName +
- ' heap dump for PID=' + this.pid_ + '.'
- });
- continue;
- }
-
- // Get the leaf stack frame corresponding to the provided index.
- const leafStackFrameId = this.idPrefix_ + leafStackFrameIndex;
- if (leafStackFrameIndex === '') {
- leafStackFrame = undefined; /* root */
- } else {
- leafStackFrame = model.stackFrames[leafStackFrameId];
- if (leafStackFrame === undefined) {
- this.model_.importWarning({
- type: 'memory_dump_parse_error',
- message: 'Missing leaf stack frame (ID ' + leafStackFrameId +
- ') of heap entry ' + i + ' (size ' + size + ') in a ' +
- allocatorName + ' heap dump for PID=' + this.pid_ + '.'
- });
- continue;
- }
- }
- }
-
- const objectTypeId = entry.type;
- let objectTypeName;
- if (objectTypeId === undefined) {
- objectTypeName = undefined; /* total over all types */
- } else if (this.processObjectTypeNameMap_ === undefined) {
- // This can only happen when the old format is used.
- continue;
- } else {
- objectTypeName = this.processObjectTypeNameMap_[objectTypeId];
- if (objectTypeName === undefined) {
- this.model_.importWarning({
- type: 'memory_dump_parse_error',
- message: 'Missing object type name (ID ' + objectTypeId +
- ') of heap entry ' + i + ' (size ' + size + ') in a ' +
- allocatorName + ' heap dump for PID=' + this.pid_ + '.'
- });
- continue;
- }
+ parse() {
+ const heapDumps = {};
+ const inflated = this.expander.inflated;
+ for (const [allocatorName, entries] of Object.entries(inflated)) {
+ const heapDump =
+ new tr.model.HeapDump(this.processMemoryDump, allocatorName);
+ for (const entry of entries) {
+ this.parseEntry(entry, heapDump);
}
-
- const count = entry.count === undefined ? undefined :
- parseInt(entry.count, 16);
- heapDump.addEntry(leafStackFrame, objectTypeName, size, count);
+ heapDump.isComplete = true;
+ heapDumps[allocatorName] = heapDump;
}
-
- return heapDump;
+ return heapDumps;
},
+
};
return {

Powered by Google App Engine
This is Rietveld 408576698