From: fschneider@chromium.org Date: Tue, 17 Jan 2012 16:06:03 +0000 (+0000) Subject: Fix handling of named interceptors in optimized code. X-Git-Tag: upstream/4.7.83~17593 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=01979c70a8b160f0065a946797123c453d87e114;p=platform%2Fupstream%2Fv8.git Fix handling of named interceptors in optimized code. When calling a constant function property from optimized code, we need to check that there is no interceptor on the receiver map. TEST=cctest/InterceptorCallICConstantFunctionNotNeededWrapped Review URL: http://codereview.chromium.org/9240006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10425 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ast.cc b/src/ast.cc index ab37053..7c5e3a7 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -725,6 +725,10 @@ void CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) { bool Call::ComputeTarget(Handle type, Handle name) { + // If there is an interceptor, we can't compute the target for + // a direct call. + if (type->has_named_interceptor()) return false; + if (check_type_ == RECEIVER_MAP_CHECK) { // For primitive checks the holder is set up to point to the // corresponding prototype object, i.e. one step of the algorithm diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index cff9a27..8525f38 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -8912,17 +8912,6 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) { } -static v8::Handle call_ic_function5; -static v8::Handle InterceptorCallICGetter5(Local name, - const AccessorInfo& info) { - ApiTestFuzzer::Fuzz(); - if (v8_str("x")->Equals(name)) - return call_ic_function5; - else - return Local(); -} - - // This test checks that if interceptor doesn't provide a function, // cached constant function is used THREADED_TEST(InterceptorCallICConstantFunctionUsed) { @@ -8943,6 +8932,17 @@ THREADED_TEST(InterceptorCallICConstantFunctionUsed) { } +static v8::Handle call_ic_function5; +static v8::Handle InterceptorCallICGetter5(Local name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + if (v8_str("x")->Equals(name)) + return call_ic_function5; + else + return Local(); +} + + // This test checks that if interceptor provides a function, // even if we cached constant function, interceptor's function // is invoked @@ -8966,6 +8966,48 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { } +static v8::Handle call_ic_function6; +static v8::Handle InterceptorCallICGetter6(Local name, + const AccessorInfo& info) { + ApiTestFuzzer::Fuzz(); + if (v8_str("x")->Equals(name)) + return call_ic_function6; + else + return Local(); +} + + +// Same test as above, except the code is wrapped in a function +// to test the optimized compiler. +THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { + i::FLAG_allow_natives_syntax = true; + v8::HandleScope scope; + v8::Handle templ = ObjectTemplate::New(); + templ->SetNamedPropertyHandler(InterceptorCallICGetter6); + LocalContext context; + context->Global()->Set(v8_str("o"), templ->NewInstance()); + call_ic_function6 = + v8_compile("function f(x) { return x - 1; }; f")->Run(); + v8::Handle value = CompileRun( + "function inc(x) { return x + 1; };" + "inc(1);" + "o.x = inc;" + "function test() {" + " var result = 0;" + " for (var i = 0; i < 1000; i++) {" + " result = o.x(42);" + " }" + " return result;" + "};" + "test();" + "test();" + "test();" + "%OptimizeFunctionOnNextCall(test);" + "test()"); + CHECK_EQ(41, value->Int32Value()); +} + + // Test the case when we stored constant function into // a stub, but it got invalidated later on THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) {