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

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: document test purpose and need for LRU cache 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
« no previous file with comments | « no previous file | tests/lib/mirrors/accessor_cache_overflow_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/lib/mirrors_impl.dart
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 9d8e9cba11ad5341323e7f2462805d4d24d85680..dd0ebd93c2873a3361a0088dfcf685e2ad60e4ed 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -298,23 +298,28 @@ class _LocalInstanceMirror extends _LocalObjectMirror
return identityHashCode(_reflectee) ^ 0x36363636;
}
- // TODO(16539): Make these weak or soft.
+ // TODO(18445): Use an LRU cache.
static var _getFieldClosures = new HashMap();
static var _setFieldClosures = new HashMap();
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) {
+ // 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 setter invocation a few times: time to invest
+ // in a closure.
var f;
var atPosition = unwrapped.indexOf('@');
if (atPosition == -1) {
@@ -326,6 +331,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));
@@ -346,13 +355,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 getter invocation a few times: time to invest
+ // in a closure.
var f;
var atPosition = unwrapped.indexOf('@');
if (atPosition == -1) {
@@ -364,6 +376,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));
« no previous file with comments | « no previous file | tests/lib/mirrors/accessor_cache_overflow_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698