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 21921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
21932 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); | 21932 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); |
21933 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), | 21933 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), |
21934 v8::Utils::OpenHandle(*name), | 21934 v8::Utils::OpenHandle(*name), |
21935 getter_i, | 21935 getter_i, |
21936 setter_i, | 21936 setter_i, |
21937 static_cast<PropertyAttributes>(attribute), | 21937 static_cast<PropertyAttributes>(attribute), |
21938 settings); | 21938 settings); |
21939 } | 21939 } |
21940 | 21940 |
21941 public: | 21941 public: |
21942 void Run(bool use_signature, bool global) { | 21942 enum SignatureType { |
| 21943 kNoSignature, |
| 21944 kSignatureOnReceiver, |
| 21945 kSignatureOnPrototype |
| 21946 }; |
| 21947 |
| 21948 void RunAll() { |
| 21949 SignatureType signature_types[] = |
| 21950 {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype}; |
| 21951 for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) { |
| 21952 SignatureType signature_type = signature_types[i]; |
| 21953 for (int j = 0; j < 2; j++) { |
| 21954 bool global = j == 0; |
| 21955 int key = signature_type + |
| 21956 ARRAY_SIZE(signature_types) * (global ? 1 : 0); |
| 21957 Run(signature_type, global, key); |
| 21958 } |
| 21959 } |
| 21960 } |
| 21961 |
| 21962 void Run(SignatureType signature_type, bool global, int key) { |
21943 v8::Isolate* isolate = CcTest::isolate(); | 21963 v8::Isolate* isolate = CcTest::isolate(); |
21944 v8::HandleScope scope(isolate); | 21964 v8::HandleScope scope(isolate); |
21945 // Build a template for signature checks. | 21965 // Build a template for signature checks. |
21946 Local<v8::ObjectTemplate> signature_template; | 21966 Local<v8::ObjectTemplate> signature_template; |
21947 Local<v8::Signature> signature; | 21967 Local<v8::Signature> signature; |
21948 { | 21968 { |
21949 Local<v8::FunctionTemplate> parent_template = | 21969 Local<v8::FunctionTemplate> parent_template = |
21950 FunctionTemplate::New(isolate); | 21970 FunctionTemplate::New(isolate); |
21951 parent_template->SetHiddenPrototype(true); | 21971 parent_template->SetHiddenPrototype(true); |
21952 Local<v8::FunctionTemplate> function_template | 21972 Local<v8::FunctionTemplate> function_template |
21953 = FunctionTemplate::New(isolate); | 21973 = FunctionTemplate::New(isolate); |
21954 function_template->Inherit(parent_template); | 21974 function_template->Inherit(parent_template); |
21955 if (use_signature) { | 21975 switch (signature_type) { |
21956 signature = v8::Signature::New(isolate, parent_template); | 21976 case kNoSignature: |
| 21977 break; |
| 21978 case kSignatureOnReceiver: |
| 21979 signature = v8::Signature::New(isolate, function_template); |
| 21980 break; |
| 21981 case kSignatureOnPrototype: |
| 21982 signature = v8::Signature::New(isolate, parent_template); |
| 21983 break; |
21957 } | 21984 } |
21958 signature_template = function_template->InstanceTemplate(); | 21985 signature_template = function_template->InstanceTemplate(); |
21959 } | 21986 } |
21960 // Global object must pass checks. | 21987 // Global object must pass checks. |
21961 Local<v8::Context> context = | 21988 Local<v8::Context> context = |
21962 v8::Context::New(isolate, NULL, signature_template); | 21989 v8::Context::New(isolate, NULL, signature_template); |
21963 v8::Context::Scope context_scope(context); | 21990 v8::Context::Scope context_scope(context); |
21964 // Install regular object that can pass signature checks. | 21991 // Install regular object that can pass signature checks. |
21965 Local<Object> function_receiver = signature_template->NewInstance(); | 21992 Local<Object> function_receiver = signature_template->NewInstance(); |
21966 context->Global()->Set(v8_str("function_receiver"), function_receiver); | 21993 context->Global()->Set(v8_str("function_receiver"), function_receiver); |
21967 // Get the holder objects. | 21994 // Get the holder objects. |
21968 Local<Object> inner_global = | 21995 Local<Object> inner_global = |
21969 Local<Object>::Cast(context->Global()->GetPrototype()); | 21996 Local<Object>::Cast(context->Global()->GetPrototype()); |
21970 Local<Object> function_holder = | 21997 // Install functions on hidden prototype object if there is one. |
21971 Local<Object>::Cast(function_receiver->GetPrototype()); | |
21972 // Install function on hidden prototype object. | |
21973 data = Object::New(isolate); | 21998 data = Object::New(isolate); |
21974 Local<FunctionTemplate> function_template = FunctionTemplate::New( | 21999 Local<FunctionTemplate> function_template = FunctionTemplate::New( |
21975 isolate, OptimizationCallback, data, signature); | 22000 isolate, OptimizationCallback, data, signature); |
21976 Local<Function> function = function_template->GetFunction(); | 22001 Local<Function> function = function_template->GetFunction(); |
21977 Local<Object> global_holder = Local<Object>::Cast( | 22002 Local<Object> global_holder = inner_global; |
21978 inner_global->GetPrototype()); | 22003 Local<Object> function_holder = function_receiver; |
| 22004 if (signature_type == kSignatureOnPrototype) { |
| 22005 function_holder = Local<Object>::Cast(function_holder->GetPrototype()); |
| 22006 global_holder = Local<Object>::Cast(global_holder->GetPrototype()); |
| 22007 } |
21979 global_holder->Set(v8_str("g_f"), function); | 22008 global_holder->Set(v8_str("g_f"), function); |
21980 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); | 22009 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); |
21981 function_holder->Set(v8_str("f"), function); | 22010 function_holder->Set(v8_str("f"), function); |
21982 SetAccessorProperty(function_holder, v8_str("acc"), function, function); | 22011 SetAccessorProperty(function_holder, v8_str("acc"), function, function); |
21983 // Initialize expected values. | 22012 // Initialize expected values. |
21984 callee = function; | 22013 callee = function; |
21985 count = 0; | 22014 count = 0; |
21986 if (global) { | 22015 if (global) { |
21987 receiver = context->Global(); | 22016 receiver = context->Global(); |
21988 holder = inner_global; | 22017 holder = inner_global; |
21989 } else { | 22018 } else { |
21990 holder = function_receiver; | 22019 holder = function_receiver; |
21991 // If not using a signature, add something else to the prototype chain | 22020 // If not using a signature, add something else to the prototype chain |
21992 // to test the case that holder != receiver | 22021 // to test the case that holder != receiver |
21993 if (!use_signature) { | 22022 if (signature_type == kNoSignature) { |
21994 receiver = Local<Object>::Cast(CompileRun( | 22023 receiver = Local<Object>::Cast(CompileRun( |
21995 "var receiver_subclass = {};\n" | 22024 "var receiver_subclass = {};\n" |
21996 "receiver_subclass.__proto__ = function_receiver;\n" | 22025 "receiver_subclass.__proto__ = function_receiver;\n" |
21997 "receiver_subclass")); | 22026 "receiver_subclass")); |
21998 } else { | 22027 } else { |
21999 receiver = Local<Object>::Cast(CompileRun( | 22028 receiver = Local<Object>::Cast(CompileRun( |
22000 "var receiver_subclass = function_receiver;\n" | 22029 "var receiver_subclass = function_receiver;\n" |
22001 "receiver_subclass")); | 22030 "receiver_subclass")); |
22002 } | 22031 } |
22003 } | 22032 } |
22004 // With no signature, the holder is not set. | 22033 // With no signature, the holder is not set. |
22005 if (!use_signature) holder = receiver; | 22034 if (signature_type == kNoSignature) holder = receiver; |
22006 // build wrap_function | 22035 // build wrap_function |
22007 int key = (use_signature ? 1 : 0) + 2 * (global ? 1 : 0); | |
22008 i::ScopedVector<char> wrap_function(200); | 22036 i::ScopedVector<char> wrap_function(200); |
22009 if (global) { | 22037 if (global) { |
22010 i::OS::SNPrintF( | 22038 i::OS::SNPrintF( |
22011 wrap_function, | 22039 wrap_function, |
22012 "function wrap_f_%d() { var f = g_f; return f(); }\n" | 22040 "function wrap_f_%d() { var f = g_f; return f(); }\n" |
22013 "function wrap_get_%d() { return this.g_acc; }\n" | 22041 "function wrap_get_%d() { return this.g_acc; }\n" |
22014 "function wrap_set_%d() { this.g_acc = 1; }\n", | 22042 "function wrap_set_%d() { this.g_acc = 1; }\n", |
22015 key, key, key); | 22043 key, key, key); |
22016 } else { | 22044 } else { |
22017 i::OS::SNPrintF( | 22045 i::OS::SNPrintF( |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22056 Local<Object> ApiCallOptimizationChecker::data; | 22084 Local<Object> ApiCallOptimizationChecker::data; |
22057 Local<Object> ApiCallOptimizationChecker::receiver; | 22085 Local<Object> ApiCallOptimizationChecker::receiver; |
22058 Local<Object> ApiCallOptimizationChecker::holder; | 22086 Local<Object> ApiCallOptimizationChecker::holder; |
22059 Local<Object> ApiCallOptimizationChecker::callee; | 22087 Local<Object> ApiCallOptimizationChecker::callee; |
22060 int ApiCallOptimizationChecker::count = 0; | 22088 int ApiCallOptimizationChecker::count = 0; |
22061 | 22089 |
22062 | 22090 |
22063 TEST(TestFunctionCallOptimization) { | 22091 TEST(TestFunctionCallOptimization) { |
22064 i::FLAG_allow_natives_syntax = true; | 22092 i::FLAG_allow_natives_syntax = true; |
22065 ApiCallOptimizationChecker checker; | 22093 ApiCallOptimizationChecker checker; |
22066 checker.Run(true, true); | 22094 checker.RunAll(); |
22067 checker.Run(false, true); | |
22068 checker.Run(true, false); | |
22069 checker.Run(false, false); | |
22070 } | 22095 } |
OLD | NEW |