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

Unified Diff: runtime/lib/mirrors_impl.dart

Issue 241703002: Prevent unbounded growth of the getField/setField closure caches. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
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));

Powered by Google App Engine
This is Rietveld 408576698