// Copyright (c) 2013 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. 'use strict'; base.require('tracing.trace_model.object_instance'); base.require('cc.util'); base.exportTo('tcmalloc', function() { var ObjectSnapshot = tracing.trace_model.ObjectSnapshot; /** * @constructor */ function HeapSnapshot() { ObjectSnapshot.apply(this, arguments); } HeapSnapshot.prototype = { __proto__: ObjectSnapshot.prototype, preInitialize: function() { cc.preInitializeObject(this); // TODO(jamescook): Any generic field setup can go here. }, // TODO(jamescook): This seems to be called before the green dot is clicked. // Consider doing it in heap_view.js. initialize: function() { if (this.args.length == 0) throw new Error('No heap snapshot data.'); // The first entry is total allocations across all stack traces. this.total_ = this.args[0]; // The rest is a list of allocations. var allocs = this.args.slice(1); // Build a nested dictionary of trace event names. this.heap_ = { children: {}, currentBytes: 0, currentAllocs: 0, totalBytes: 0, totalAllocs: 0 }; for (var i = 0; i < allocs.length; i++) { var alloc = allocs[i]; var traceNames = alloc.trace.split(' '); // We don't want to record allocations caused by the heap profiling // system itself, so skip allocations with this special name. if (traceNames.indexOf('trace-memory-ignore') != -1) continue; var heapEntry = this.heap_; // Walk down into the heap of stack traces. for (var j = 0; j < traceNames.length; j++) { // Look for existing children with this trace. var traceName = traceNames[j]; // The empty trace name means "(here)", so don't roll those up into // parent traces because they have already been counted. if (traceName.length != 0) { // Add up the total memory for intermediate entries, so the top of // each subtree is the total memory for that tree. heapEntry.currentBytes += alloc.currentBytes; heapEntry.currentAllocs += alloc.currentAllocs; heapEntry.totalBytes += alloc.totalBytes; heapEntry.totalAllocs += alloc.totalAllocs; } if (!heapEntry.children[traceName]) { // New trace entry at this depth, so create a child for it. heapEntry.children[traceName] = { children: {}, currentBytes: alloc.currentBytes, currentAllocs: alloc.currentAllocs, totalBytes: alloc.totalBytes, totalAllocs: alloc.totalAllocs }; } // Descend into the children. heapEntry = heapEntry.children[traceName]; } } } }; ObjectSnapshot.register('memory::Heap', HeapSnapshot); return { HeapSnapshot: HeapSnapshot }; });