Chromium Code Reviews| Index: runtime/lib/mirrors_impl.dart |
| diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart |
| index 9983abba1410f3288f11f6f7bb3cdefdbc63ff3d..ccf55cb61711e5141177223e38e4f47fe1c17990 100644 |
| --- a/runtime/lib/mirrors_impl.dart |
| +++ b/runtime/lib/mirrors_impl.dart |
| @@ -330,17 +330,22 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| static var _getFieldCallCounts = new HashMap(); |
| static var _setFieldCallCounts = new HashMap(); |
| static const _closureThreshold = 20; |
| + static const _cacheSizeLimit = 255; |
| _getFieldSlow(unwrapped) { |
| // Slow path factored out to give the fast path a better chance at being |
| // inlined. |
| + if (_getFieldCallCounts.length == 2 * _cacheSizeLimit) { |
|
Ivan Posva
2014/04/25 17:07:08
Please file a bug that we need to implement a LRU
rmacnak
2014/04/25 17:46:22
Done.
|
| + // Prevent unbounded cache growth. |
| + _getFieldCallCounts = new HashMap(); |
| + } |
| var callCount = _getFieldCallCounts[unwrapped]; |
| if (callCount == null) { |
| callCount = 0; |
| } |
| if (callCount == _closureThreshold) { |
| - // We've seen a success getter invocation a few times: time to invest in a |
| - // closure. |
| + // 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) { |
| @@ -352,6 +357,10 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| var privateKey = unwrapped.substring(atPosition); |
| f = _eval('(x) => x.$withoutKey', privateKey); |
| } |
| + if (_getFieldClosures.length == _cacheSizeLimit) { |
| + // Prevent unbounded cache growth. |
| + _getFieldClosures = new HashMap(); |
| + } |
| _getFieldClosures[unwrapped] = f; |
| _getFieldCallCounts.remove(unwrapped); // We won't look for this again. |
| return reflect(f(_reflectee)); |
| @@ -372,13 +381,16 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| _setFieldSlow(unwrapped, arg) { |
| // Slow path factored out to give the fast path a better chance at being |
| // inlined. |
| + if (_setFieldCallCounts.length == 2 * _cacheSizeLimit) { |
| + _setFieldCallCounts = new HashMap(); |
| + } |
| var callCount = _setFieldCallCounts[unwrapped]; |
| if (callCount == null) { |
| callCount = 0; |
| } |
| if (callCount == _closureThreshold) { |
| - // We've seen a success getter invocation a few times: time to invest in a |
| - // closure. |
| + // 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) { |
| @@ -390,6 +402,10 @@ class _LocalInstanceMirror extends _LocalObjectMirror |
| var privateKey = unwrapped.substring(atPosition); |
| f = _eval('(x, v) => x.$withoutKey = v', privateKey); |
| } |
| + if (_setFieldClosures.length == _cacheSizeLimit) { |
| + // Prevent unbounded cache growth. |
| + _setFieldClosures = new HashMap(); |
| + } |
| _setFieldClosures[unwrapped] = f; |
| _setFieldCallCounts.remove(unwrapped); |
| return reflect(f(_reflectee, arg)); |