Chromium Code Reviews| Index: test/cctest/test-api.cc |
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
| index f71b3258a8a34afba89f1576b45870c3f7e2ddc5..3bc0cc6401310e275e7fa497fdbc57d3047f1781 100644 |
| --- a/test/cctest/test-api.cc |
| +++ b/test/cctest/test-api.cc |
| @@ -5793,6 +5793,257 @@ THREADED_TEST(InterceptorCallICCachedFromGlobal) { |
| CHECK_EQ(239 * 10, value->Int32Value()); |
| } |
| +static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
|
antonm
2010/02/08 12:07:38
I know that's boring, but apparently you didn't co
Vitaly Repeshko
2010/02/09 16:15:24
Thanks, added a test. Yeah, it's boring...
|
| + const AccessorInfo& info) { |
| + ApiTestFuzzer::Fuzz(); |
| + int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
| + ++(*call_count); |
| + if ((*call_count) % 200 == 0) { |
| + v8::internal::Heap::CollectAllGarbage(true); |
| + } |
| + return v8::Handle<Value>(); |
| +} |
| + |
| +static v8::Handle<Value> FastApiCallback_TrivialSignature( |
| + const v8::Arguments& args) { |
| + ApiTestFuzzer::Fuzz(); |
| + CHECK_EQ(args.This(), args.Holder()); |
| + CHECK(args.Data()->Equals(v8_str("method_data"))); |
| + return v8::Integer::New(args[0]->Int32Value() + 1); |
| +} |
| + |
| +static v8::Handle<Value> FastApiCallback_SimpleSignature( |
| + const v8::Arguments& args) { |
| + ApiTestFuzzer::Fuzz(); |
| + CHECK_EQ(args.This()->GetPrototype(), args.Holder()); |
| + CHECK(args.Data()->Equals(v8_str("method_data"))); |
| + // Note, we're using HasRealNamedProperty instead of Has to avoid |
| + // invoking the interceptor again. |
| + CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo"))); |
| + return v8::Integer::New(args[0]->Int32Value() + 1); |
| +} |
| + |
| +static void GenerateSomeGarbage() { |
| + CompileRun( |
| + "var garbage;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" |
| + "}" |
| + "garbage = undefined;"); |
| +} |
| + |
| +THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) { |
| + 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_TrivialSignature, |
| + v8_str("method_data"), |
| + v8::Handle<v8::Signature>()); |
| + 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(); |
|
Mads Ager (chromium)
2010/02/08 08:56:58
Could you document why you generate some extra gar
Vitaly Repeshko
2010/02/09 16:15:24
Done.
|
| + context->Global()->Set(v8_str("o"), fun->NewInstance()); |
| + v8::Handle<Value> value = CompileRun( |
| + "var result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
|
Mads Ager (chromium)
2010/02/08 08:56:58
I think we use 1000 in other places as well, but d
Vitaly Repeshko
2010/02/09 16:15:24
Sure we don't need that many. Reduced iterations b
|
| + " result = o.method(41);" |
| + "}"); |
| + CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
|
antonm
2010/02/08 12:07:38
if you add result as a last line of script, you co
Vitaly Repeshko
2010/02/09 16:15:24
Yup, but I prefer a slightly more uniform way here
|
| + CHECK_EQ(1000, interceptor_call_count); |
| +} |
| + |
| +THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) { |
| + 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::Handle<Value> value = CompileRun( |
| + "o.foo = 17;" |
| + "var receiver = {};" |
| + "receiver.__proto__ = o;" |
| + "var result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " result = receiver.method(41);" |
| + "}"); |
| + CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
| + CHECK_EQ(1000, interceptor_call_count); |
| +} |
| + |
| +THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss) { |
| + 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::Handle<Value> value = CompileRun( |
| + "o.foo = 17;" |
| + "var receiver = {};" |
| + "receiver.__proto__ = o;" |
| + "var result = 0;" |
| + "var saved_result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " result = receiver.method(41);" |
| + " if (i == 500) {" |
| + " saved_result = result;" |
| + " receiver = {method: function(x) { return x - 1 }};" |
| + " }" |
| + "}"); |
| + CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); |
| + CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
| + CHECK(interceptor_call_count >= 500); |
| +} |
| + |
| +THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { |
| + 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 < 1000; i++) {" |
| + " result = receiver.method(41);" |
| + " if (i == 500) {" |
| + " saved_result = result;" |
| + " receiver = {method: receiver.method};" |
| + " }" |
| + "}"); |
| + CHECK(try_catch.HasCaught()); |
| + CHECK_EQ(v8_str("TypeError: Illegal invocation"), |
| + try_catch.Exception()->ToString()); |
| + CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
| + CHECK(interceptor_call_count >= 500); |
| +} |
| + |
| +THREADED_TEST(CallICFastApi_TrivialSignature) { |
| + v8::HandleScope scope; |
| + v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| + v8::Handle<v8::FunctionTemplate> method_templ = |
| + v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, |
| + v8_str("method_data"), |
| + v8::Handle<v8::Signature>()); |
| + 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::Handle<Value> value = CompileRun( |
| + "var result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " result = o.method(41);" |
| + "}"); |
| + |
| + CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
| +} |
| + |
| +THREADED_TEST(CallICFastApi_SimpleSignature) { |
| + 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::Handle<Value> value = CompileRun( |
| + "o.foo = 17;" |
| + "var receiver = {};" |
| + "receiver.__proto__ = o;" |
| + "var result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " result = receiver.method(41);" |
| + "}"); |
| + |
| + CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); |
| +} |
| + |
| +THREADED_TEST(CallICFastApi_SimpleSignature_Miss) { |
| + 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::Handle<Value> value = CompileRun( |
| + "o.foo = 17;" |
| + "var receiver = {};" |
| + "receiver.__proto__ = o;" |
| + "var result = 0;" |
| + "var saved_result = 0;" |
| + "for (var i = 0; i < 1000; i++) {" |
| + " result = receiver.method(41);" |
| + " if (i == 500) {" |
| + " saved_result = result;" |
| + " receiver = {method: function(x) { return x - 1 }};" |
| + " }" |
| + "}"); |
| + CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); |
| + CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
| +} |
| + |
| static int interceptor_call_count = 0; |