Fix ICs for slow objects with native accessor.

This prevents creation of LoadICs or StoreICs for native callbacks on
objects in dictionary mode. Those ICs fail if the accessor is installed
on the receiver itself and also lead to bogus type feedback.

R=danno@chromium.org
BUG=chromium:137002
TEST=test/test-api/Regress137002[a,b]

Review URL: https://chromiumcodereview.appspot.com/10781011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12088 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f17ce0cc
......@@ -989,6 +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 (!info->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeLoadCallback(
name, receiver, holder, info);
......@@ -1265,6 +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 (!callback->IsCompatibleReceiver(*receiver)) return;
code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
name, receiver, holder, callback);
......@@ -1484,6 +1486,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
if (callback->IsAccessorInfo()) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
if (v8::ToCData<Address>(info->setter()) == 0) return;
if (!receiver->HasFastProperties()) return;
ASSERT(info->IsCompatibleReceiver(*receiver));
code = isolate()->stub_cache()->ComputeStoreCallback(
name, receiver, info, strict_mode);
......
......@@ -16813,3 +16813,46 @@ TEST(TryFinallyMessage) {
CHECK_EQ(6, message->GetLineNumber());
}
}
THREADED_TEST(Regress137002a) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope;
LocalContext context;
Local<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetAccessor(v8_str("foo"),
GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// Turn monomorphic on slow object with native accessor, then turn
// polymorphic, finally optimize to create negative lookup and fail.
CompileRun("function f(x) { return x.foo; }"
"%OptimizeObjectForAddingMultipleProperties(obj, 1);"
"obj.__proto__ = null;"
"f(obj); f(obj); f({});"
"%OptimizeFunctionOnNextCall(f);"
"var result = f(obj);");
CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
}
THREADED_TEST(Regress137002b) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope;
LocalContext context;
Local<ObjectTemplate> templ = ObjectTemplate::New();
templ->SetAccessor(v8_str("foo"),
GetterWhichReturns42,
SetterWhichSetsYOnThisTo23);
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// 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);"
"obj.__proto__ = null;"
"f(obj); f(obj); delete obj.foo;"
"var result = f(obj);");
CHECK(context->Global()->Get(v8_str("result"))->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