Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |