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

Side by Side Diff: sdk/lib/async/future_impl.dart

Issue 1524533002: Try reducing code size for _prependListeners. Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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.async; 5 part of dart.async;
6 6
7 /** The onValue and onError handlers return either a value or a future */ 7 /** The onValue and onError handlers return either a value or a future */
8 typedef dynamic _FutureOnValue<T>(T value); 8 typedef dynamic _FutureOnValue<T>(T value);
9 /** Test used by [Future.catchError] to handle skip some errors. */ 9 /** Test used by [Future.catchError] to handle skip some errors. */
10 typedef bool _FutureErrorTest(var error); 10 typedef bool _FutureErrorTest(var error);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 _state = _PENDING_COMPLETE; 233 _state = _PENDING_COMPLETE;
234 } 234 }
235 235
236 AsyncError get _error { 236 AsyncError get _error {
237 assert(_hasError); 237 assert(_hasError);
238 return _resultOrListeners; 238 return _resultOrListeners;
239 } 239 }
240 240
241 _Future get _chainSource { 241 _Future get _chainSource {
242 assert(_isChained); 242 assert(_isChained);
243 return _resultOrListeners; 243 _Future result = _resultOrListeners;
244 while (result._isChained) {
245 result = result._resultOrListeners;
246 _resultOrListeners = result;
247 }
248 return result;
244 } 249 }
245 250
246 // This method is used by async/await. 251 // This method is used by async/await.
247 void _setValue(T value) { 252 void _setValue(T value) {
248 assert(!_isComplete); // But may have a completion pending. 253 assert(!_isComplete); // But may have a completion pending.
249 _state = _VALUE; 254 _state = _VALUE;
250 _resultOrListeners = value; 255 _resultOrListeners = value;
251 } 256 }
252 257
253 void _setErrorObject(AsyncError error) { 258 void _setErrorObject(AsyncError error) {
(...skipping 15 matching lines...) Expand all
269 _state = source._state; 274 _state = source._state;
270 _resultOrListeners = source._resultOrListeners; 275 _resultOrListeners = source._resultOrListeners;
271 } 276 }
272 277
273 void _addListener(_FutureListener listener) { 278 void _addListener(_FutureListener listener) {
274 assert(listener._nextListener == null); 279 assert(listener._nextListener == null);
275 if (_mayAddListener) { 280 if (_mayAddListener) {
276 listener._nextListener = _resultOrListeners; 281 listener._nextListener = _resultOrListeners;
277 _resultOrListeners = listener; 282 _resultOrListeners = listener;
278 } else { 283 } else {
279 if (_isChained) { 284 _handleListener(listener);
280 // Delegate listeners to chained source future.
281 // If the source is complete, instead copy its values and
282 // drop the chaining.
283 _Future source = _chainSource;
284 if (!source._isComplete) {
285 source._addListener(listener);
286 return;
287 }
288 _cloneResult(source);
289 }
290 assert(_isComplete);
291 // Handle late listeners asynchronously.
292 _zone.scheduleMicrotask(() {
293 _propagateToListeners(this, listener);
294 });
295 } 285 }
296 } 286 }
297 287
288 void _handleListener(_FutureListener listener) {
289 assert(listener._nextListener == null);
290 assert(!_mayAddListener);
291 if (_isChained) {
292 _Future source = _chainSource;
293 // Delegate listeners to chained source future.
294 // If the source is complete, instead copy its values and
295 // drop the chaining.
296 if (!source._isComplete) {
297 source._addListener(listener);
298 return;
299 }
300 _cloneResult(source);
301 }
302 assert(_isComplete);
303 // Handle late listeners asynchronously.
304 _zone.scheduleMicrotask(() {
305 _propagateToListeners(this, listener);
306 });
307 }
308
298 void _prependListeners(_FutureListener listeners) { 309 void _prependListeners(_FutureListener listeners) {
299 if (listeners == null) return; 310 while (listeners != null) {
300 if (_mayAddListener) { 311 _FutureListener first = listeners;
301 _FutureListener existingListeners = _resultOrListeners; 312 listeners = listeners._nextListener;
302 _resultOrListeners = listeners; 313 first._nextListener = null;
303 if (existingListeners != null) { 314 _addListener(first);
304 _FutureListener cursor = listeners;
305 while (cursor._nextListener != null) {
306 cursor = cursor._nextListener;
307 }
308 cursor._nextListener = existingListeners;
309 }
310 } else {
311 if (_isChained) {
312 // Delegate listeners to chained source future.
313 // If the source is complete, instead copy its values and
314 // drop the chaining.
315 _Future source = _chainSource;
316 if (!source._isComplete) {
317 source._prependListeners(listeners);
318 return;
319 }
320 _cloneResult(source);
321 }
322 assert(_isComplete);
323 listeners = _reverseListeners(listeners);
324 _zone.scheduleMicrotask(() {
325 _propagateToListeners(this, listeners);
326 });
327 } 315 }
328 } 316 }
329 317
330 _FutureListener _removeListeners() { 318 _FutureListener _removeListeners() {
331 // Reverse listeners before returning them, so the resulting list is in 319 // Reverse listeners before returning them, so the resulting list is in
332 // subscription order. 320 // subscription order.
333 assert(!_isComplete); 321 assert(!_isComplete);
334 _FutureListener current = _resultOrListeners; 322 _FutureListener current = _resultOrListeners;
335 _resultOrListeners = null; 323 _resultOrListeners = null;
336 return _reverseListeners(current);
337 }
338
339 _FutureListener _reverseListeners(_FutureListener listeners) {
340 _FutureListener prev = null; 324 _FutureListener prev = null;
341 _FutureListener current = listeners;
342 while (current != null) { 325 while (current != null) {
343 _FutureListener next = current._nextListener; 326 _FutureListener next = current._nextListener;
344 current._nextListener = prev; 327 current._nextListener = prev;
345 prev = current; 328 prev = current;
346 current = next; 329 current = next;
347 } 330 }
348 return prev; 331 return prev;
349 } 332 }
350 333
351 // Take the value (when completed) of source and complete target with that 334 // Take the value (when completed) of source and complete target with that
(...skipping 30 matching lines...) Expand all
382 } 365 }
383 } 366 }
384 367
385 // Take the value (when completed) of source and complete target with that 368 // Take the value (when completed) of source and complete target with that
386 // value (or error). This function expects that source is a _Future. 369 // value (or error). This function expects that source is a _Future.
387 static void _chainCoreFuture(_Future source, _Future target) { 370 static void _chainCoreFuture(_Future source, _Future target) {
388 assert(target._mayAddListener); // Not completed, not already chained. 371 assert(target._mayAddListener); // Not completed, not already chained.
389 while (source._isChained) { 372 while (source._isChained) {
390 source = source._chainSource; 373 source = source._chainSource;
391 } 374 }
375 _FutureListener listeners = target._removeListeners();
392 if (source._isComplete) { 376 if (source._isComplete) {
393 _FutureListener listeners = target._removeListeners();
394 target._cloneResult(source); 377 target._cloneResult(source);
395 _propagateToListeners(target, listeners); 378 _propagateToListeners(target, listeners);
396 } else { 379 } else {
397 _FutureListener listeners = target._resultOrListeners;
398 target._setChained(source); 380 target._setChained(source);
399 source._prependListeners(listeners); 381 source._prependListeners(listeners);
400 } 382 }
401 } 383 }
402 384
403 void _complete(value) { 385 void _complete(value) {
404 assert(!_isComplete); 386 assert(!_isComplete);
405 if (value is Future) { 387 if (value is Future) {
406 if (value is _Future) { 388 if (value is _Future) {
407 _chainCoreFuture(value, this); 389 _chainCoreFuture(value, this);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 } 689 }
708 }, onError: (e, s) { 690 }, onError: (e, s) {
709 if (timer.isActive) { 691 if (timer.isActive) {
710 timer.cancel(); 692 timer.cancel();
711 result._completeError(e, s); 693 result._completeError(e, s);
712 } 694 }
713 }); 695 });
714 return result; 696 return result;
715 } 697 }
716 } 698 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698