1 // Copyright (c) 2012 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.
7 tvcm.require('tcmalloc.heap_instance_track');
8 tvcm.require('tracing.analysis.object_snapshot_view');
9 tvcm.require('tracing.analysis.object_instance_view');
10 tvcm.require('tracing.tracks.container_track');
11 tvcm.require('tracing.tracks.counter_track');
12 tvcm.require('tracing.tracks.object_instance_track');
13 tvcm.require('tracing.tracks.spacing_track');
14 tvcm.require('tracing.tracks.thread_track');
15 tvcm.require('tracing.trace_model_settings');
16 tvcm.require('tracing.filter');
17 tvcm.require('tvcm.ui');
18 tvcm.require('tvcm.ui.dom_helpers');
20 tvcm.requireStylesheet('tracing.tracks.process_track_base');
22 tvcm.exportTo('tracing.tracks', function() {
24 var ObjectSnapshotView = tracing.analysis.ObjectSnapshotView;
25 var ObjectInstanceView = tracing.analysis.ObjectInstanceView;
26 var TraceModelSettings = tracing.TraceModelSettings;
27 var SpacingTrack = tracing.tracks.SpacingTrack;
30 * Visualizes a Process by building ThreadTracks and CounterTracks.
33 var ProcessTrackBase =
34 tvcm.ui.define('process-track-base', tracing.tracks.ContainerTrack);
36 ProcessTrackBase.prototype = {
38 __proto__: tracing.tracks.ContainerTrack.prototype,
40 decorate: function(viewport) {
41 tracing.tracks.ContainerTrack.prototype.decorate.call(this, viewport);
43 this.processBase_ = undefined;
45 this.classList.add('process-track-base');
46 this.classList.add('expanded');
48 this.processNameEl_ = tvcm.ui.createSpan();
49 this.processNameEl_.classList.add('process-track-name');
51 this.headerEl_ = tvcm.ui.createDiv({className: 'process-track-header'});
52 this.headerEl_.appendChild(this.processNameEl_);
53 this.headerEl_.addEventListener('click', this.onHeaderClick_.bind(this));
55 this.appendChild(this.headerEl_);
59 return this.processBase_;
62 set processBase(processBase) {
63 this.processBase_ = processBase;
65 if (this.processBase_) {
66 var modelSettings = new TraceModelSettings(this.processBase_.model);
68 if (this.processBase_.labels !== undefined &&
69 this.processBase_.labels.length == 1 &&
70 this.processBase_.labels[0] == 'chrome://tracing') {
75 this.expanded = modelSettings.getSettingFor(
76 this.processBase_, 'expanded', defaultValue);
79 this.updateContents_();
83 return this.classList.contains('expanded');
86 set expanded(expanded) {
87 expanded = !!expanded;
89 if (this.expanded === expanded)
92 this.classList.toggle('expanded');
94 // Expanding and collapsing tracks is, essentially, growing and shrinking
95 // the viewport. We dispatch a change event to trigger any processing
97 this.viewport_.dispatchChangeEvent();
99 if (!this.processBase_)
102 var modelSettings = new TraceModelSettings(this.processBase_.model);
103 modelSettings.setSettingFor(this.processBase_, 'expanded', expanded);
106 get hasVisibleContent() {
108 return this.children.length > 1;
112 onHeaderClick_: function(e) {
115 this.expanded = !this.expanded;
118 updateContents_: function() {
119 this.tracks_.forEach(function(track) {
120 this.removeChild(track);
123 if (!this.processBase_)
126 this.processNameEl_.textContent = this.processBase_.userFriendlyName;
127 this.headerEl_.title = this.processBase_.userFriendlyDetails;
129 // Create the object instance tracks for this process.
130 this.willAppendTracks_();
131 this.appendObjectInstanceTracks_();
132 this.appendCounterTracks_();
133 this.appendThreadTracks_();
134 this.didAppendTracks_();
137 addEventsToTrackMap: function(eventToTrackMap) {
138 this.tracks_.forEach(function(track) {
139 track.addEventsToTrackMap(eventToTrackMap);
143 willAppendTracks_: function() {
146 didAppendTracks_: function() {
149 appendObjectInstanceTracks_: function() {
150 var instancesByTypeName =
151 this.processBase_.objects.getAllInstancesByTypeName();
152 var instanceTypeNames = tvcm.dictionaryKeys(instancesByTypeName);
153 instanceTypeNames.sort();
155 var didAppendAtLeastOneTrack = false;
156 instanceTypeNames.forEach(function(typeName) {
157 var allInstances = instancesByTypeName[typeName];
159 // If a object snapshot has a view it will be shown,
160 // unless the view asked for it to not be shown.
161 var instanceViewInfo = ObjectInstanceView.getViewInfo(typeName);
162 var snapshotViewInfo = ObjectSnapshotView.getViewInfo(typeName);
163 if (instanceViewInfo && !instanceViewInfo.options.showInTrackView)
164 instanceViewInfo = undefined;
165 if (snapshotViewInfo && !snapshotViewInfo.options.showInTrackView)
166 snapshotViewInfo = undefined;
167 var hasViewInfo = instanceViewInfo || snapshotViewInfo;
169 // There are some instances that don't merit their own track in
170 // the UI. Filter them out.
171 var visibleInstances = [];
172 for (var i = 0; i < allInstances.length; i++) {
173 var instance = allInstances[i];
175 // Do not create tracks for instances that have no snapshots.
176 if (instance.snapshots.length === 0)
179 // Do not create tracks for instances that have implicit snapshots
180 // and don't have a view.
181 if (instance.hasImplicitSnapshots && !hasViewInfo)
184 visibleInstances.push(instance);
186 if (visibleInstances.length === 0)
189 // Look up the constructor for this track, or use the default
190 // constructor if none exists.
191 var trackConstructor =
192 tracing.tracks.ObjectInstanceTrack.getTrackConstructor(typeName);
193 if (!trackConstructor)
194 trackConstructor = tracing.tracks.ObjectInstanceTrack;
195 var track = new trackConstructor(this.viewport);
196 track.objectInstances = visibleInstances;
197 this.appendChild(track);
198 didAppendAtLeastOneTrack = true;
200 if (didAppendAtLeastOneTrack)
201 this.appendChild(new SpacingTrack(this.viewport));
204 appendCounterTracks_: function() {
205 // Add counter tracks for this process.
206 var counters = tvcm.dictionaryValues(this.processBase.counters);
207 counters.sort(tracing.trace_model.Counter.compare);
209 // Create the counters for this process.
210 counters.forEach(function(counter) {
211 var track = new tracing.tracks.CounterTrack(this.viewport);
212 track.counter = counter;
213 this.appendChild(track);
214 this.appendChild(new SpacingTrack(this.viewport));
218 appendThreadTracks_: function() {
219 // Get a sorted list of threads.
220 var threads = tvcm.dictionaryValues(this.processBase.threads);
221 threads.sort(tracing.trace_model.Thread.compare);
223 // Create the threads.
224 threads.forEach(function(thread) {
225 var track = new tracing.tracks.ThreadTrack(this.viewport);
226 track.thread = thread;
227 if (!track.hasVisibleContent)
229 this.appendChild(track);
230 this.appendChild(new SpacingTrack(this.viewport));
236 ProcessTrackBase: ProcessTrackBase