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
This commit is contained in:
ager@chromium.org 2008-09-16 12:41:36 +00:00
parent 6b4f5aba96
commit a0257ca1a0
3 changed files with 22 additions and 11 deletions

View File

@ -143,7 +143,8 @@ IC::State IC::StateFrom(Code* target, Object* receiver) {
// the receiver map's code cache. Therefore, if the current target // the receiver map's code cache. Therefore, if the current target
// is in the receiver map's code cache, the inline cache failed due // is in the receiver map's code cache, the inline cache failed due
// to prototype check failure. // 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 // For keyed load/store, the most likely cause of cache failure is
// that the key has changed. We do not distinguish between // that the key has changed. We do not distinguish between
// prototype and non-prototype failures for keyed access. // prototype and non-prototype failures for keyed access.
@ -152,11 +153,9 @@ IC::State IC::StateFrom(Code* target, Object* receiver) {
return MONOMORPHIC; return MONOMORPHIC;
} }
// Clear the code cache for this map to avoid hitting the same // Remove the target from the code cache to avoid hitting the same
// invalid stub again. It seems likely that most of the code in // invalid stub again.
// the cache is invalid if one of the stubs is so we flush the map->RemoveFromCodeCache(index);
// entire code cache.
map->ClearCodeCache();
return MONOMORPHIC_PROTOTYPE_FAILURE; return MONOMORPHIC_PROTOTYPE_FAILURE;
} }

View File

@ -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(); FixedArray* array = code_cache();
int len = array->length(); int len = array->length();
for (int i = 0; i < len; i += 2) { 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
} }

View File

@ -2343,8 +2343,12 @@ class Map: public HeapObject {
// Returns the found code or undefined if absent. // Returns the found code or undefined if absent.
Object* FindInCodeCache(String* name, Code::Flags flags); Object* FindInCodeCache(String* name, Code::Flags flags);
// Tells whether code is in the code cache. // Returns the non-negative index of the code object if it is in the
bool IncludedInCodeCache(Code* code); // 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. // Dispatched behavior.
void MapIterateBody(ObjectVisitor* v); void MapIterateBody(ObjectVisitor* v);