OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart.developer; | 5 part of dart.developer; |
6 | 6 |
7 typedef dynamic TimelineSyncFunction(); | 7 typedef dynamic TimelineSyncFunction(); |
8 typedef Future TimelineAsyncFunction(); | 8 typedef Future TimelineAsyncFunction(); |
9 | 9 |
10 /// Add to the timeline. | 10 /// Add to the timeline. |
(...skipping 26 matching lines...) Expand all Loading... |
37 block.finish(); | 37 block.finish(); |
38 } | 38 } |
39 | 39 |
40 /// Emit an instant event. | 40 /// Emit an instant event. |
41 static void instantSync(String name, {Map arguments}) { | 41 static void instantSync(String name, {Map arguments}) { |
42 if (name is! String) { | 42 if (name is! String) { |
43 throw new ArgumentError.value(name, | 43 throw new ArgumentError.value(name, |
44 'name', | 44 'name', |
45 'Must be a String'); | 45 'Must be a String'); |
46 } | 46 } |
47 Map instantArguments = { | 47 Map instantArguments; |
48 'isolateNumber': '${Timeline._isolateId}' | |
49 }; | |
50 if (arguments is Map) { | 48 if (arguments is Map) { |
51 instantArguments.addAll(arguments); | 49 instantArguments = new Map.from(arguments); |
52 } | 50 } |
53 String argumentsAsJson = JSON.encode(instantArguments); | |
54 _reportInstantEvent(_getTraceClock(), | 51 _reportInstantEvent(_getTraceClock(), |
55 'Dart', | 52 'Dart', |
56 name, | 53 name, |
57 argumentsAsJson); | 54 _argumentsAsJson(instantArguments)); |
58 } | 55 } |
59 | 56 |
60 | 57 |
61 /// A utility method to time a synchronous [function]. Internally calls | 58 /// A utility method to time a synchronous [function]. Internally calls |
62 /// [function] bracketed by calls to [startSync] and [finishSync]. | 59 /// [function] bracketed by calls to [startSync] and [finishSync]. |
63 static dynamic timeSync(String name, | 60 static dynamic timeSync(String name, |
64 TimelineSyncFunction function, | 61 TimelineSyncFunction function, |
65 {Map arguments}) { | 62 {Map arguments}) { |
66 startSync(name, arguments: arguments); | 63 startSync(name, arguments: arguments); |
67 try { | 64 try { |
68 return function(); | 65 return function(); |
69 } finally { | 66 } finally { |
70 finishSync(); | 67 finishSync(); |
71 } | 68 } |
72 } | 69 } |
73 | 70 |
74 static final List<_SyncBlock> _stack = new List<_SyncBlock>(); | 71 static final List<_SyncBlock> _stack = new List<_SyncBlock>(); |
75 | |
76 static final int _isolateId = _getIsolateNum(); | 72 static final int _isolateId = _getIsolateNum(); |
| 73 static final String _isolateIdString = _isolateId.toString(); |
77 } | 74 } |
78 | 75 |
79 /// An asynchronous task on the timeline. An asynchronous task can have many | 76 /// An asynchronous task on the timeline. An asynchronous task can have many |
80 /// (nested) synchronous operations. Synchronous operations can live longer than | 77 /// (nested) synchronous operations. Synchronous operations can live longer than |
81 /// the current isolate event. To pass a [TimelineTask] to another isolate, | 78 /// the current isolate event. To pass a [TimelineTask] to another isolate, |
82 /// you must first call [pass] to get the task id and then construct a new | 79 /// you must first call [pass] to get the task id and then construct a new |
83 /// [TimelineTask] in the other isolate. | 80 /// [TimelineTask] in the other isolate. |
84 class TimelineTask { | 81 class TimelineTask { |
85 /// Create a task. [taskId] will be set by the system. | 82 /// Create a task. [taskId] will be set by the system. |
86 TimelineTask() | 83 TimelineTask() |
(...skipping 27 matching lines...) Expand all Loading... |
114 block._start(); | 111 block._start(); |
115 } | 112 } |
116 | 113 |
117 /// Emit an instant event for this task. | 114 /// Emit an instant event for this task. |
118 void instant(String name, {Map arguments}) { | 115 void instant(String name, {Map arguments}) { |
119 if (name is! String) { | 116 if (name is! String) { |
120 throw new ArgumentError.value(name, | 117 throw new ArgumentError.value(name, |
121 'name', | 118 'name', |
122 'Must be a String'); | 119 'Must be a String'); |
123 } | 120 } |
124 Map instantArguments = { | 121 Map instantArguments; |
125 'isolateNumber': '${Timeline._isolateId}' | |
126 }; | |
127 if (arguments is Map) { | 122 if (arguments is Map) { |
128 instantArguments.addAll(arguments); | 123 instantArguments = new Map.from(arguments); |
129 } | 124 } |
130 String argumentsAsJson = JSON.encode(instantArguments); | |
131 _reportTaskEvent(_getTraceClock(), | 125 _reportTaskEvent(_getTraceClock(), |
132 _taskId, | 126 _taskId, |
133 'n', | 127 'n', |
134 'Dart', | 128 'Dart', |
135 name, | 129 name, |
136 argumentsAsJson); | 130 _argumentsAsJson(instantArguments)); |
137 } | 131 } |
138 | 132 |
139 /// Finish the last synchronous operation that was started. | 133 /// Finish the last synchronous operation that was started. |
140 void finish() { | 134 void finish() { |
141 if (_stack.length == 0) { | 135 if (_stack.length == 0) { |
142 throw new StateError( | 136 throw new StateError( |
143 'Uneven calls to start and finish'); | 137 'Uneven calls to start and finish'); |
144 } | 138 } |
145 // Pop top item off of stack. | 139 // Pop top item off of stack. |
146 var block = _stack.removeLast(); | 140 var block = _stack.removeLast(); |
(...skipping 26 matching lines...) Expand all Loading... |
173 /// The asynchronous task id. | 167 /// The asynchronous task id. |
174 final int _taskId; | 168 final int _taskId; |
175 /// An (optional) set of arguments which will be serialized to JSON and | 169 /// An (optional) set of arguments which will be serialized to JSON and |
176 /// associated with this block. | 170 /// associated with this block. |
177 final Map arguments = {}; | 171 final Map arguments = {}; |
178 | 172 |
179 _AsyncBlock._(this.name, this._taskId); | 173 _AsyncBlock._(this.name, this._taskId); |
180 | 174 |
181 // Emit the start event. | 175 // Emit the start event. |
182 void _start() { | 176 void _start() { |
183 arguments['isolateNumber'] = '${Timeline._isolateId}'; | |
184 String argumentsAsJson = JSON.encode(arguments); | |
185 _reportTaskEvent(_getTraceClock(), | 177 _reportTaskEvent(_getTraceClock(), |
186 _taskId, | 178 _taskId, |
187 'b', | 179 'b', |
188 category, | 180 category, |
189 name, | 181 name, |
190 argumentsAsJson); | 182 _argumentsAsJson(arguments)); |
191 } | 183 } |
192 | 184 |
193 // Emit the finish event. | 185 // Emit the finish event. |
194 void _finish() { | 186 void _finish() { |
195 _reportTaskEvent(_getTraceClock(), | 187 _reportTaskEvent(_getTraceClock(), |
196 _taskId, | 188 _taskId, |
197 'e', | 189 'e', |
198 category, | 190 category, |
199 name, | 191 name, |
200 JSON.encode({})); | 192 _argumentsAsJson(null)); |
201 } | 193 } |
202 } | 194 } |
203 | 195 |
204 /// A synchronous block of time on the timeline. This block should not be | 196 /// A synchronous block of time on the timeline. This block should not be |
205 /// kept open across isolate messages. | 197 /// kept open across isolate messages. |
206 class _SyncBlock { | 198 class _SyncBlock { |
207 /// The category this block belongs to. | 199 /// The category this block belongs to. |
208 final String category = 'Dart'; | 200 final String category = 'Dart'; |
209 /// The name of this block. | 201 /// The name of this block. |
210 final String name; | 202 final String name; |
211 /// An (optional) set of arguments which will be serialized to JSON and | 203 /// An (optional) set of arguments which will be serialized to JSON and |
212 /// associated with this block. | 204 /// associated with this block. |
213 final Map arguments = {}; | 205 final Map arguments = {}; |
214 // The start time stamp. | 206 // The start time stamp. |
215 final int _start; | 207 final int _start; |
216 | 208 |
217 _SyncBlock._(this.name, | 209 _SyncBlock._(this.name, |
218 this._start); | 210 this._start); |
219 | 211 |
220 /// Finish this block of time. At this point, this block can no longer be | 212 /// Finish this block of time. At this point, this block can no longer be |
221 /// used. | 213 /// used. |
222 void finish() { | 214 void finish() { |
223 var end = _getTraceClock(); | |
224 | |
225 arguments['isolateNumber'] = '${Timeline._isolateId}'; | |
226 | |
227 // Encode arguments map as JSON before reporting. | |
228 var argumentsAsJson = JSON.encode(arguments); | |
229 | |
230 // Report event to runtime. | 215 // Report event to runtime. |
231 _reportCompleteEvent(_start, | 216 _reportCompleteEvent(_start, |
232 end, | 217 _getTraceClock(), |
233 category, | 218 category, |
234 name, | 219 name, |
235 argumentsAsJson); | 220 _argumentsAsJson(arguments)); |
236 } | 221 } |
237 } | 222 } |
238 | 223 |
| 224 String _fastPathArguments; |
| 225 String _argumentsAsJson(Map arguments) { |
| 226 if ((arguments == null) || (arguments.length == 0)) { |
| 227 // Fast path no arguments. Avoid calling JSON.encode. |
| 228 if (_fastPathArguments == null) { |
| 229 _fastPathArguments = '{"isolateNumber":"${Timeline._isolateId}"}'; |
| 230 } |
| 231 return _fastPathArguments; |
| 232 } |
| 233 // Add isolateNumber to arguments map. |
| 234 arguments['isolateNumber'] = Timeline._isolateIdString; |
| 235 return JSON.encode(arguments); |
| 236 } |
| 237 |
239 /// Returns the next async task id. | 238 /// Returns the next async task id. |
240 external int _getNextAsyncId(); | 239 external int _getNextAsyncId(); |
241 | 240 |
242 /// Returns the current value from the trace clock. | 241 /// Returns the current value from the trace clock. |
243 external int _getTraceClock(); | 242 external int _getTraceClock(); |
244 | 243 |
245 /// Returns the isolate's main port number. | 244 /// Returns the isolate's main port number. |
246 external int _getIsolateNum(); | 245 external int _getIsolateNum(); |
247 | 246 |
248 /// Reports an event for a task. | 247 /// Reports an event for a task. |
249 external void _reportTaskEvent(int start, | 248 external void _reportTaskEvent(int start, |
250 int taskId, | 249 int taskId, |
251 String phase, | 250 String phase, |
252 String category, | 251 String category, |
253 String name, | 252 String name, |
254 String argumentsAsJson); | 253 String argumentsAsJson); |
255 | 254 |
256 /// Reports a complete synchronous event. | 255 /// Reports a complete synchronous event. |
257 external void _reportCompleteEvent(int start, | 256 external void _reportCompleteEvent(int start, |
258 int end, | 257 int end, |
259 String category, | 258 String category, |
260 String name, | 259 String name, |
261 String argumentsAsJson); | 260 String argumentsAsJson); |
262 | 261 |
263 /// Reports an instant event. | 262 /// Reports an instant event. |
264 external void _reportInstantEvent(int start, | 263 external void _reportInstantEvent(int start, |
265 String category, | 264 String category, |
266 String name, | 265 String name, |
267 String argumentsAsJson); | 266 String argumentsAsJson); |
OLD | NEW |