Commit 5c6db6d0 authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Fix the 137002 fix (Don't generate ICs for accessors on slow

case objects).  We should be testing the holder for dictionary
mode, not the receiver.
Review URL: https://chromiumcodereview.appspot.com/10827113

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12247 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d4e6aa33
......@@ -989,7 +989,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
if (callback->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->getter()) == 0) return;
if (!receiver->HasFastProperties()) return;
if (!holder->HasFastProperties()) return;
if (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info);
......@@ -997,7 +997,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
if (!getter->IsJSFunction()) return;
if (holder->IsGlobalObject()) return;
if (!receiver->HasFastProperties()) return;
if (!holder->HasFastProperties()) return;
code = isolate()->stub_cache()->ComputeLoadViaGetter(
name, receiver, holder, Handle<JSFunction>::cast(getter));
} else {
......@@ -1266,7 +1266,7 @@ void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
Handle<AccessorInfo> callback =
Handle<AccessorInfo>::cast(callback_object);
if (v8::ToCData<Address>(callback->getter()) == 0) return;
if (!receiver->HasFastProperties()) return;
if (!holder->HasFastProperties()) return;
if (!callback->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
name, receiver, holder, callback);
......@@ -1325,7 +1325,9 @@ static bool LookupForWrite(Handle<JSObject> receiver,
// that we explicitly exclude native accessors for now, because the stubs
// are not yet prepared for this scenario.
receiver->Lookup(*name, lookup);
if (!lookup->IsPropertyCallbacks()) return false;
if (!lookup->IsPropertyCallbacks()) {
return false;
}
Handle<Object> callback(lookup->GetCallbackObject());
return callback->IsAccessorPair() && StoreICableLookup(lookup);
}
......@@ -1487,9 +1489,10 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
case CALLBACKS: {
Handle<Object> callback(lookup->GetCallbackObject());
if (callback->IsAccessorInfo()) {
ASSERT(*holder == *receiver); // LookupForWrite checks this.
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->setter()) == 0) return;
if (!receiver->HasFastProperties()) return;
if (!holder->HasFastProperties()) return;
ASSERT(info->IsCompatibleReceiver(*receiver));
code = isolate()->stub_cache()->ComputeStoreCallback(
name, receiver, info, strict_mode);
......@@ -1497,7 +1500,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
if (!setter->IsJSFunction()) return;
if (holder->IsGlobalObject()) return;
if (!receiver->HasFastProperties()) return;
if (!holder->HasFastProperties()) return;
code = isolate()->stub_cache()->ComputeStoreViaSetter(
name, receiver, holder, Handle<JSFunction>::cast(setter),
strict_mode);
......
......@@ -17003,12 +17003,48 @@ THREADED_TEST(Regress137002b) {
// Turn monomorphic on slow object with native accessor, then just
// delete the property and fail.
CompileRun("function f(x) { return x.foo; }"
"%OptimizeObjectForAddingMultipleProperties(obj, 1);"
CompileRun("function load(x) { return x.foo; }"
"function store(x) { x.foo = void 0; }"
"function keyed_load(x, key) { return x[key]; }"
// Second version of function has a different source (add void 0)
// so that it does not share code with the first version. This
// ensures that the ICs are monomorphic.
"function load2(x) { void 0; return x.foo; }"
"function store2(x) { void 0; x.foo = void 0; }"
"function keyed_load2(x, key) { void 0; return x[key]; }"
"obj.__proto__ = null;"
"f(obj); f(obj); delete obj.foo;"
"var result = f(obj);");
CHECK(context->Global()->Get(v8_str("result"))->IsUndefined());
"var subobj = {};"
"subobj.__proto__ = obj;"
"%OptimizeObjectForAddingMultipleProperties(obj, 1);"
// Make the ICs monomorphic.
"load(obj); load(obj);"
"load2(subobj); load2(subobj);"
"store(obj);"
"store2(subobj);"
"keyed_load(obj, 'foo'); keyed_load(obj, 'foo');"
"keyed_load2(subobj, 'foo'); keyed_load2(subobj, 'foo');"
// Delete the accessor. It better not be called any more now.
"delete obj.foo;"
"obj.y = void 0;"
"subobj.y = void 0;"
"var load_result = load(obj);"
"var load_result2 = load2(subobj);"
"var keyed_load_result = keyed_load(obj, 'foo');"
"var keyed_load_result2 = keyed_load2(subobj, 'foo');"
"store(obj);"
"store2(subobj);"
"var y_from_obj = obj.y;"
"var y_from_subobj = subobj.y;");
CHECK(context->Global()->Get(v8_str("load_result"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("load_result2"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("keyed_load_result"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("keyed_load_result2"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("y_from_obj"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("y_from_subobj"))->IsUndefined());
}
......
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