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
This commit is contained in:
fschneider@chromium.org 2012-01-17 16:06:03 +00:00
parent fb24808c70
commit 01979c70a8
2 changed files with 57 additions and 11 deletions

View File

@ -725,6 +725,10 @@ void CaseClause::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
bool Call::ComputeTarget(Handle<Map> type, Handle<String> 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

View File

@ -8912,17 +8912,6 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) {
}
static v8::Handle<Value> call_ic_function5;
static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name))
return call_ic_function5;
else
return Local<Value>();
}
// 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<Value> call_ic_function5;
static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name))
return call_ic_function5;
else
return Local<Value>();
}
// 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<Value> call_ic_function6;
static v8::Handle<Value> InterceptorCallICGetter6(Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name))
return call_ic_function6;
else
return Local<Value>();
}
// 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<v8::ObjectTemplate> 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> 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) {