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:
parent
fb24808c70
commit
01979c70a8
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user