| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 21818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21829 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); | 21829 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); |
| 21830 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), | 21830 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), |
| 21831 v8::Utils::OpenHandle(*name), | 21831 v8::Utils::OpenHandle(*name), |
| 21832 getter_i, | 21832 getter_i, |
| 21833 setter_i, | 21833 setter_i, |
| 21834 static_cast<PropertyAttributes>(attribute), | 21834 static_cast<PropertyAttributes>(attribute), |
| 21835 settings); | 21835 settings); |
| 21836 } | 21836 } |
| 21837 | 21837 |
| 21838 public: | 21838 public: |
| 21839 void Run(bool use_signature, bool global) { | 21839 enum SignatureType { |
| 21840 kNoSignature, |
| 21841 kSignatureOnReceiver, |
| 21842 kSignatureOnPrototype |
| 21843 }; |
| 21844 |
| 21845 void RunAll() { |
| 21846 SignatureType signature_types[] = |
| 21847 {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype}; |
| 21848 for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) { |
| 21849 SignatureType signature_type = signature_types[i]; |
| 21850 for (int j = 0; j < 2; j++) { |
| 21851 bool global = j == 0; |
| 21852 int key = signature_type + |
| 21853 ARRAY_SIZE(signature_types) * (global ? 1 : 0); |
| 21854 Run(signature_type, global, key); |
| 21855 } |
| 21856 } |
| 21857 } |
| 21858 |
| 21859 void Run(SignatureType signature_type, bool global, int key) { |
| 21840 v8::Isolate* isolate = CcTest::isolate(); | 21860 v8::Isolate* isolate = CcTest::isolate(); |
| 21841 v8::HandleScope scope(isolate); | 21861 v8::HandleScope scope(isolate); |
| 21842 // Build a template for signature checks. | 21862 // Build a template for signature checks. |
| 21843 Local<v8::ObjectTemplate> signature_template; | 21863 Local<v8::ObjectTemplate> signature_template; |
| 21844 Local<v8::Signature> signature; | 21864 Local<v8::Signature> signature; |
| 21845 { | 21865 { |
| 21846 Local<v8::FunctionTemplate> parent_template = | 21866 Local<v8::FunctionTemplate> parent_template = |
| 21847 FunctionTemplate::New(isolate); | 21867 FunctionTemplate::New(isolate); |
| 21848 parent_template->SetHiddenPrototype(true); | 21868 parent_template->SetHiddenPrototype(true); |
| 21849 Local<v8::FunctionTemplate> function_template | 21869 Local<v8::FunctionTemplate> function_template |
| 21850 = FunctionTemplate::New(isolate); | 21870 = FunctionTemplate::New(isolate); |
| 21851 function_template->Inherit(parent_template); | 21871 function_template->Inherit(parent_template); |
| 21852 if (use_signature) { | 21872 switch (signature_type) { |
| 21853 signature = v8::Signature::New(isolate, parent_template); | 21873 case kNoSignature: |
| 21874 break; |
| 21875 case kSignatureOnReceiver: |
| 21876 signature = v8::Signature::New(isolate, function_template); |
| 21877 break; |
| 21878 case kSignatureOnPrototype: |
| 21879 signature = v8::Signature::New(isolate, parent_template); |
| 21880 break; |
| 21854 } | 21881 } |
| 21855 signature_template = function_template->InstanceTemplate(); | 21882 signature_template = function_template->InstanceTemplate(); |
| 21856 } | 21883 } |
| 21857 // Global object must pass checks. | 21884 // Global object must pass checks. |
| 21858 Local<v8::Context> context = | 21885 Local<v8::Context> context = |
| 21859 v8::Context::New(isolate, NULL, signature_template); | 21886 v8::Context::New(isolate, NULL, signature_template); |
| 21860 v8::Context::Scope context_scope(context); | 21887 v8::Context::Scope context_scope(context); |
| 21861 // Install regular object that can pass signature checks. | 21888 // Install regular object that can pass signature checks. |
| 21862 Local<Object> function_receiver = signature_template->NewInstance(); | 21889 Local<Object> function_receiver = signature_template->NewInstance(); |
| 21863 context->Global()->Set(v8_str("function_receiver"), function_receiver); | 21890 context->Global()->Set(v8_str("function_receiver"), function_receiver); |
| 21864 // Get the holder objects. | 21891 // Get the holder objects. |
| 21865 Local<Object> inner_global = | 21892 Local<Object> inner_global = |
| 21866 Local<Object>::Cast(context->Global()->GetPrototype()); | 21893 Local<Object>::Cast(context->Global()->GetPrototype()); |
| 21867 Local<Object> function_holder = | 21894 // Install functions on hidden prototype object if there is one. |
| 21868 Local<Object>::Cast(function_receiver->GetPrototype()); | |
| 21869 // Install function on hidden prototype object. | |
| 21870 data = Object::New(isolate); | 21895 data = Object::New(isolate); |
| 21871 Local<FunctionTemplate> function_template = FunctionTemplate::New( | 21896 Local<FunctionTemplate> function_template = FunctionTemplate::New( |
| 21872 isolate, OptimizationCallback, data, signature); | 21897 isolate, OptimizationCallback, data, signature); |
| 21873 Local<Function> function = function_template->GetFunction(); | 21898 Local<Function> function = function_template->GetFunction(); |
| 21874 Local<Object> global_holder = Local<Object>::Cast( | 21899 Local<Object> global_holder = inner_global; |
| 21875 inner_global->GetPrototype()); | 21900 Local<Object> function_holder = function_receiver; |
| 21901 if (signature_type == kSignatureOnPrototype) { |
| 21902 function_holder = Local<Object>::Cast(function_holder->GetPrototype()); |
| 21903 global_holder = Local<Object>::Cast(global_holder->GetPrototype()); |
| 21904 } |
| 21876 global_holder->Set(v8_str("g_f"), function); | 21905 global_holder->Set(v8_str("g_f"), function); |
| 21877 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); | 21906 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); |
| 21878 function_holder->Set(v8_str("f"), function); | 21907 function_holder->Set(v8_str("f"), function); |
| 21879 SetAccessorProperty(function_holder, v8_str("acc"), function, function); | 21908 SetAccessorProperty(function_holder, v8_str("acc"), function, function); |
| 21880 // Initialize expected values. | 21909 // Initialize expected values. |
| 21881 callee = function; | 21910 callee = function; |
| 21882 count = 0; | 21911 count = 0; |
| 21883 if (global) { | 21912 if (global) { |
| 21884 receiver = context->Global(); | 21913 receiver = context->Global(); |
| 21885 holder = inner_global; | 21914 holder = inner_global; |
| 21886 } else { | 21915 } else { |
| 21887 holder = function_receiver; | 21916 holder = function_receiver; |
| 21888 // If not using a signature, add something else to the prototype chain | 21917 // If not using a signature, add something else to the prototype chain |
| 21889 // to test the case that holder != receiver | 21918 // to test the case that holder != receiver |
| 21890 if (!use_signature) { | 21919 if (signature_type == kNoSignature) { |
| 21891 receiver = Local<Object>::Cast(CompileRun( | 21920 receiver = Local<Object>::Cast(CompileRun( |
| 21892 "var receiver_subclass = {};\n" | 21921 "var receiver_subclass = {};\n" |
| 21893 "receiver_subclass.__proto__ = function_receiver;\n" | 21922 "receiver_subclass.__proto__ = function_receiver;\n" |
| 21894 "receiver_subclass")); | 21923 "receiver_subclass")); |
| 21895 } else { | 21924 } else { |
| 21896 receiver = Local<Object>::Cast(CompileRun( | 21925 receiver = Local<Object>::Cast(CompileRun( |
| 21897 "var receiver_subclass = function_receiver;\n" | 21926 "var receiver_subclass = function_receiver;\n" |
| 21898 "receiver_subclass")); | 21927 "receiver_subclass")); |
| 21899 } | 21928 } |
| 21900 } | 21929 } |
| 21901 // With no signature, the holder is not set. | 21930 // With no signature, the holder is not set. |
| 21902 if (!use_signature) holder = receiver; | 21931 if (signature_type == kNoSignature) holder = receiver; |
| 21903 // build wrap_function | 21932 // build wrap_function |
| 21904 int key = (use_signature ? 1 : 0) + 2 * (global ? 1 : 0); | |
| 21905 i::ScopedVector<char> wrap_function(200); | 21933 i::ScopedVector<char> wrap_function(200); |
| 21906 if (global) { | 21934 if (global) { |
| 21907 i::OS::SNPrintF( | 21935 i::OS::SNPrintF( |
| 21908 wrap_function, | 21936 wrap_function, |
| 21909 "function wrap_f_%d() { var f = g_f; return f(); }\n" | 21937 "function wrap_f_%d() { var f = g_f; return f(); }\n" |
| 21910 "function wrap_get_%d() { return this.g_acc; }\n" | 21938 "function wrap_get_%d() { return this.g_acc; }\n" |
| 21911 "function wrap_set_%d() { this.g_acc = 1; }\n", | 21939 "function wrap_set_%d() { this.g_acc = 1; }\n", |
| 21912 key, key, key); | 21940 key, key, key); |
| 21913 } else { | 21941 } else { |
| 21914 i::OS::SNPrintF( | 21942 i::OS::SNPrintF( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21953 Local<Object> ApiCallOptimizationChecker::data; | 21981 Local<Object> ApiCallOptimizationChecker::data; |
| 21954 Local<Object> ApiCallOptimizationChecker::receiver; | 21982 Local<Object> ApiCallOptimizationChecker::receiver; |
| 21955 Local<Object> ApiCallOptimizationChecker::holder; | 21983 Local<Object> ApiCallOptimizationChecker::holder; |
| 21956 Local<Object> ApiCallOptimizationChecker::callee; | 21984 Local<Object> ApiCallOptimizationChecker::callee; |
| 21957 int ApiCallOptimizationChecker::count = 0; | 21985 int ApiCallOptimizationChecker::count = 0; |
| 21958 | 21986 |
| 21959 | 21987 |
| 21960 TEST(TestFunctionCallOptimization) { | 21988 TEST(TestFunctionCallOptimization) { |
| 21961 i::FLAG_allow_natives_syntax = true; | 21989 i::FLAG_allow_natives_syntax = true; |
| 21962 ApiCallOptimizationChecker checker; | 21990 ApiCallOptimizationChecker checker; |
| 21963 checker.Run(true, true); | 21991 checker.RunAll(); |
| 21964 checker.Run(false, true); | |
| 21965 checker.Run(true, false); | |
| 21966 checker.Run(false, false); | |
| 21967 } | 21992 } |
| OLD | NEW |