Chromium Code Reviews| Index: runtime/lib/mirrors_impl.dart |
| diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart |
| index 89b7f0581bd505f1084e83d346642d45da5d043f..8a928713afc2acb3d33bfd1881bdaccf0a36aa20 100644 |
| --- a/runtime/lib/mirrors_impl.dart |
| +++ b/runtime/lib/mirrors_impl.dart |
| @@ -5,7 +5,7 @@ |
| // VM-specific implementation of the dart:mirrors library. |
| import "dart:collection" show UnmodifiableListView, UnmodifiableMapView; |
| -import "dart:_internal" show LRUMap; |
| +import "dart:_internal" show Cache; |
| final emptyList = new UnmodifiableListView([]); |
| final emptyMap = new UnmodifiableMapView({}); |
| @@ -299,40 +299,30 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| return identityHashCode(_reflectee) ^ 0x36363636; |
| } |
| - static var _getFieldClosures = new LRUMap.withShift(9); |
| - static var _setFieldClosures = new LRUMap.withShift(9); |
| - static var _getFieldCallCounts = new LRUMap.withShift(10); |
| - static var _setFieldCallCounts = new LRUMap.withShift(10); |
| - static const _closureThreshold = 20; |
| + static var _getFieldClosures = new Cache.withInitialShift(4); |
| + static var _setFieldClosures = new Cache.withInitialShift(4); |
| + |
| + _createGetterClosure(unwrapped) { |
| + var atPosition = unwrapped.indexOf('@'); |
| + if (atPosition == -1) { |
| + // Public symbol. |
| + return _eval('(x) => x.$unwrapped', null); |
| + } else { |
| + // Private symbol. |
| + var withoutKey = unwrapped.substring(0, atPosition); |
| + var privateKey = unwrapped.substring(atPosition); |
| + return _eval('(x) => x.$withoutKey', privateKey); |
| + } |
| + } |
| _getFieldSlow(unwrapped) { |
| // Slow path factored out to give the fast path a better chance at being |
| // inlined. |
| - var callCount = _getFieldCallCounts[unwrapped]; |
| - if (callCount == null) { |
| - callCount = 0; |
| - } |
| - if (callCount == _closureThreshold) { |
| - // We've seen a successful setter invocation a few times: time to invest |
| - // in a closure. |
| - var f; |
| - var atPosition = unwrapped.indexOf('@'); |
| - if (atPosition == -1) { |
| - // Public symbol. |
| - f = _eval('(x) => x.$unwrapped', null); |
| - } else { |
| - // Private symbol. |
| - var withoutKey = unwrapped.substring(0, atPosition); |
| - var privateKey = unwrapped.substring(atPosition); |
| - f = _eval('(x) => x.$withoutKey', privateKey); |
| - } |
| - _getFieldClosures[unwrapped] = f; |
| - return reflect(f(_reflectee)); |
| - } |
| var result = reflect(_invokeGetter(_reflectee, unwrapped)); |
| - // Only update call count if we don't throw to avoid creating closures for |
| - // non-existent getters. |
| - _getFieldCallCounts[unwrapped] = callCount + 1; |
| + // Wait until success to avoid creating closures for non-existent getters. |
| + _getFieldClosures[unwrapped] = (r) { |
| + return (_getFieldClosures[unwrapped] = _createGetterClosure(unwrapped))(r); |
|
Ivan Posva
2014/08/06 23:05:14
Long line?
|
| + }; |
| return result; |
| } |
| @@ -342,35 +332,28 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| return (f == null) ? _getFieldSlow(unwrapped) : reflect(f(_reflectee)); |
| } |
| + _createSetterClosure(unwrapped) { |
| + var atPosition = unwrapped.indexOf('@'); |
| + if (atPosition == -1) { |
| + // Public symbol. |
| + return _eval('(x, v) => x.$unwrapped = v', null); |
| + } else { |
| + // Private symbol. |
| + var withoutKey = unwrapped.substring(0, atPosition); |
| + var privateKey = unwrapped.substring(atPosition); |
| + return _eval('(x, v) => x.$withoutKey = v', privateKey); |
| + } |
| + } |
| + |
| _setFieldSlow(unwrapped, arg) { |
| // Slow path factored out to give the fast path a better chance at being |
| // inlined. |
| - var callCount = _setFieldCallCounts[unwrapped]; |
| - if (callCount == null) { |
| - callCount = 0; |
| - } |
| - if (callCount == _closureThreshold) { |
| - // We've seen a successful getter invocation a few times: time to invest |
| - // in a closure. |
| - var f; |
| - var atPosition = unwrapped.indexOf('@'); |
| - if (atPosition == -1) { |
| - // Public symbol. |
| - f = _eval('(x, v) => x.$unwrapped = v', null); |
| - } else { |
| - // Private symbol. |
| - var withoutKey = unwrapped.substring(0, atPosition); |
| - var privateKey = unwrapped.substring(atPosition); |
| - f = _eval('(x, v) => x.$withoutKey = v', privateKey); |
| - } |
| - _setFieldClosures[unwrapped] = f; |
| - return reflect(f(_reflectee, arg)); |
| - } |
| _invokeSetter(_reflectee, unwrapped, arg); |
| var result = reflect(arg); |
| - // Only update call count if we don't throw to avoid creating closures for |
| - // non-existent setters. |
| - _setFieldCallCounts[unwrapped] = callCount + 1; |
| + // Wait until success to avoid creating closures for non-existent setters. |
| + _setFieldClosures[unwrapped] = (r, v) { |
| + return (_setFieldClosures[unwrapped] = _createSetterClosure(unwrapped))(r, v); |
| + }; |
| return result; |
| } |