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

Side by Side Diff: runtime/lib/mirrors_impl.dart

Issue 144383007: Optimize getField by caching a closure generated from eval. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: avoid entries for MNU Created 6 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) 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 // VM-specific implementation of the dart:mirrors library. 5 // VM-specific implementation of the dart:mirrors library.
6 6
7 import "dart:collection"; 7 import "dart:collection";
8 8
9 final emptyList = new UnmodifiableListView([]); 9 final emptyList = new UnmodifiableListView([]);
10 final emptyMap = new _UnmodifiableMapView({}); 10 final emptyMap = new _UnmodifiableMapView({});
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 } 325 }
326 } 326 }
327 if (!found) { 327 if (!found) {
328 throw new ArgumentError( 328 throw new ArgumentError(
329 "${MirrorSystem.getName(type.simpleName)} has no instance method " 329 "${MirrorSystem.getName(type.simpleName)} has no instance method "
330 "${MirrorSystem.getName(selector)}"); 330 "${MirrorSystem.getName(selector)}");
331 } 331 }
332 return new _InvocationTrampoline(this, selector); 332 return new _InvocationTrampoline(this, selector);
333 } 333 }
334 334
335 // TODO(16539): Make these weak or soft.
336 static var _getFieldClosures = new HashMap();
337 static var _setFieldClosures = new HashMap();
338 static var _getFieldCallCounts = new HashMap();
339 static var _setFieldCallCounts = new HashMap();
340
341 _getFieldSlow(unwrapped) {
342 // Slow path factored out to give the fast path a better chance at being
343 // inlined.
344 var callCount = _getFieldCallCounts[unwrapped];
345 if (callCount == null) {
346 callCount = 0;
347 }
348 if (callCount == 20) {
Ivan Posva 2014/02/05 22:23:44 How about naming this arbitrary constant and pulli
rmacnak 2014/02/05 22:56:31 Done.
349 // We've seen a success getter invocation a few times: time to invest in a
350 // closure.
351 var f;
352 var atPosition = unwrapped.indexOf('@');
353 if (atPosition == -1) {
354 // Public symbol.
355 f = _eval('(x) => x.$unwrapped', null);
356 } else {
357 // Private symbol.
358 var withoutKey = unwrapped.substring(0, atPosition);
359 var privateKey = unwrapped.substring(atPosition);
360 f = _eval('(x) => x.$withoutKey', privateKey);
361 }
362 _getFieldClosures[unwrapped] = f;
363 _getFieldCallCounts.remove(unwrapped); // We won't look for this again.
364 return reflect(f(_reflectee));
365 }
366 var result = reflect(_invokeGetter(_reflectee, unwrapped));
367 // Only update call count if we don't throw to avoid creating closures for
368 // non-existent getters.
369 _getFieldCallCounts[unwrapped] = callCount + 1;
370 return result;
371 }
372
373 InstanceMirror getField(Symbol memberName) {
374 var unwrapped = _n(memberName);
375 var f = _getFieldClosures[unwrapped];
376 return (f == null)
Ivan Posva 2014/02/05 22:23:44 return (f == null) ? _getFieldSlow(unwrapped
rmacnak 2014/02/05 22:56:31 Done.
377 ? _getFieldSlow(unwrapped)
378 : reflect(f(_reflectee));
379 }
380
381 _setFieldSlow(unwrapped, arg) {
382 // Slow path factored out to give the fast path a better chance at being
383 // inlined.
384 var callCount = _setFieldCallCounts[unwrapped];
385 if (callCount == null) {
386 callCount = 0;
387 }
388 if (callCount == 20) {
389 // We've seen a success getter invocation a few times: time to invest in a
390 // closure.
391 var f;
392 var atPosition = unwrapped.indexOf('@');
393 if (atPosition == -1) {
394 // Public symbol.
395 f = _eval('(x, v) => x.$unwrapped = v', null);
396 } else {
397 // Private symbol.
398 var withoutKey = unwrapped.substring(0, atPosition);
399 var privateKey = unwrapped.substring(atPosition);
400 f = _eval('(x, v) => x.$withoutKey = v', privateKey);
401 }
402 _setFieldClosures[unwrapped] = f;
403 _setFieldCallCounts.remove(unwrapped);
404 return reflect(f(_reflectee, arg));
405 }
406 _invokeSetter(_reflectee, unwrapped, arg);
407 var result = reflect(arg);
408 // Only update call count if we don't throw to avoid creating closures for
409 // non-existent setters.
410 _setFieldCallCounts[unwrapped] = callCount + 1;
411 return result;
412 }
413
414 InstanceMirror setField(Symbol memberName, arg) {
415 var unwrapped = _n(memberName);
416 var f = _setFieldClosures[unwrapped];
417 return (f == null)
418 ? _setFieldSlow(unwrapped, arg)
419 : reflect(f(_reflectee, arg));
420 }
421
422 static _eval(expression, privateKey)
423 native "Mirrors_evalInLibraryWithPrivateKey";
424
335 // Override to include the receiver in the arguments. 425 // Override to include the receiver in the arguments.
336 InstanceMirror invoke(Symbol memberName, 426 InstanceMirror invoke(Symbol memberName,
337 List positionalArguments, 427 List positionalArguments,
338 [Map<Symbol, dynamic> namedArguments]) { 428 [Map<Symbol, dynamic> namedArguments]) {
339 int numPositionalArguments = positionalArguments.length + 1; // Receiver. 429 int numPositionalArguments = positionalArguments.length + 1; // Receiver.
340 int numNamedArguments = namedArguments != null ? namedArguments.length : 0; 430 int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
341 int numArguments = numPositionalArguments + numNamedArguments; 431 int numArguments = numPositionalArguments + numNamedArguments;
342 List arguments = new List(numArguments); 432 List arguments = new List(numArguments);
343 arguments[0] = _reflectee; // Receiver. 433 arguments[0] = _reflectee; // Receiver.
344 arguments.setRange(1, numPositionalArguments, positionalArguments); 434 arguments.setRange(1, numPositionalArguments, positionalArguments);
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 if (typeMirror == null) { 1582 if (typeMirror == null) {
1493 typeMirror = makeLocalTypeMirror(key); 1583 typeMirror = makeLocalTypeMirror(key);
1494 _instanitationCache[key] = typeMirror; 1584 _instanitationCache[key] = typeMirror;
1495 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { 1585 if (typeMirror is ClassMirror && !typeMirror._isGeneric) {
1496 _declarationCache[key] = typeMirror; 1586 _declarationCache[key] = typeMirror;
1497 } 1587 }
1498 } 1588 }
1499 return typeMirror; 1589 return typeMirror;
1500 } 1590 }
1501 } 1591 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698