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

Side by Side Diff: src/builtins.cc

Issue 2084923003: Optimize HandleApiCallHelper and friends (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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 unified diff | Download patch
« no previous file with comments | « src/api.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/ieee754.h" 10 #include "src/base/ieee754.h"
(...skipping 5083 matching lines...) Expand 10 before | Expand all | Expand 10 after
5094 isolate, NewTypeError(MessageTemplate::kStrictPoisonPill)); 5094 isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));
5095 } 5095 }
5096 5096
5097 5097
5098 // ----------------------------------------------------------------------------- 5098 // -----------------------------------------------------------------------------
5099 // 5099 //
5100 5100
5101 5101
5102 namespace { 5102 namespace {
5103 5103
5104 // Returns the holder JSObject if the function can legally be called with this
5105 // receiver. Returns nullptr if the call is illegal.
5106 // TODO(dcarney): CallOptimization duplicates this logic, merge.
5107 JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info,
5108 JSObject* receiver) {
5109 Object* recv_type = info->signature();
5110 // No signature, return holder.
5111 if (!recv_type->IsFunctionTemplateInfo()) return receiver;
5112 FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
5113
5114 // Check the receiver. Fast path for receivers with no hidden prototypes.
5115 if (signature->IsTemplateFor(receiver)) return receiver;
5116 if (!receiver->map()->has_hidden_prototype()) return nullptr;
5117 for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype,
5118 PrototypeIterator::END_AT_NON_HIDDEN);
5119 !iter.IsAtEnd(); iter.Advance()) {
5120 JSObject* current = iter.GetCurrent<JSObject>();
5121 if (signature->IsTemplateFor(current)) return current;
5122 }
5123 return nullptr;
5124 }
5125
5104 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate, 5126 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(Isolate* isolate,
5105 BuiltinArguments args) { 5127 BuiltinArguments args) {
5106 HandleScope scope(isolate); 5128 HandleScope scope(isolate);
5107 Handle<HeapObject> function = args.target<HeapObject>(); 5129 Handle<HeapObject> function = args.target<HeapObject>();
5108 Handle<HeapObject> new_target = args.new_target(); 5130 Handle<HeapObject> new_target = args.new_target();
5109 bool is_construct = !new_target->IsUndefined(isolate); 5131 bool is_construct = !new_target->IsUndefined(isolate);
5110 Handle<JSReceiver> receiver; 5132 Handle<JSObject> receiver;
5111 5133
5112 DCHECK(function->IsFunctionTemplateInfo() || 5134 DCHECK(function->IsFunctionTemplateInfo() ||
5113 Handle<JSFunction>::cast(function)->shared()->IsApiFunction()); 5135 Handle<JSFunction>::cast(function)->shared()->IsApiFunction());
5114 5136
5115 Handle<FunctionTemplateInfo> fun_data = 5137 Handle<FunctionTemplateInfo> fun_data =
5116 function->IsFunctionTemplateInfo() 5138 function->IsFunctionTemplateInfo()
5117 ? Handle<FunctionTemplateInfo>::cast(function) 5139 ? Handle<FunctionTemplateInfo>::cast(function)
5118 : handle(JSFunction::cast(*function)->shared()->get_api_func_data()); 5140 : handle(JSFunction::cast(*function)->shared()->get_api_func_data());
5141 JSObject* raw_holder;
5119 if (is_construct) { 5142 if (is_construct) {
5120 DCHECK(args.receiver()->IsTheHole(isolate)); 5143 DCHECK(args.receiver()->IsTheHole(isolate));
5121 if (fun_data->instance_template()->IsUndefined(isolate)) { 5144 if (fun_data->instance_template()->IsUndefined(isolate)) {
5122 v8::Local<ObjectTemplate> templ = 5145 v8::Local<ObjectTemplate> templ =
5123 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), 5146 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
5124 ToApiHandle<v8::FunctionTemplate>(fun_data)); 5147 ToApiHandle<v8::FunctionTemplate>(fun_data));
5125 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); 5148 fun_data->set_instance_template(*Utils::OpenHandle(*templ));
5126 } 5149 }
5127 Handle<ObjectTemplateInfo> instance_template( 5150 Handle<ObjectTemplateInfo> instance_template(
5128 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); 5151 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate);
5129 ASSIGN_RETURN_ON_EXCEPTION( 5152 ASSIGN_RETURN_ON_EXCEPTION(
5130 isolate, receiver, 5153 isolate, receiver,
5131 ApiNatives::InstantiateObject(instance_template, 5154 ApiNatives::InstantiateObject(instance_template,
5132 Handle<JSReceiver>::cast(new_target)), 5155 Handle<JSReceiver>::cast(new_target)),
5133 Object); 5156 Object);
5134 args[0] = *receiver; 5157 args[0] = *receiver;
5135 DCHECK_EQ(*receiver, *args.receiver()); 5158 DCHECK_EQ(*receiver, *args.receiver());
5159
5160 raw_holder = *receiver;
5136 } else { 5161 } else {
5137 DCHECK(args.receiver()->IsJSReceiver()); 5162 DCHECK(args.receiver()->IsJSReceiver());
5138 receiver = args.at<JSReceiver>(0);
5139 }
5140 5163
5141 if (!is_construct && !fun_data->accept_any_receiver()) { 5164 Handle<JSReceiver> object = args.at<JSReceiver>(0);
5142 if (receiver->IsJSObject() && receiver->IsAccessCheckNeeded()) { 5165 if (!object->IsJSObject()) {
5143 Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); 5166 // This function cannot be called with the given receiver. Abort!
5144 if (!isolate->MayAccess(handle(isolate->context()), js_receiver)) { 5167 THROW_NEW_ERROR(
5145 isolate->ReportFailedAccessCheck(js_receiver); 5168 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
5146 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5169 }
5147 } 5170
5171 receiver = Handle<JSObject>::cast(object);
5172
5173 if (!fun_data->accept_any_receiver() && receiver->IsAccessCheckNeeded() &&
5174 !isolate->MayAccess(handle(isolate->context()), receiver)) {
5175 isolate->ReportFailedAccessCheck(receiver);
5176 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5177 }
5178
5179 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *receiver);
5180
5181 if (raw_holder == nullptr) {
5182 // This function cannot be called with the given receiver. Abort!
5183 THROW_NEW_ERROR(
5184 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
5148 } 5185 }
5149 } 5186 }
5150 5187
5151 Object* raw_holder = fun_data->GetCompatibleReceiver(isolate, *receiver);
5152
5153 if (raw_holder->IsNull(isolate)) {
5154 // This function cannot be called with the given receiver. Abort!
5155 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIllegalInvocation),
5156 Object);
5157 }
5158
5159 Object* raw_call_data = fun_data->call_code(); 5188 Object* raw_call_data = fun_data->call_code();
5160 if (!raw_call_data->IsUndefined(isolate)) { 5189 if (!raw_call_data->IsUndefined(isolate)) {
5161 DCHECK(raw_call_data->IsCallHandlerInfo()); 5190 DCHECK(raw_call_data->IsCallHandlerInfo());
5162 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 5191 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
5163 Object* callback_obj = call_data->callback(); 5192 Object* callback_obj = call_data->callback();
5164 v8::FunctionCallback callback = 5193 v8::FunctionCallback callback =
5165 v8::ToCData<v8::FunctionCallback>(callback_obj); 5194 v8::ToCData<v8::FunctionCallback>(callback_obj);
5166 Object* data_obj = call_data->data(); 5195 Object* data_obj = call_data->data();
5167 5196
5168 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); 5197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
5169 DCHECK(raw_holder->IsJSObject());
5170 5198
5171 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, 5199 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
5172 *new_target, &args[0] - 1, 5200 *new_target, &args[0] - 1,
5173 args.length() - 1); 5201 args.length() - 1);
5174 5202
5175 Handle<Object> result = custom.Call(callback); 5203 Handle<Object> result = custom.Call(callback);
5176 if (result.is_null()) result = isolate->factory()->undefined_value(); 5204 if (result.is_null()) result = isolate->factory()->undefined_value();
5177 5205
5178 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5206 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5179 if (!is_construct || result->IsJSObject()) { 5207 if (!is_construct || result->IsJSObject()) {
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
6065 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 6093 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
6066 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 6094 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
6067 #undef DEFINE_BUILTIN_ACCESSOR_C 6095 #undef DEFINE_BUILTIN_ACCESSOR_C
6068 #undef DEFINE_BUILTIN_ACCESSOR_A 6096 #undef DEFINE_BUILTIN_ACCESSOR_A
6069 #undef DEFINE_BUILTIN_ACCESSOR_T 6097 #undef DEFINE_BUILTIN_ACCESSOR_T
6070 #undef DEFINE_BUILTIN_ACCESSOR_S 6098 #undef DEFINE_BUILTIN_ACCESSOR_S
6071 #undef DEFINE_BUILTIN_ACCESSOR_H 6099 #undef DEFINE_BUILTIN_ACCESSOR_H
6072 6100
6073 } // namespace internal 6101 } // namespace internal
6074 } // namespace v8 6102 } // namespace v8
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698