Commit 950ad34a authored by ager@chromium.org's avatar ager@chromium.org

Propagate the information that a monomorphic prototype failure has

occured.  After a monomorphic prototype failure has been detected,
other monomorphic inline caches for the same type will have a code
object in the map's code cache which is not the current target.  We
recognize this case and use the code object that is in the cache
instead of going megamorphic.

Review URL: http://codereview.chromium.org/2928

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@331 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 08e6b7c3
This diff is collapsed.
...@@ -81,8 +81,12 @@ class IC { ...@@ -81,8 +81,12 @@ class IC {
Code* target() { return GetTargetAtAddress(address()); } Code* target() { return GetTargetAtAddress(address()); }
inline Address address(); inline Address address();
// Compute the current IC state based on the target stub and the receiver. // Compute the state of the current inline cache. If the current
static State StateFrom(Code* target, Object* receiver); // inline cache is monomorphic, this might change the code cache in
// the receiver map and it might return a code object from the code
// cache in the receiver map that should be used as the new target.
static State ComputeCacheState(Code* target, Object* receiver,
Object* name, Object** new_target);
// Clear the inline cache to initial state. // Clear the inline cache to initial state.
static void Clear(Address address); static void Clear(Address address);
...@@ -161,7 +165,7 @@ class CallIC: public IC { ...@@ -161,7 +165,7 @@ class CallIC: public IC {
public: public:
CallIC() : IC(EXTRA_CALL_FRAME) { ASSERT(target()->is_call_stub()); } CallIC() : IC(EXTRA_CALL_FRAME) { ASSERT(target()->is_call_stub()); }
Object* LoadFunction(State state, Handle<Object> object, Handle<String> name); Object* LoadFunction(Handle<Object> object, Handle<String> name);
// Code generator routines. // Code generator routines.
...@@ -179,7 +183,6 @@ class CallIC: public IC { ...@@ -179,7 +183,6 @@ class CallIC: public IC {
// Update the inline cache and the global stub cache based on the // Update the inline cache and the global stub cache based on the
// lookup result. // lookup result.
void UpdateCaches(LookupResult* lookup, void UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object, Handle<Object> object,
Handle<String> name); Handle<String> name);
...@@ -197,7 +200,7 @@ class LoadIC: public IC { ...@@ -197,7 +200,7 @@ class LoadIC: public IC {
public: public:
LoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_load_stub()); } LoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_load_stub()); }
Object* Load(State state, Handle<Object> object, Handle<String> name); Object* Load(Handle<Object> object, Handle<String> name);
// Code generator routines. // Code generator routines.
static void GenerateInitialize(MacroAssembler* masm); static void GenerateInitialize(MacroAssembler* masm);
...@@ -219,7 +222,6 @@ class LoadIC: public IC { ...@@ -219,7 +222,6 @@ class LoadIC: public IC {
// Update the inline cache and the global stub cache based on the // Update the inline cache and the global stub cache based on the
// lookup result. // lookup result.
void UpdateCaches(LookupResult* lookup, void UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object, Handle<Object> object,
Handle<String> name); Handle<String> name);
...@@ -243,7 +245,7 @@ class KeyedLoadIC: public IC { ...@@ -243,7 +245,7 @@ class KeyedLoadIC: public IC {
public: public:
KeyedLoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_keyed_load_stub()); } KeyedLoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_keyed_load_stub()); }
Object* Load(State state, Handle<Object> object, Handle<Object> key); Object* Load(Handle<Object> object, Handle<Object> key);
// Code generator routines. // Code generator routines.
static void GenerateMiss(MacroAssembler* masm); static void GenerateMiss(MacroAssembler* masm);
...@@ -256,7 +258,6 @@ class KeyedLoadIC: public IC { ...@@ -256,7 +258,6 @@ class KeyedLoadIC: public IC {
// Update the inline cache. // Update the inline cache.
void UpdateCaches(LookupResult* lookup, void UpdateCaches(LookupResult* lookup,
State state,
Handle<Object> object, Handle<Object> object,
Handle<String> name); Handle<String> name);
...@@ -283,8 +284,7 @@ class StoreIC: public IC { ...@@ -283,8 +284,7 @@ class StoreIC: public IC {
public: public:
StoreIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_store_stub()); } StoreIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_store_stub()); }
Object* Store(State state, Object* Store(Handle<Object> object,
Handle<Object> object,
Handle<String> name, Handle<String> name,
Handle<Object> value); Handle<Object> value);
...@@ -299,7 +299,7 @@ class StoreIC: public IC { ...@@ -299,7 +299,7 @@ class StoreIC: public IC {
// Update the inline cache and the global stub cache based on the // Update the inline cache and the global stub cache based on the
// lookup result. // lookup result.
void UpdateCaches(LookupResult* lookup, void UpdateCaches(LookupResult* lookup,
State state, Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value); Handle<Object> value);
...@@ -320,8 +320,7 @@ class KeyedStoreIC: public IC { ...@@ -320,8 +320,7 @@ class KeyedStoreIC: public IC {
public: public:
KeyedStoreIC() : IC(NO_EXTRA_FRAME) { } KeyedStoreIC() : IC(NO_EXTRA_FRAME) { }
Object* Store(State state, Object* Store(Handle<Object> object,
Handle<Object> object,
Handle<Object> name, Handle<Object> name,
Handle<Object> value); Handle<Object> value);
...@@ -335,7 +334,6 @@ class KeyedStoreIC: public IC { ...@@ -335,7 +334,6 @@ class KeyedStoreIC: public IC {
// Update the inline cache. // Update the inline cache.
void UpdateCaches(LookupResult* lookup, void UpdateCaches(LookupResult* lookup,
State state,
Handle<JSObject> receiver, Handle<JSObject> receiver,
Handle<String> name, Handle<String> name,
Handle<Object> value); Handle<Object> value);
......
...@@ -2109,6 +2109,20 @@ void Map::ClearCodeCache() { ...@@ -2109,6 +2109,20 @@ void Map::ClearCodeCache() {
} }
Object* Map::FindInCodeCache(String* name, Code::Flags flags) {
int index;
return FindIndexInCodeCache(name, flags, &index);
}
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
}
#undef CAST_ACCESSOR #undef CAST_ACCESSOR
#undef INT_ACCESSORS #undef INT_ACCESSORS
#undef SMI_ACCESSORS #undef SMI_ACCESSORS
......
...@@ -2410,41 +2410,27 @@ Object* Map::UpdateCodeCache(String* name, Code* code) { ...@@ -2410,41 +2410,27 @@ Object* Map::UpdateCodeCache(String* name, Code* code) {
} }
Object* Map::FindInCodeCache(String* name, Code::Flags flags) { Object* Map::FindIndexInCodeCache(String* name, Code::Flags flags, int* index) {
FixedArray* cache = code_cache(); FixedArray* cache = code_cache();
int length = cache->length(); int length = cache->length();
for (int i = 0; i < length; i += 2) { for (int i = 0; i < length; i += 2) {
Object* key = cache->get(i); Object* key = cache->get(i);
if (key->IsUndefined()) { if (key->IsUndefined()) {
return key; continue;
} }
if (name->Equals(String::cast(key))) { if (name->Equals(String::cast(key))) {
Code* code = Code::cast(cache->get(i + 1)); Code* code = Code::cast(cache->get(i + 1));
if (code->flags() == flags) return code; if (code->flags() == flags) {
*index = i + 1;
return code;
}
} }
} }
*index = -1;
return Heap::undefined_value(); return Heap::undefined_value();
} }
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 i + 1;
}
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
}
void FixedArray::FixedArrayIterateBody(ObjectVisitor* v) { void FixedArray::FixedArrayIterateBody(ObjectVisitor* v) {
IteratePointers(v, kHeaderSize, kHeaderSize + length() * kPointerSize); IteratePointers(v, kHeaderSize, kHeaderSize + length() * kPointerSize);
} }
......
...@@ -2342,14 +2342,14 @@ class Map: public HeapObject { ...@@ -2342,14 +2342,14 @@ class Map: public HeapObject {
Object* UpdateCodeCache(String* name, Code* code); Object* UpdateCodeCache(String* name, Code* code);
// Returns the found code or undefined if absent. // Returns the found code or undefined if absent.
Object* FindInCodeCache(String* name, Code::Flags flags); inline Object* FindInCodeCache(String* name, Code::Flags flags);
// Returns the non-negative index of the code object if it is in the // Returns the found code or undefined if absent. Also returns the
// cache and -1 otherwise. // index at which the code was found or -1 if absent.
int IndexInCodeCache(Code* code); Object* FindIndexInCodeCache(String* name, Code::Flags flags, int* index);
// Removes a code object from the code cache at the given index. // Removes a code object from the code cache at the given index.
void RemoveFromCodeCache(int index); inline void RemoveFromCodeCache(int index);
// Dispatched behavior. // Dispatched behavior.
void MapIterateBody(ObjectVisitor* v); void MapIterateBody(ObjectVisitor* v);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment