Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1373)

Unified Diff: test/cctest/test-api.cc

Issue 573003: ia32: Fuse map and type checks in call ICs for API functions. (Closed)
Patch Set: Rewrote a comment. Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/stub-cache.h ('K') | « src/x64/stub-cache-x64.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« src/stub-cache.h ('K') | « src/x64/stub-cache-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698