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

Unified Diff: src/runtime.cc

Issue 6348002: Do not use possibly stale values for cache size, etc. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Next round Created 9 years, 11 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 | « src/objects-inl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 0cde7779a3d3fbb817b9825129fd5442f0dc2af3..2f1f54c6965cab37030644e5d29e3794a7c9c0cd 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -10654,51 +10654,12 @@ static MaybeObject* Runtime_Abort(Arguments args) {
}
-MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj,
- int index,
- Object* key_obj) {
- ASSERT(index % 2 == 0); // index of the key
- ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
- ASSERT(index < cache_obj->length());
-
- HandleScope scope;
-
- Handle<FixedArray> cache(cache_obj);
- Handle<Object> key(key_obj);
- Handle<JSFunction> factory(JSFunction::cast(
- cache->get(JSFunctionResultCache::kFactoryIndex)));
- // TODO(antonm): consider passing a receiver when constructing a cache.
- Handle<Object> receiver(Top::global_context()->global());
-
- Handle<Object> value;
- {
- // This handle is nor shared, nor used later, so it's safe.
- Object** argv[] = { key.location() };
- bool pending_exception = false;
- value = Execution::Call(factory,
- receiver,
- 1,
- argv,
- &pending_exception);
- if (pending_exception) return Failure::Exception();
- }
-
- cache->set(index, *key);
- cache->set(index + 1, *value);
- cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index));
-
- return *value;
-}
-
-
static MaybeObject* Runtime_GetFromCache(Arguments args) {
// This is only called from codegen, so checks might be more lax.
- CONVERT_CHECKED(FixedArray, cache, args[0]);
+ CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]);
Object* key = args[1];
- const int finger_index =
- Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value();
-
+ int finger_index = cache->finger_index();
Object* o = cache->get(finger_index);
if (o == key) {
// The fastest case: hit the same place again.
@@ -10710,35 +10671,78 @@ static MaybeObject* Runtime_GetFromCache(Arguments args) {
i -= 2) {
o = cache->get(i);
if (o == key) {
- cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
+ cache->set_finger_index(i);
return cache->get(i + 1);
}
}
- const int size =
- Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value();
+ int size = cache->size();
ASSERT(size <= cache->length());
for (int i = size - 2; i > finger_index; i -= 2) {
o = cache->get(i);
if (o == key) {
- cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i));
+ cache->set_finger_index(i);
return cache->get(i + 1);
}
}
- // Cache miss. If we have spare room, put new data into it, otherwise
- // evict post finger entry which must be least recently used.
- if (size < cache->length()) {
- cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2));
- return CacheMiss(cache, size, key);
+ // There is no value in the cache. Invoke the function and cache result.
+ HandleScope scope;
+
+ Handle<JSFunctionResultCache> cache_handle(cache);
+ Handle<Object> key_handle(key);
+ Handle<Object> value;
+ {
+ Handle<JSFunction> factory(JSFunction::cast(
+ cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
+ // TODO(antonm): consider passing a receiver when constructing a cache.
+ Handle<Object> receiver(Top::global_context()->global());
+ // This handle is nor shared, nor used later, so it's safe.
+ Object** argv[] = { key_handle.location() };
+ bool pending_exception = false;
+ value = Execution::Call(factory,
+ receiver,
+ 1,
+ argv,
+ &pending_exception);
+ if (pending_exception) return Failure::Exception();
+ }
+
+#ifdef DEBUG
+ cache_handle->JSFunctionResultCacheVerify();
+#endif
+
+ // Function invocation may have cleared the cache. Reread all the data.
+ finger_index = cache_handle->finger_index();
+ size = cache_handle->size();
+
+ // If we have spare room, put new data into it, otherwise evict post finger
+ // entry which is likely to be the least recently used.
+ int index = -1;
+ if (size < cache_handle->length()) {
+ cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
+ index = size;
} else {
- int target_index = finger_index + JSFunctionResultCache::kEntrySize;
- if (target_index == cache->length()) {
- target_index = JSFunctionResultCache::kEntriesIndex;
+ index = finger_index + JSFunctionResultCache::kEntrySize;
+ if (index == cache_handle->length()) {
+ index = JSFunctionResultCache::kEntriesIndex;
}
- return CacheMiss(cache, target_index, key);
}
+
+ ASSERT(index % 2 == 0);
+ ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
+ ASSERT(index < cache_handle->length());
+
+ cache_handle->set(index, *key_handle);
+ cache_handle->set(index + 1, *value);
+ cache_handle->set_finger_index(index);
+
+#ifdef DEBUG
+ cache_handle->JSFunctionResultCacheVerify();
+#endif
+
+ return *value;
}
#ifdef DEBUG
« no previous file with comments | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698