Revision: 12088 Author: [email protected] Date: Mon Jul 16 02:53:32 2012 Log: 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. [email protected] BUG=chromium:137002 TEST=test/test-api/Regress137002[a,b] Review URL: https://chromiumcodereview.appspot.com/10781011 http://code.google.com/p/v8/source/detail?r=12088 Modified: /branches/bleeding_edge/src/ic.cc /branches/bleeding_edge/test/cctest/test-api.cc ======================================= --- /branches/bleeding_edge/src/ic.cc Fri Jul 13 02:37:03 2012 +++ /branches/bleeding_edge/src/ic.cc Mon Jul 16 02:53:32 2012 @@ -989,6 +989,7 @@ 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 @@ 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 @@ 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); ======================================= --- /branches/bleeding_edge/test/cctest/test-api.cc Fri Jul 13 09:33:27 2012 +++ /branches/bleeding_edge/test/cctest/test-api.cc Mon Jul 16 02:53:32 2012 @@ -16813,3 +16813,46 @@ 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()); +} -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
