From: ager@chromium.org Date: Tue, 16 Sep 2008 12:41:36 +0000 (+0000) Subject: Only remove the code object that caused the monomorphic prototype X-Git-Tag: upstream/4.7.83~25363 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a0257ca1a0d8c2e9a17e31dbe930ecbd8cd1a01d;p=platform%2Fupstream%2Fv8.git Only remove the code object that caused the monomorphic prototype failure instead of clearing the cache. Clearing the cache makes us miss subsequent monomorphic prototype failures. Review URL: http://codereview.chromium.org/2889 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@318 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ic.cc b/src/ic.cc index be90d8034..59794ea72 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -143,7 +143,8 @@ IC::State IC::StateFrom(Code* target, Object* receiver) { // the receiver map's code cache. Therefore, if the current target // is in the receiver map's code cache, the inline cache failed due // to prototype check failure. - if (map->IncludedInCodeCache(target)) { + int index = map->IndexInCodeCache(target); + if (index >= 0) { // For keyed load/store, the most likely cause of cache failure is // that the key has changed. We do not distinguish between // prototype and non-prototype failures for keyed access. @@ -152,11 +153,9 @@ IC::State IC::StateFrom(Code* target, Object* receiver) { return MONOMORPHIC; } - // Clear the code cache for this map to avoid hitting the same - // invalid stub again. It seems likely that most of the code in - // the cache is invalid if one of the stubs is so we flush the - // entire code cache. - map->ClearCodeCache(); + // Remove the target from the code cache to avoid hitting the same + // invalid stub again. + map->RemoveFromCodeCache(index); return MONOMORPHIC_PROTOTYPE_FAILURE; } diff --git a/src/objects.cc b/src/objects.cc index 22640e8a5..1e42d0244 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2427,13 +2427,21 @@ Object* Map::FindInCodeCache(String* name, Code::Flags flags) { } -bool Map::IncludedInCodeCache(Code* code) { +int Map::IndexInCodeCache(Code* code) { FixedArray* array = code_cache(); int len = array->length(); for (int i = 0; i < len; i += 2) { - if (array->get(i+1) == code) return true; + if (array->get(i + 1) == code) return i + 1; } - return false; + return -1; +} + + +void Map::RemoveFromCodeCache(int index) { + FixedArray* array = code_cache(); + ASSERT(array->length() >= index && array->get(index)->IsCode()); + array->set_undefined(index - 1); // key + array->set_undefined(index); // code } diff --git a/src/objects.h b/src/objects.h index 841db2d0e..53a2fece8 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2343,8 +2343,12 @@ class Map: public HeapObject { // Returns the found code or undefined if absent. Object* FindInCodeCache(String* name, Code::Flags flags); - // Tells whether code is in the code cache. - bool IncludedInCodeCache(Code* code); + // Returns the non-negative index of the code object if it is in the + // cache and -1 otherwise. + int IndexInCodeCache(Code* code); + + // Removes a code object from the code cache at the given index. + void RemoveFromCodeCache(int index); // Dispatched behavior. void MapIterateBody(ObjectVisitor* v);