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

Side by Side Diff: runtime/bin/vmservice/client/lib/src/service/object.dart

Issue 205713004: Add isolate tag-profile and better handling of errors (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of service; 5 part of service;
6 6
7 /// A [ServiceObject] is an object known to the VM service and is tied 7 /// A [ServiceObject] is an object known to the VM service and is tied
8 /// to an owning [Isolate]. 8 /// to an owning [Isolate].
9 abstract class ServiceObject extends Observable { 9 abstract class ServiceObject extends Observable {
10 /// The owner of this [ServiceObject]. This can be an [Isolate], a 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 assert(serviceType == 'Error'); 95 assert(serviceType == 'Error');
96 return new Future.value(this); 96 return new Future.value(this);
97 } 97 }
98 return vm.getAsMap(link).then(update); 98 return vm.getAsMap(link).then(update);
99 } 99 }
100 100
101 /// Update [this] using [m] as a source. [m] can be a reference. 101 /// Update [this] using [m] as a source. [m] can be a reference.
102 ServiceObject update(ObservableMap m) { 102 ServiceObject update(ObservableMap m) {
103 // Assert that m is a service map. 103 // Assert that m is a service map.
104 assert(ServiceObject.isServiceMap(m)); 104 assert(ServiceObject.isServiceMap(m));
105 if ((m['type'] == 'Error') && (_serviceType != 'Error')) {
106 // Got an unexpected error. Don't update the object.
107 return _upgradeToServiceObject(vm, isolate, m);
108 }
109 // TODO(johnmccutchan): Should we allow for a ServiceObject's id 105 // TODO(johnmccutchan): Should we allow for a ServiceObject's id
110 // or type to change? 106 // or type to change?
111 _id = m['id']; 107 _id = m['id'];
112 _serviceType = stripRef(m['type']); 108 _serviceType = stripRef(m['type']);
113 _update(m); 109 _update(m);
114 return this; 110 return this;
115 } 111 }
116 112
117 // update internal state from [map]. [map] can be a reference. 113 // update internal state from [map]. [map] can be a reference.
118 void _update(ObservableMap map); 114 void _update(ObservableMap map);
119 115
120 void _created() { 116 void _created() {
121 var refNotice = _ref ? ' Created from reference.' : '';
122 Logger.root.info('Created ServiceObject for \'${_id}\' with type '
123 '\'${_serviceType}\'.' + refNotice);
124 } 117 }
turnidge 2014/03/24 20:22:13 Maybe just drop _created() entirely.
Cutch 2014/03/25 14:39:06 Done.
125 118
126 // ------------------------------------------------------ 119 // ------------------------------------------------------
127 120
128 /// Returns true if [map] is a service map. i.e. it has the following keys: 121 /// Returns true if [map] is a service map. i.e. it has the following keys:
129 /// 'id' and a 'type'. 122 /// 'id' and a 'type'.
130 static bool isServiceMap(ObservableMap m) { 123 static bool isServiceMap(ObservableMap m) {
131 return (m != null) && (m['id'] != null) && (m['type'] != null); 124 return (m != null) && (m['id'] != null) && (m['type'] != null);
132 } 125 }
133 126
134 /// Returns true if [type] is a reference type. i.e. it begins with an 127 /// Returns true if [type] is a reference type. i.e. it begins with an
(...skipping 29 matching lines...) Expand all
164 assert(_isolates == null); 157 assert(_isolates == null);
165 _isolates = new IsolateList(this); 158 _isolates = new IsolateList(this);
166 name = "vm"; 159 name = "vm";
167 vmName = "vm"; 160 vmName = "vm";
168 } 161 }
169 162
170 VM() : super(null, "vm", "VM") { 163 VM() : super(null, "vm", "VM") {
171 _initOnce(); 164 _initOnce();
172 } 165 }
173 166
167 final StreamController<ServiceException> exceptions =
168 new StreamController.broadcast();
169 final StreamController<ServiceError> errors =
170 new StreamController.broadcast();
171
174 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); 172 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+');
175 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+(/|$)'); 173 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+(/|$)');
176 174
177 String _parseObjectId(String id) { 175 String _parseObjectId(String id) {
178 Match m = _currentObjectMatcher.matchAsPrefix(id); 176 Match m = _currentObjectMatcher.matchAsPrefix(id);
179 if (m == null) { 177 if (m == null) {
180 return null; 178 return null;
181 } 179 }
182 return m.input.substring(m.end); 180 return m.input.substring(m.end);
183 } 181 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 } 213 }
216 } 214 }
217 } 215 }
218 } else if (id == 'vm') { 216 } else if (id == 'vm') {
219 return reload(); 217 return reload();
220 } else { 218 } else {
221 return getDirect(id); 219 return getDirect(id);
222 } 220 }
223 } 221 }
224 222
225 /// Gets [id] as an [ObservableMap] from the service directly. 223 /// Gets [id] as an [ObservableMap] from the service directly. If
224 /// an error occurs, the future is completed as an error with a
225 /// ServiceError or ServiceException. Therefore the chained then()
226 /// execution path will always receive a map encoding a ServiceObject.
226 Future<ObservableMap> getAsMap(String id) { 227 Future<ObservableMap> getAsMap(String id) {
227 return getString(id).then((response) { 228 return getString(id).then((response) {
228 try { 229 try {
229 var map = JSON.decode(response); 230 var map = toObservable(JSON.decode(response));
230 Logger.root.info('Decoded $id'); 231 if (!ServiceObject.isServiceMap(map)) {
231 Logger.root.info('Response $response'); 232 return new Future.error(
232 return toObservable(map); 233 new ServiceException.fromMap(this, toObservable({
234 'type': 'ServiceException',
235 'id': '',
236 'kind': 'FormatException',
237 'response': map,
238 'message': 'Top level service responses must be service maps.',
239 })));
240 }
241 // Preemptively capture ServiceError and ServiceExceptions.
242 if (map['type'] == 'ServiceError') {
243 return new Future.error(new ServiceError.fromMap(this, map));
244 } else if (map['type'] == 'ServiceException') {
245 return new Future.error(new ServiceException.fromMap(this, map));
246 }
247 // map is now guaranteed to be a non-error/exception ServiceObject.
248 return map;
233 } catch (e, st) { 249 } catch (e, st) {
234 return toObservable({ 250 print(e);
235 'type': 'Error', 251 print(st);
252 return new Future.error(
253 new ServiceException.fromMap(this, toObservable({
254 'type': 'ServiceException',
236 'id': '', 255 'id': '',
237 'kind': 'DecodeError', 256 'kind': 'DecodeException',
238 'message': '$e', 257 'response': response,
239 }); 258 'message': 'Could not decode JSON: $e',
259 })));
240 } 260 }
241 }).catchError((error) { 261 }).catchError((error) {
242 return toObservable({ 262 // ServiceError.
243 'type': 'Error', 263 errors.add(error);
244 'id': '', 264 return new Future.error(error);
245 'kind': 'LastResort', 265 }, test: (e) => e is ServiceError).catchError((exception) {
turnidge 2014/03/24 20:22:13 I hadn't seen the "test" stuff before. Wacky!
246 'message': '$error' 266 // ServiceException.
247 }); 267 exceptions.add(exception);
248 }); 268 return new Future.error(exception);
269 }, test: (e) => e is ServiceException);
249 } 270 }
250 271
251 /// Get [id] as a [String] from the service directly. See [getAsMap]. 272 /// Get [id] as a [String] from the service directly. See [getAsMap].
252 Future<String> getString(String id); 273 Future<String> getString(String id);
253 274
254 void _update(ObservableMap map) { 275 void _update(ObservableMap map) {
255 _ref = false; 276 _ref = false;
256 version = map['version']; 277 version = map['version'];
257 architecture = map['architecture']; 278 architecture = map['architecture'];
258 uptime = map['uptime']; 279 uptime = map['uptime'];
259 _isolates.updateIsolates(map['isolates']); 280 _isolates.updateIsolates(map['isolates']);
260 allIsolates.clear(); 281 allIsolates.clear();
261 allIsolates.addAll(_isolates.isolates.values); 282 allIsolates.addAll(_isolates.isolates.values);
262 } 283 }
263 } 284 }
264 285
286 class TagProfileSnapshot {
287 final double seconds;
288 final List<int> counters;
289 int get sum => _sum;
290 int _sum = 0;
291 TagProfileSnapshot(this.seconds, int countersLength)
292 : counters = new List<int>(countersLength);
293
294 /// Set [counters] and update [sum].
295 void set(List<int> counters) {
296 this.counters.setAll(0, counters);
297 for (var i = 0; i < this.counters.length; i++) {
298 _sum += this.counters[i];
299 }
300 }
301
302 /// Set [counters] with the delta from [counters] to [old_counters]
303 /// and update [sum].
304 void delta(List<int> counters, List<int> old_counters) {
305 for (var i = 0; i < this.counters.length; i++) {
306 this.counters[i] = counters[i] - old_counters[i];
307 _sum += this.counters[i];
308 }
309 }
310
311 /// Update [counters] with new maximum values seen in [counters].
312 void max(List<int> counters) {
313 for (var i = 0; i < counters.length; i++) {
314 var c = counters[i];
315 this.counters[i] = this.counters[i] > c ? this.counters[i] : c;
316 }
317 }
318
319 /// Zero [counters].
320 void zero() {
321 for (var i = 0; i < counters.length; i++) {
322 counters[i] = 0;
323 }
324 }
325 }
326
327 class TagProfile {
328 final List<String> names = new List<String>();
329 final List<TagProfileSnapshot> snapshots = new List<TagProfileSnapshot>();
330 double get updatedAtSeconds => _seconds;
331 double _seconds;
332 TagProfileSnapshot _maxSnapshot;
333 int _historySize;
334 int _countersLength = 0;
335
336 TagProfile(this._historySize);
337
338 void _processTagProfile(double seconds, ObservableMap tagProfile) {
339 _seconds = seconds;
340 var counters = tagProfile['counters'];
341 if (names.length == 0) {
342 // Initialization.
343 names.addAll(tagProfile['names']);
344 _countersLength = tagProfile['counters'].length;
345 for (var i = 0; i < _historySize; i++) {
346 var snapshot = new TagProfileSnapshot(0.0, _countersLength);
347 snapshot.zero();
348 snapshots.add(snapshot);
349 }
350 // The counters monotonically grow, keep track of the maximum value.
351 _maxSnapshot = new TagProfileSnapshot(0.0, _countersLength);
352 _maxSnapshot.set(counters);
353 return;
354 }
355 var snapshot = new TagProfileSnapshot(seconds, _countersLength);
356 // We snapshot the delta from the current counters to the maximum counter
357 // values.
358 snapshot.delta(counters, _maxSnapshot.counters);
359 _maxSnapshot.max(counters);
360 snapshots.add(snapshot);
361 // Only keep _historySize snapshots.
362 if (snapshots.length > _historySize) {
363 snapshots.removeAt(0);
364 }
365 }
366 }
turnidge 2014/03/24 20:22:13 What do you think of us moving the profilng helper
Cutch 2014/03/25 14:39:06 sgtm.
367
265 /// State for a running isolate. 368 /// State for a running isolate.
266 class Isolate extends ServiceObject { 369 class Isolate extends ServiceObject {
370 final TagProfile tagProfile = new TagProfile(20);
371
267 String get link => _id; 372 String get link => _id;
268 String get hashLink => '#/$_id'; 373 String get hashLink => '#/$_id';
269 374
270 @observable bool pausedOnStart = false; 375 @observable bool pausedOnStart = false;
271 @observable bool pausedOnExit = false; 376 @observable bool pausedOnExit = false;
272 @observable bool running = false; 377 @observable bool running = false;
273 @observable bool idle = false; 378 @observable bool idle = false;
274 379
275 ScriptCache _scripts; 380 ScriptCache _scripts;
276 /// Script cache. 381 /// Script cache.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 @observable final Map<String, double> timers = 470 @observable final Map<String, double> timers =
366 toObservable(new Map<String, double>()); 471 toObservable(new Map<String, double>());
367 472
368 @observable int newHeapUsed = 0; 473 @observable int newHeapUsed = 0;
369 @observable int oldHeapUsed = 0; 474 @observable int oldHeapUsed = 0;
370 @observable int newHeapCapacity = 0; 475 @observable int newHeapCapacity = 0;
371 @observable int oldHeapCapacity = 0; 476 @observable int oldHeapCapacity = 0;
372 477
373 @observable String fileAndLine; 478 @observable String fileAndLine;
374 479
480 @observable DartError stickyError;
481
375 void _update(ObservableMap map) { 482 void _update(ObservableMap map) {
376 upgradeCollection(map, vm, this); 483 upgradeCollection(map, vm, this);
377 mainPort = map['mainPort']; 484 mainPort = map['mainPort'];
378 name = map['name']; 485 name = map['name'];
379 if (ServiceObject.isRefType(map['type'])) { 486 if (ServiceObject.isRefType(map['type'])) {
380 return; 487 return;
381 } 488 }
382 _ref = false; 489 _ref = false;
383 if (map['rootLib'] == null || 490 if (map['rootLib'] == null ||
384 map['timers'] == null || 491 map['timers'] == null ||
(...skipping 28 matching lines...) Expand all
413 newHeapUsed = map['heap']['usedNew']; 520 newHeapUsed = map['heap']['usedNew'];
414 oldHeapUsed = map['heap']['usedOld']; 521 oldHeapUsed = map['heap']['usedOld'];
415 newHeapCapacity = map['heap']['capacityNew']; 522 newHeapCapacity = map['heap']['capacityNew'];
416 oldHeapCapacity = map['heap']['capacityOld']; 523 oldHeapCapacity = map['heap']['capacityOld'];
417 524
418 // Isolate status 525 // Isolate status
419 pausedOnStart = map['pausedOnStart']; 526 pausedOnStart = map['pausedOnStart'];
420 pausedOnExit = map['pausedOnExit']; 527 pausedOnExit = map['pausedOnExit'];
421 running = map['topFrame'] != null; 528 running = map['topFrame'] != null;
422 idle = !pausedOnStart && !pausedOnExit && !running; 529 idle = !pausedOnStart && !pausedOnExit && !running;
530 stickyError = map['stickyError'];
531 }
532
533 Future<TagProfile> updateTagProfile() {
534 return vm.getAsMap(relativeLink('profile/tag')).then((ObservableMap m) {
535 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0;
536 tagProfile._processTagProfile(seconds, m);
537 return tagProfile;
538 });
423 } 539 }
424 540
425 @reflectable CodeTrieNode profileTrieRoot; 541 @reflectable CodeTrieNode profileTrieRoot;
426 // The profile trie is serialized as a list of integers. Each node 542 // The profile trie is serialized as a list of integers. Each node
427 // is recreated by consuming some portion of the list. The format is as 543 // is recreated by consuming some portion of the list. The format is as
428 // follows: 544 // follows:
429 // [0] index into codeTable of code object. 545 // [0] index into codeTable of code object.
430 // [1] tick count (number of times this stack frame occured). 546 // [1] tick count (number of times this stack frame occured).
431 // [2] child node count 547 // [2] child node count
432 // Reading the trie is done by recursively reading the tree depth-first 548 // Reading the trie is done by recursively reading the tree depth-first
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return node; 583 return node;
468 } 584 }
469 } 585 }
470 586
471 // TODO(johnmccutchan): Make this into an IsolateCache. 587 // TODO(johnmccutchan): Make this into an IsolateCache.
472 class IsolateList { 588 class IsolateList {
473 final VM _vm; 589 final VM _vm;
474 final isolates = new ObservableMap<String, Isolate>(); 590 final isolates = new ObservableMap<String, Isolate>();
475 591
476 IsolateList(this._vm); 592 IsolateList(this._vm);
477 593
478 void updateIsolates(List<Map> members) { 594 void updateIsolates(List<Map> members) {
479 // Find dead isolates. 595 // Find dead isolates.
480 var deadIsolates = []; 596 var deadIsolates = [];
481 isolates.forEach((k, v) { 597 isolates.forEach((k, v) {
482 if (!_foundIsolateInMembers(k, members)) { 598 if (!_foundIsolateInMembers(k, members)) {
483 deadIsolates.add(k); 599 deadIsolates.add(k);
484 } 600 }
485 }); 601 });
486 // Remove them. 602 // Remove them.
487 deadIsolates.forEach((id) { 603 deadIsolates.forEach((id) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 isolates[id] = isolate; 654 isolates[id] = isolate;
539 isolate.load(); 655 isolate.load();
540 return isolate; 656 return isolate;
541 } 657 }
542 658
543 static bool _foundIsolateInMembers(String id, List<Map> members) { 659 static bool _foundIsolateInMembers(String id, List<Map> members) {
544 return members.any((E) => E['id'] == id); 660 return members.any((E) => E['id'] == id);
545 } 661 }
546 } 662 }
547 663
548
549 /// A [ServiceObject] which implements [ObservableMap]. 664 /// A [ServiceObject] which implements [ObservableMap].
550 class ServiceMap extends ServiceObject implements ObservableMap { 665 class ServiceMap extends ServiceObject implements ObservableMap {
551 final ObservableMap _map = new ObservableMap(); 666 final ObservableMap _map = new ObservableMap();
552 ServiceMap(Isolate isolate, String id, String serviceType) : 667 ServiceMap(Isolate isolate, String id, String serviceType) :
553 super(isolate, id, serviceType) { 668 super(isolate, id, serviceType) {
554 } 669 }
555 670
556 ServiceMap.fromMap(Isolate isolate, ObservableMap m) : 671 ServiceMap.fromMap(Isolate isolate, ObservableMap m) :
557 super.fromMap(isolate, m); 672 super.fromMap(isolate, m);
558 673
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 bool deliverChanges() => _map.deliverChanges(); 706 bool deliverChanges() => _map.deliverChanges();
592 void notifyChange(ChangeRecord record) => _map.notifyChange(record); 707 void notifyChange(ChangeRecord record) => _map.notifyChange(record);
593 notifyPropertyChange(Symbol field, Object oldValue, Object newValue) => 708 notifyPropertyChange(Symbol field, Object oldValue, Object newValue) =>
594 _map.notifyPropertyChange(field, oldValue, newValue); 709 _map.notifyPropertyChange(field, oldValue, newValue);
595 void observed() => _map.observed(); 710 void observed() => _map.observed();
596 void unobserved() => _map.unobserved(); 711 void unobserved() => _map.unobserved();
597 Stream<List<ChangeRecord>> get changes => _map.changes; 712 Stream<List<ChangeRecord>> get changes => _map.changes;
598 bool get hasObservers => _map.hasObservers; 713 bool get hasObservers => _map.hasObservers;
599 } 714 }
600 715
601 class ServiceError extends ServiceObject { 716 /// A [DartError] is peered to a Dart Error object.
602 ServiceError.fromMap(ServiceObject owner, Map m) : super.fromMap(owner, m); 717 class DartError extends ServiceObject {
718 DartError.fromMap(ServiceObject owner, Map m) : super.fromMap(owner, m);
603 719
604 @observable String kind; 720 @observable String kind;
605 @observable String message; 721 @observable String message;
722 @observable ServiceMap exception;
723 @observable ServiceMap stacktrace;
724
725 void _update(ObservableMap map) {
726 kind = map['kind'];
727 message = map['message'];
728 if (map['exception'] != null) {
729 exception = new ServiceMap.fromMap(owner, map['exception']);
730 } else {
731 exception = null;
732 }
733 if (map['stacktrace'] != null) {
734 stacktrace = new ServiceMap.fromMap(owner, map['stacktrace']);
735 } else {
736 stacktrace = null;
737 }
738 name = 'DartError $kind';
739 vmName = name;
740 }
741
742 // TODO: stackTrace?
turnidge 2014/03/24 20:22:13 Delete this TODO?
Cutch 2014/03/25 14:39:06 Done.
743 }
744
745 /// A [ServiceError] is an error that was triggered in the service
746 /// server or client. Errors are prorammer mistakes that could have
747 /// been prevented, for example, requesting a non-existant path over the
748 /// service.
749 class ServiceError extends ServiceObject {
750 ServiceError.fromMap(ServiceObject owner, Map m)
751 : super.fromMap(owner, m);
752
753 @observable String kind;
754 @observable String message;
606 755
607 void _update(ObservableMap map) { 756 void _update(ObservableMap map) {
608 kind = map['kind']; 757 kind = map['kind'];
609 message = map['message']; 758 message = map['message'];
610 name = 'ServiceError $kind'; 759 name = 'ServiceError $kind';
611 vmName = name; 760 vmName = name;
612 } 761 }
762 }
613 763
614 // TODO: stackTrace? 764 /// A [ServiceException] is an exception that was triggered in the service
765 /// server or client. Exceptions are events that should be handled,
766 /// for example, an isolate went away or the connection to the VM was lost.
767 class ServiceException extends ServiceObject {
768 ServiceException.fromMap(ServiceObject owner, Map m)
769 : super.fromMap(owner, m);
770
771 @observable String kind;
772 @observable String message;
773 @observable dynamic response;
774
775 void _update(ObservableMap map) {
776 kind = map['kind'];
777 message = map['message'];
778 response = map['response'];
779 name = 'ServiceException $kind';
780 vmName = name;
781 }
615 } 782 }
616 783
617 class ScriptLine { 784 class ScriptLine {
618 @reflectable final int line; 785 @reflectable final int line;
619 @reflectable final String text; 786 @reflectable final String text;
620 ScriptLine(this.line, this.text); 787 ScriptLine(this.line, this.text);
621 } 788 }
622 789
623 class Script extends ServiceObject { 790 class Script extends ServiceObject {
624 @reflectable final lines = new ObservableList<ScriptLine>(); 791 @reflectable final lines = new ObservableList<ScriptLine>();
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 void _update(ObservableMap m) { 1044 void _update(ObservableMap m) {
878 assert(ServiceObject.isServiceMap(m)); 1045 assert(ServiceObject.isServiceMap(m));
879 assert(m['id'] == _id); 1046 assert(m['id'] == _id);
880 assert(ServiceObject.stripRef(m['type']) == _serviceType); 1047 assert(ServiceObject.stripRef(m['type']) == _serviceType);
881 name = m['user_name']; 1048 name = m['user_name'];
882 vmName = m['name']; 1049 vmName = m['name'];
883 kind = CodeKind.fromString(m['kind']); 1050 kind = CodeKind.fromString(m['kind']);
884 startAddress = int.parse(m['start'], radix:16); 1051 startAddress = int.parse(m['start'], radix:16);
885 endAddress = int.parse(m['end'], radix:16); 1052 endAddress = int.parse(m['end'], radix:16);
886 function = _upgradeToServiceObject(vm, isolate, m['function']); 1053 function = _upgradeToServiceObject(vm, isolate, m['function']);
887 objectPool = _upgradeToServiceObject(vm, isolate, m['object_pool']); 1054 if (m['object_pool'] != null) {
1055 objectPool = _upgradeToServiceObject(vm, isolate, m['object_pool']);
1056 } else {
1057 objectPool = null;
1058 }
888 var disassembly = m['disassembly']; 1059 var disassembly = m['disassembly'];
889 if (disassembly != null) { 1060 if (disassembly != null) {
890 _processDisassembly(disassembly); 1061 _processDisassembly(disassembly);
891 } 1062 }
892 // We are a reference if we don't have instructions and are Dart code. 1063 // We are a reference if we don't have instructions and are Dart code.
893 _ref = (instructions.length == 0) && (kind == CodeKind.Dart); 1064 _ref = (instructions.length == 0) && (kind == CodeKind.Dart);
894 hasDisassembly = (instructions.length != 0) && (kind == CodeKind.Dart); 1065 hasDisassembly = (instructions.length != 0) && (kind == CodeKind.Dart);
895 } 1066 }
896 1067
897 @observable bool hasDisassembly = false; 1068 @observable bool hasDisassembly = false;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 1120
950 int _callCount(List<CodeCallCount> calls, Code code) { 1121 int _callCount(List<CodeCallCount> calls, Code code) {
951 for (CodeCallCount caller in calls) { 1122 for (CodeCallCount caller in calls) {
952 if (caller.code == code) { 1123 if (caller.code == code) {
953 return caller.count; 1124 return caller.count;
954 } 1125 }
955 } 1126 }
956 return 0; 1127 return 0;
957 } 1128 }
958 } 1129 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698