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:
parent
6b4f5aba96
commit
a0257ca1a0
11
src/ic.cc
11
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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user