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

Unified Diff: src/ic.cc

Issue 2801018: This change allows generating call-stubs for objects with normal (non-fast) o... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
===================================================================
--- src/ic.cc (revision 5007)
+++ src/ic.cc (working copy)
@@ -134,14 +134,46 @@
}
#endif
+
+static bool HasNormalObjectsInPrototypeChain(LookupResult* lookup,
+ Object* receiver) {
+ Object* end = lookup->IsProperty() ? lookup->holder() : Heap::null_value();
+ for (Object* current = receiver;
+ current != end;
+ current = current->GetPrototype()) {
+ if (current->IsJSObject() &&
+ !JSObject::cast(current)->HasFastProperties() &&
+ !current->IsJSGlobalProxy() &&
+ !current->IsJSGlobalObject()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
IC::State IC::StateFrom(Code* target, Object* receiver, Object* name) {
IC::State state = target->ic_state();
if (state != MONOMORPHIC) return state;
if (receiver->IsUndefined() || receiver->IsNull()) return state;
- Map* map = GetCodeCacheMapForObject(receiver);
+ InlineCacheHolderFlag cache_holder =
+ Code::ExtractCacheHolderFromFlags(target->flags());
+
+ if (cache_holder == OWN_MAP && !receiver->IsJSObject()) {
+ // The stub was generated for JSObject but called for non-JSObject.
+ // IC::GetCodeCacheMap is not applicable.
+ return MONOMORPHIC;
+ } else if (cache_holder == PROTOTYPE_MAP &&
+ receiver->GetPrototype()->IsNull()) {
+ // IC::GetCodeCacheMap is not applicable.
+ return MONOMORPHIC;
+ }
+ Map* map = IC::GetCodeCacheMap(receiver, cache_holder);
+
// Decide whether the inline cache failed because of changes to the
// receiver itself or changes to one of its prototypes.
//
@@ -487,12 +519,24 @@
void CallICBase::UpdateCaches(LookupResult* lookup,
- State state,
- Handle<Object> object,
- Handle<String> name) {
+ State state,
+ Handle<Object> object,
+ Handle<String> name) {
// Bail out if we didn't find a result.
if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
+#ifndef V8_TARGET_ARCH_IA32
+ // Normal objects only implemented for IA32 by now.
+ if (HasNormalObjectsInPrototypeChain(lookup, *object)) return;
+#else
+ if (lookup->holder() != *object &&
+ HasNormalObjectsInPrototypeChain(lookup, object->GetPrototype())) {
+ // Suppress optimization for prototype chains with slow properties objects
+ // in the middle.
+ return;
+ }
+#endif
+
// Compute the number of arguments.
int argc = target()->arguments_count();
InLoopFlag in_loop = target()->ic_in_loop();
@@ -590,8 +634,13 @@
state == MONOMORPHIC_PROTOTYPE_FAILURE) {
set_target(Code::cast(code));
} else if (state == MEGAMORPHIC) {
+ // Cache code holding map should be consistent with
+ // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
+ Map* map = JSObject::cast(object->IsJSObject() ? *object :
+ object->GetPrototype())->map();
+
// Update the stub cache.
- StubCache::Set(*name, GetCodeCacheMapForObject(*object), Code::cast(code));
+ StubCache::Set(*name, map, Code::cast(code));
}
#ifdef DEBUG
@@ -795,6 +844,8 @@
if (!object->IsJSObject()) return;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (HasNormalObjectsInPrototypeChain(lookup, *object)) return;
+
// Compute the code stub for this load.
Object* code = NULL;
if (state == UNINITIALIZED) {
@@ -871,8 +922,12 @@
} else if (state == MONOMORPHIC) {
set_target(megamorphic_stub());
} else if (state == MEGAMORPHIC) {
- // Update the stub cache.
- StubCache::Set(*name, GetCodeCacheMapForObject(*object), Code::cast(code));
+ // Cache code holding map should be consistent with
+ // GenerateMonomorphicCacheProbe.
+ Map* map = JSObject::cast(object->IsJSObject() ? *object :
+ object->GetPrototype())->map();
+
+ StubCache::Set(*name, map, Code::cast(code));
}
#ifdef DEBUG
@@ -1018,6 +1073,8 @@
if (!object->IsJSObject()) return;
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
+ if (HasNormalObjectsInPrototypeChain(lookup, *object)) return;
+
// Compute the code stub for this load.
Object* code = NULL;
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698