Reviewers: danno,
Description:
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]
Please review this at https://chromiumcodereview.appspot.com/10781011/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/ic.cc
M test/cctest/test-api.cc
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
a6b7a1df8c7a3a98535cb835ebf91cda33c5e912..69a3f2a65f2e9a459a01c33f9fac488c9151c4f6
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -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);
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
229607266004673f87054898df272440f22105f0..136832c7cbdf939e477d4d8ab7d26e7914efc838
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -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());
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev