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

Side by Side Diff: runtime/observatory/lib/src/service/object.dart

Issue 926103002: Add Breakpoint class to Observatory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 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] represents a persistent object within the vm. 7 /// A [ServiceObject] represents a persistent object within the vm.
8 abstract class ServiceObject extends Observable { 8 abstract class ServiceObject extends Observable {
9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { 9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
10 return o1.name.compareTo(o2.name); 10 return o1.name.compareTo(o2.name);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 116 }
117 if (!_isServiceMap(map)) { 117 if (!_isServiceMap(map)) {
118 Logger.root.severe('Malformed service object: $map'); 118 Logger.root.severe('Malformed service object: $map');
119 } 119 }
120 assert(_isServiceMap(map)); 120 assert(_isServiceMap(map));
121 var type = _stripRef(map['type']); 121 var type = _stripRef(map['type']);
122 var vmType = map['_vmType'] != null ? _stripRef(map['_vmType']) : type; 122 var vmType = map['_vmType'] != null ? _stripRef(map['_vmType']) : type;
123 var obj = null; 123 var obj = null;
124 assert(type != 'VM'); 124 assert(type != 'VM');
125 switch (type) { 125 switch (type) {
126 case 'Breakpoint':
127 obj = new Breakpoint._empty(owner);
128 break;
126 case 'Class': 129 case 'Class':
127 obj = new Class._empty(owner); 130 obj = new Class._empty(owner);
128 break; 131 break;
129 case 'Code': 132 case 'Code':
130 obj = new Code._empty(owner); 133 obj = new Code._empty(owner);
131 break; 134 break;
132 case 'Context': 135 case 'Context':
133 obj = new Context._empty(owner); 136 obj = new Context._empty(owner);
134 break; 137 break;
135 case 'Counter': 138 case 'Counter':
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 var children = _trieData[_trieDataCursor++]; 1017 var children = _trieData[_trieDataCursor++];
1015 // Recursively read child nodes. 1018 // Recursively read child nodes.
1016 for (var i = 0; i < children; i++) { 1019 for (var i = 0; i < children; i++) {
1017 var child = _readTrieNode(codeTable); 1020 var child = _readTrieNode(codeTable);
1018 node.children.add(child); 1021 node.children.add(child);
1019 node.summedChildCount += child.count; 1022 node.summedChildCount += child.count;
1020 } 1023 }
1021 return node; 1024 return node;
1022 } 1025 }
1023 1026
1024 ObservableList breakpoints = new ObservableList(); 1027 ObservableList<Breakpoint> breakpoints = new ObservableList();
1025 1028
1026 void _removeBreakpoint(ServiceMap bpt) { 1029 void _removeBreakpoint(Breakpoint bpt) {
1027 var script = bpt['location']['script']; 1030 var script = bpt.script;
1028 var tokenPos = bpt['location']['tokenPos']; 1031 var tokenPos = bpt.tokenPos;
1029 assert(tokenPos != null); 1032 assert(tokenPos != null);
1030 if (script.loaded) { 1033 if (script.loaded) {
1031 var line = script.tokenToLine(tokenPos); 1034 var line = script.tokenToLine(tokenPos);
1032 assert(line != null); 1035 assert(line != null);
1033 if (script.lines[line - 1] != null) { 1036 if (script.lines[line - 1] != null) {
1034 assert(script.lines[line - 1].bpt == bpt); 1037 assert(script.lines[line - 1].bpt == bpt);
1035 script.lines[line - 1].bpt = null; 1038 script.lines[line - 1].bpt = null;
1036 } 1039 }
1037 } 1040 }
1038 } 1041 }
1039 1042
1040 void _addBreakpoint(ServiceMap bpt) { 1043 void _addBreakpoint(Breakpoint bpt) {
1041 var script = bpt['location']['script']; 1044 var script = bpt.script;
1042 var tokenPos = bpt['location']['tokenPos']; 1045 var tokenPos = bpt.tokenPos;
1043 assert(tokenPos != null); 1046 assert(tokenPos != null);
1044 if (script.loaded) { 1047 if (script.loaded) {
1045 var line = script.tokenToLine(tokenPos); 1048 var line = script.tokenToLine(tokenPos);
1046 assert(line != null); 1049 assert(line != null);
1047 assert(script.lines[line - 1].bpt == null); 1050 assert(script.lines[line - 1].bpt == null);
1048 script.lines[line - 1].bpt = bpt; 1051 script.lines[line - 1].bpt = bpt;
1049 } else { 1052 } else {
1050 // Load the script and then plop in the breakpoint. 1053 // Load the script and then plop in the breakpoint.
1051 script.load().then((_) { 1054 script.load().then((_) {
1052 _addBreakpoint(bpt); 1055 _addBreakpoint(bpt);
1053 }); 1056 });
1054 } 1057 }
1055 } 1058 }
1056 1059
1057 void _updateBreakpoints(ServiceMap newBreakpoints) { 1060 void _updateBreakpoints(ServiceMap newBreakpoints) {
1058 // Remove all of the old breakpoints from the Script lines. 1061 // Remove all of the old breakpoints from the Script lines.
1059 if (breakpoints != null) { 1062 if (breakpoints != null) {
1060 for (var bpt in breakpoints) { 1063 for (var bpt in breakpoints) {
1061 _removeBreakpoint(bpt); 1064 _removeBreakpoint(bpt);
1062 } 1065 }
1063 } 1066 }
1064 // Add all of the new breakpoints to the Script lines. 1067 // Add all of the new breakpoints to the Script lines.
1065 for (var bpt in newBreakpoints['breakpoints']) { 1068 for (var bpt in newBreakpoints['breakpoints']) {
1066 _addBreakpoint(bpt); 1069 _addBreakpoint(bpt);
1067 } 1070 }
1068 breakpoints.clear(); 1071 breakpoints.clear();
1069 breakpoints.addAll(newBreakpoints['breakpoints']); 1072 breakpoints.addAll(newBreakpoints['breakpoints']);
1070 1073
1071 // Sort the breakpoints by breakpointNumber. 1074 // Sort the breakpoints by breakpointNumber.
1072 breakpoints.sort((a, b) => (a['breakpointNumber'] - b['breakpointNumber'])); 1075 breakpoints.sort((a, b) => (a.number - b.number));
1073 } 1076 }
1074 1077
1075 Future<ServiceObject> _inProgressReloadBpts; 1078 Future<ServiceObject> _inProgressReloadBpts;
1076 1079
1077 Future reloadBreakpoints() { 1080 Future reloadBreakpoints() {
1078 // TODO(turnidge): Can reusing the Future here ever cause us to 1081 // TODO(turnidge): Can reusing the Future here ever cause us to
1079 // get stale breakpoints? 1082 // get stale breakpoints?
1080 if (_inProgressReloadBpts == null) { 1083 if (_inProgressReloadBpts == null) {
1081 _inProgressReloadBpts = 1084 _inProgressReloadBpts =
1082 invokeRpc('getBreakpoints', {}).then((newBpts) { 1085 invokeRpc('getBreakpoints', {}).then((newBpts) {
1083 _updateBreakpoints(newBpts); 1086 _updateBreakpoints(newBpts);
1084 }).whenComplete(() { 1087 }).whenComplete(() {
1085 _inProgressReloadBpts = null; 1088 _inProgressReloadBpts = null;
1086 }); 1089 });
1087 } 1090 }
1088 return _inProgressReloadBpts; 1091 return _inProgressReloadBpts;
1089 } 1092 }
1090 1093
1091 Future<ServiceObject> addBreakpoint(Script script, int line) { 1094 Future<ServiceObject> addBreakpoint(Script script, int line) {
1092 // TODO(turnidge): Pass line as an int instead of a string. 1095 // TODO(turnidge): Pass line as an int instead of a string.
1093 return invokeRpc('addBreakpoint', 1096 Map params = {
1094 { 'script': script.id, 'line': '$line' }).then((result) { 1097 'script': script.id,
1095 if (result is ServiceMap && 1098 'line': '$line',
1096 result.type == 'Breakpoint' && 1099 };
1097 result['resolved'] && 1100 return invokeRpc('addBreakpoint', params).then((result) {
1098 script.loaded && 1101 if (result is DartError) {
1099 script.tokenToLine(result['location']['tokenPos']) != line) { 1102 return result;
1100 // Unable to set a breakpoint at desired line. 1103 }
1101 script.lines[line - 1].possibleBpt = false; 1104 Breakpoint bpt = result;
1102 } 1105 if (bpt.resolved &&
1103 // TODO(turnidge): Instead of reloading all of the breakpoints, 1106 script.loaded &&
1104 // rely on events to update the breakpoint list. 1107 script.tokenToLine(result.tokenPos) != line) {
1105 return reloadBreakpoints().then((_) { 1108 // Unable to set a breakpoint at desired line.
1106 return result; 1109 script.lines[line - 1].possibleBpt = false;
1107 }); 1110 }
1111 // TODO(turnidge): Instead of reloading all of the breakpoints,
1112 // rely on events to update the breakpoint list.
1113 return reloadBreakpoints().then((_) {
1114 return result;
1108 }); 1115 });
1116 });
1109 } 1117 }
1110 1118
1111 Future removeBreakpoint(ServiceMap bpt) { 1119 Future removeBreakpoint(Breakpoint bpt) {
1112 return invokeRpc('removeBreakpoint', 1120 return invokeRpc('removeBreakpoint',
1113 { 'breakpointId': bpt.id }).then((result) { 1121 { 'breakpointId': bpt.id }).then((result) {
1114 if (result is DartError) { 1122 if (result is DartError) {
1115 // TODO(turnidge): Handle this more gracefully. 1123 // TODO(turnidge): Handle this more gracefully.
1116 Logger.root.severe(result.message); 1124 Logger.root.severe(result.message);
1125 return result;
1117 } 1126 }
1118 if (pauseEvent != null && 1127 if (pauseEvent != null &&
1119 pauseEvent.breakpoint != null && 1128 pauseEvent.breakpoint != null &&
1120 (pauseEvent.breakpoint['id'] == bpt['id'])) { 1129 (pauseEvent.breakpoint.id == bpt.id)) {
rmacnak 2015/02/13 19:00:42 As discussed, just noting id versus number weirdne
1121 return isolate.reload(); 1130 return isolate.reload();
1122 } else { 1131 } else {
1123 return reloadBreakpoints(); 1132 return reloadBreakpoints();
1124 } 1133 }
1125 }); 1134 });
1126 } 1135 }
1127 1136
1128 // TODO(turnidge): If the user invokes pause (or other rpcs) twice, 1137 // TODO(turnidge): If the user invokes pause (or other rpcs) twice,
1129 // they could get a race. Consider returning an "in progress" 1138 // they could get a race. Consider returning an "in progress"
1130 // future to avoid this. 1139 // future to avoid this.
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 1422
1414 /// A [ServiceEvent] is an asynchronous event notification from the vm. 1423 /// A [ServiceEvent] is an asynchronous event notification from the vm.
1415 class ServiceEvent extends ServiceObject { 1424 class ServiceEvent extends ServiceObject {
1416 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); 1425 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
1417 1426
1418 ServiceEvent.vmDisconencted() : super._empty(null) { 1427 ServiceEvent.vmDisconencted() : super._empty(null) {
1419 eventType = 'VMDisconnected'; 1428 eventType = 'VMDisconnected';
1420 } 1429 }
1421 1430
1422 @observable String eventType; 1431 @observable String eventType;
1423 @observable ServiceMap breakpoint; 1432 @observable Breakpoint breakpoint;
1424 @observable ServiceMap exception; 1433 @observable ServiceMap exception;
1425 @observable ByteData data; 1434 @observable ByteData data;
1426 @observable int count; 1435 @observable int count;
1427 1436
1428 void _update(ObservableMap map, bool mapIsRef) { 1437 void _update(ObservableMap map, bool mapIsRef) {
1429 _loaded = true; 1438 _loaded = true;
1430 _upgradeCollection(map, owner); 1439 _upgradeCollection(map, owner);
1431 eventType = map['eventType']; 1440 eventType = map['eventType'];
1432 name = 'ServiceEvent $eventType'; 1441 name = 'ServiceEvent $eventType';
1433 vmName = name; 1442 vmName = name;
(...skipping 10 matching lines...) Expand all
1444 count = map['count']; 1453 count = map['count'];
1445 } 1454 }
1446 } 1455 }
1447 1456
1448 String toString() { 1457 String toString() {
1449 return 'ServiceEvent of type $eventType with ' 1458 return 'ServiceEvent of type $eventType with '
1450 '${data == null ? 0 : data.lengthInBytes} bytes of binary data'; 1459 '${data == null ? 0 : data.lengthInBytes} bytes of binary data';
1451 } 1460 }
1452 } 1461 }
1453 1462
1463 class Breakpoint extends ServiceObject {
1464 Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner);
1465
1466 // TODO(turnidge): Add state to track if a breakpoint has been
1467 // removed from the program. Remove from the cache when deleted.
1468 bool get canCache => true;
1469 bool get immutable => false;
1470
1471 // A unique integer identifier for this breakpoint.
1472 @observable int number;
1473
1474 // Source location information.
1475 @observable Script script;
1476 @observable int tokenPos;
1477
1478 // The breakpoint has been assigned to a final source location.
1479 @observable bool resolved;
1480
1481 // The breakpoint is active.
1482 @observable bool enabled;
1483
1484 void _update(ObservableMap map, bool mapIsRef) {
1485 _loaded = true;
1486 _upgradeCollection(map, owner);
1487
1488 number = map['breakpointNumber'];
1489 script = map['location']['script'];
1490 tokenPos = map['location']['tokenPos'];
1491
1492 resolved = map['resolved'];
1493 enabled = map['enabled'];
1494 }
1495
1496 String toString() {
1497 if (number != null) {
1498 return 'Breakpoint ${number} at ${script.name}(token:${tokenPos})';
1499 } else {
1500 return 'Uninitialized breakpoint';
1501 }
1502 }
1503 }
1504
1454 class Library extends ServiceObject with Coverage { 1505 class Library extends ServiceObject with Coverage {
1455 @observable String url; 1506 @observable String url;
1456 @reflectable final imports = new ObservableList<Library>(); 1507 @reflectable final imports = new ObservableList<Library>();
1457 @reflectable final scripts = new ObservableList<Script>(); 1508 @reflectable final scripts = new ObservableList<Script>();
1458 @reflectable final classes = new ObservableList<Class>(); 1509 @reflectable final classes = new ObservableList<Class>();
1459 @reflectable final variables = new ObservableList<Field>(); 1510 @reflectable final variables = new ObservableList<Field>();
1460 @reflectable final functions = new ObservableList<ServiceFunction>(); 1511 @reflectable final functions = new ObservableList<ServiceFunction>();
1461 1512
1462 bool get canCache => true; 1513 bool get canCache => true;
1463 bool get immutable => false; 1514 bool get immutable => false;
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 1940
1890 String toString() => 'Field(${owner.name}.$name)'; 1941 String toString() => 'Field(${owner.name}.$name)';
1891 } 1942 }
1892 1943
1893 1944
1894 class ScriptLine extends Observable { 1945 class ScriptLine extends Observable {
1895 final Script script; 1946 final Script script;
1896 final int line; 1947 final int line;
1897 final String text; 1948 final String text;
1898 @observable int hits; 1949 @observable int hits;
1899 @observable ServiceMap bpt; 1950 @observable Breakpoint bpt;
1900 @observable bool possibleBpt = true; 1951 @observable bool possibleBpt = true;
1901 1952
1902 bool get isBlank { 1953 bool get isBlank {
1903 // Compute isBlank on demand. 1954 // Compute isBlank on demand.
1904 if (_isBlank == null) { 1955 if (_isBlank == null) {
1905 _isBlank = text.trim().isEmpty; 1956 _isBlank = text.trim().isEmpty;
1906 } 1957 }
1907 return _isBlank; 1958 return _isBlank;
1908 } 1959 }
1909 bool _isBlank; 1960 bool _isBlank;
(...skipping 28 matching lines...) Expand all
1938 } 1989 }
1939 } 1990 }
1940 return true; 1991 return true;
1941 } 1992 }
1942 1993
1943 ScriptLine(this.script, this.line, this.text) { 1994 ScriptLine(this.script, this.line, this.text) {
1944 possibleBpt = !_isTrivialLine(text); 1995 possibleBpt = !_isTrivialLine(text);
1945 1996
1946 // TODO(turnidge): This is not so efficient. Consider improving. 1997 // TODO(turnidge): This is not so efficient. Consider improving.
1947 for (var bpt in this.script.isolate.breakpoints) { 1998 for (var bpt in this.script.isolate.breakpoints) {
1948 var bptScript = bpt['location']['script']; 1999 if (bpt.script == this.script &&
1949 var bptTokenPos = bpt['location']['tokenPos']; 2000 bpt.script.tokenToLine(bpt.tokenPos) == line) {
1950 if (bptScript == this.script &&
1951 bptScript.tokenToLine(bptTokenPos) == line) {
1952 this.bpt = bpt; 2001 this.bpt = bpt;
1953 } 2002 }
1954 } 2003 }
1955 } 2004 }
1956 } 2005 }
1957 2006
1958 class Script extends ServiceObject with Coverage { 2007 class Script extends ServiceObject with Coverage {
1959 final lines = new ObservableList<ScriptLine>(); 2008 final lines = new ObservableList<ScriptLine>();
1960 final _hits = new Map<int, int>(); 2009 final _hits = new Map<int, int>();
1961 @observable String kind; 2010 @observable String kind;
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
2858 var v = list[i]; 2907 var v = list[i];
2859 if ((v is ObservableMap) && _isServiceMap(v)) { 2908 if ((v is ObservableMap) && _isServiceMap(v)) {
2860 list[i] = owner.getFromMap(v); 2909 list[i] = owner.getFromMap(v);
2861 } else if (v is ObservableList) { 2910 } else if (v is ObservableList) {
2862 _upgradeObservableList(v, owner); 2911 _upgradeObservableList(v, owner);
2863 } else if (v is ObservableMap) { 2912 } else if (v is ObservableMap) {
2864 _upgradeObservableMap(v, owner); 2913 _upgradeObservableMap(v, owner);
2865 } 2914 }
2866 } 2915 }
2867 } 2916 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/script_inset.html ('k') | runtime/observatory/test/debugging_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698