Home | History | Annotate | Download | only in tcmalloc
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 'use strict';
      6 
      7 base.require('tracing.trace_model.object_instance');
      8 base.require('cc.util');
      9 
     10 base.exportTo('tcmalloc', function() {
     11   var ObjectSnapshot = tracing.trace_model.ObjectSnapshot;
     12 
     13   /**
     14    * @constructor
     15    */
     16   function HeapSnapshot() {
     17     ObjectSnapshot.apply(this, arguments);
     18   }
     19 
     20   HeapSnapshot.prototype = {
     21     __proto__: ObjectSnapshot.prototype,
     22 
     23     preInitialize: function() {
     24       cc.preInitializeObject(this);
     25 
     26       // TODO(jamescook): Any generic field setup can go here.
     27     },
     28 
     29     // TODO(jamescook): This seems to be called before the green dot is clicked.
     30     // Consider doing it in heap_view.js.
     31     initialize: function() {
     32       if (this.args.length == 0)
     33         throw new Error('No heap snapshot data.');
     34 
     35       // The first entry is total allocations across all stack traces.
     36       this.total_ = this.args[0];
     37       // The rest is a list of allocations.
     38       var allocs = this.args.slice(1);
     39 
     40       // Build a nested dictionary of trace event names.
     41       this.heap_ = {
     42         children: {},
     43         currentBytes: 0,
     44         currentAllocs: 0,
     45         totalBytes: 0,
     46         totalAllocs: 0
     47       };
     48       for (var i = 0; i < allocs.length; i++) {
     49         var alloc = allocs[i];
     50         var traceNames = alloc.trace.split(' ');
     51         // We don't want to record allocations caused by the heap profiling
     52         // system itself, so skip allocations with this special name.
     53         if (traceNames.indexOf('trace-memory-ignore') != -1)
     54           continue;
     55         var heapEntry = this.heap_;
     56         // Walk down into the heap of stack traces.
     57         for (var j = 0; j < traceNames.length; j++) {
     58           // Look for existing children with this trace.
     59           var traceName = traceNames[j];
     60           // The empty trace name means "(here)", so don't roll those up into
     61           // parent traces because they have already been counted.
     62           if (traceName.length != 0) {
     63             // Add up the total memory for intermediate entries, so the top of
     64             // each subtree is the total memory for that tree.
     65             heapEntry.currentBytes += alloc.currentBytes;
     66             heapEntry.currentAllocs += alloc.currentAllocs;
     67             heapEntry.totalBytes += alloc.totalBytes;
     68             heapEntry.totalAllocs += alloc.totalAllocs;
     69           }
     70           if (!heapEntry.children[traceName]) {
     71             // New trace entry at this depth, so create a child for it.
     72             heapEntry.children[traceName] = {
     73               children: {},
     74               currentBytes: alloc.currentBytes,
     75               currentAllocs: alloc.currentAllocs,
     76               totalBytes: alloc.totalBytes,
     77               totalAllocs: alloc.totalAllocs
     78             };
     79           }
     80           // Descend into the children.
     81           heapEntry = heapEntry.children[traceName];
     82         }
     83       }
     84     }
     85 
     86   };
     87 
     88   ObjectSnapshot.register('memory::Heap', HeapSnapshot);
     89 
     90   return {
     91     HeapSnapshot: HeapSnapshot
     92   };
     93 });
     94