Fix miss in smi check when doing fast api call.
BUG=http://crbug.com/36604 Review URL: http://codereview.chromium.org/660004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3942 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3d76502914
commit
e76f06a1e2
@ -1223,7 +1223,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
|
||||
// -- ...
|
||||
// -- esp[(argc + 1) * 4] : receiver
|
||||
// -----------------------------------
|
||||
Label miss;
|
||||
Label miss_in_smi_check;
|
||||
|
||||
// Get the receiver from the stack.
|
||||
const int argc = arguments().immediate();
|
||||
@ -1232,7 +1232,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
|
||||
// Check that the receiver isn't a smi.
|
||||
if (check != NUMBER_CHECK) {
|
||||
__ test(edx, Immediate(kSmiTagMask));
|
||||
__ j(zero, &miss, not_taken);
|
||||
__ j(zero, &miss_in_smi_check, not_taken);
|
||||
}
|
||||
|
||||
// Make sure that it's okay not to patch the on stack receiver
|
||||
@ -1241,6 +1241,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
|
||||
|
||||
CallOptimization optimization(function);
|
||||
int depth = kInvalidProtoDepth;
|
||||
Label miss;
|
||||
|
||||
switch (check) {
|
||||
case RECEIVER_MAP_CHECK:
|
||||
@ -1359,6 +1360,7 @@ Object* CallStubCompiler::CompileCallConstant(Object* object,
|
||||
if (depth != kInvalidProtoDepth) {
|
||||
FreeSpaceForFastApiCall(masm(), eax);
|
||||
}
|
||||
__ bind(&miss_in_smi_check);
|
||||
Handle<Code> ic = ComputeCallMiss(arguments().immediate());
|
||||
__ jmp(ic, RelocInfo::CODE_TARGET);
|
||||
|
||||
|
@ -6433,6 +6433,45 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
|
||||
CHECK_GE(interceptor_call_count, 50);
|
||||
}
|
||||
|
||||
THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
|
||||
int interceptor_call_count = 0;
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
|
||||
v8::Handle<v8::FunctionTemplate> method_templ =
|
||||
v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
|
||||
v8_str("method_data"),
|
||||
v8::Signature::New(fun_templ));
|
||||
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
|
||||
proto_templ->Set(v8_str("method"), method_templ);
|
||||
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
|
||||
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
|
||||
NULL, NULL, NULL, NULL,
|
||||
v8::External::Wrap(&interceptor_call_count));
|
||||
LocalContext context;
|
||||
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
|
||||
GenerateSomeGarbage();
|
||||
context->Global()->Set(v8_str("o"), fun->NewInstance());
|
||||
v8::TryCatch try_catch;
|
||||
v8::Handle<Value> value = CompileRun(
|
||||
"o.foo = 17;"
|
||||
"var receiver = {};"
|
||||
"receiver.__proto__ = o;"
|
||||
"var result = 0;"
|
||||
"var saved_result = 0;"
|
||||
"for (var i = 0; i < 100; i++) {"
|
||||
" result = receiver.method(41);"
|
||||
" if (i == 50) {"
|
||||
" saved_result = result;"
|
||||
" receiver = 333;"
|
||||
" }"
|
||||
"}");
|
||||
CHECK(try_catch.HasCaught());
|
||||
CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
|
||||
try_catch.Exception()->ToString());
|
||||
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
|
||||
CHECK_GE(interceptor_call_count, 50);
|
||||
}
|
||||
|
||||
THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
|
||||
int interceptor_call_count = 0;
|
||||
v8::HandleScope scope;
|
||||
@ -6521,7 +6560,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature) {
|
||||
CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value());
|
||||
}
|
||||
|
||||
THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
|
||||
THREADED_TEST(CallICFastApi_SimpleSignature_Miss1) {
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
|
||||
v8::Handle<v8::FunctionTemplate> method_templ =
|
||||
@ -6552,6 +6591,40 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss) {
|
||||
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
|
||||
}
|
||||
|
||||
THREADED_TEST(CallICFastApi_SimpleSignature_Miss2) {
|
||||
v8::HandleScope scope;
|
||||
v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
|
||||
v8::Handle<v8::FunctionTemplate> method_templ =
|
||||
v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
|
||||
v8_str("method_data"),
|
||||
v8::Signature::New(fun_templ));
|
||||
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
|
||||
proto_templ->Set(v8_str("method"), method_templ);
|
||||
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
|
||||
LocalContext context;
|
||||
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
|
||||
GenerateSomeGarbage();
|
||||
context->Global()->Set(v8_str("o"), fun->NewInstance());
|
||||
v8::TryCatch try_catch;
|
||||
v8::Handle<Value> value = CompileRun(
|
||||
"o.foo = 17;"
|
||||
"var receiver = {};"
|
||||
"receiver.__proto__ = o;"
|
||||
"var result = 0;"
|
||||
"var saved_result = 0;"
|
||||
"for (var i = 0; i < 100; i++) {"
|
||||
" result = receiver.method(41);"
|
||||
" if (i == 50) {"
|
||||
" saved_result = result;"
|
||||
" receiver = 333;"
|
||||
" }"
|
||||
"}");
|
||||
CHECK(try_catch.HasCaught());
|
||||
CHECK_EQ(v8_str("TypeError: Object 333 has no method 'method'"),
|
||||
try_catch.Exception()->ToString());
|
||||
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
|
||||
}
|
||||
|
||||
|
||||
static int interceptor_call_count = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user