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

Unified Diff: src/compiler/js-native-context-specialization.cc

Issue 2458643002: [turbofan] Handle inlining of API getters/setters. (Closed)
Patch Set: Update. Created 4 years, 1 month 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
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-native-context-specialization.cc
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index f6b29ab81c74d93fcef3cf7a182bf4d2b42dda42..57e933b1aa0c3b28db60ff0567db144605787a47 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -869,12 +869,26 @@ JSNativeContextSpecialization::BuildPropertyAccess(
context, target, frame_state);
// Introduce the call to the getter function.
- value = effect = graph()->NewNode(
- javascript()->CallFunction(
- 2, 0.0f, VectorSlotPair(),
- ConvertReceiverMode::kNotNullOrUndefined),
- target, receiver, context, frame_state0, effect, control);
- control = graph()->NewNode(common()->IfSuccess(), value);
+ if (access_info.constant()->IsJSFunction()) {
+ value = effect = graph()->NewNode(
+ javascript()->CallFunction(
+ 2, 0.0f, VectorSlotPair(),
+ ConvertReceiverMode::kNotNullOrUndefined),
+ target, receiver, context, frame_state0, effect, control);
+ control = graph()->NewNode(common()->IfSuccess(), value);
+ } else {
+ DCHECK(access_info.constant()->IsFunctionTemplateInfo());
+ Handle<FunctionTemplateInfo> function_template_info(
+ Handle<FunctionTemplateInfo>::cast(access_info.constant()));
+ DCHECK(!function_template_info->call_code()->IsUndefined(isolate()));
+ ZoneVector<Node*> stack_parameters(graph()->zone());
+ ValueEffectControl value_effect_control = InlineApiCall(
+ receiver, context, target, frame_state0, &stack_parameters,
+ effect, control, shared_info, function_template_info);
+ value = value_effect_control.value();
+ effect = value_effect_control.effect();
+ control = value_effect_control.control();
+ }
break;
}
case AccessMode::kStore: {
@@ -892,12 +906,27 @@ JSNativeContextSpecialization::BuildPropertyAccess(
context, target, frame_state);
// Introduce the call to the setter function.
- effect = graph()->NewNode(javascript()->CallFunction(
- 3, 0.0f, VectorSlotPair(),
- ConvertReceiverMode::kNotNullOrUndefined),
- target, receiver, value, context,
- frame_state0, effect, control);
- control = graph()->NewNode(common()->IfSuccess(), effect);
+ if (access_info.constant()->IsJSFunction()) {
+ effect = graph()->NewNode(
+ javascript()->CallFunction(
+ 3, 0.0f, VectorSlotPair(),
+ ConvertReceiverMode::kNotNullOrUndefined),
+ target, receiver, value, context, frame_state0, effect, control);
+ control = graph()->NewNode(common()->IfSuccess(), effect);
+ } else {
+ DCHECK(access_info.constant()->IsFunctionTemplateInfo());
+ Handle<FunctionTemplateInfo> function_template_info(
+ Handle<FunctionTemplateInfo>::cast(access_info.constant()));
+ DCHECK(!function_template_info->call_code()->IsUndefined(isolate()));
+ ZoneVector<Node*> stack_parameters(graph()->zone());
+ stack_parameters.push_back(value);
+ ValueEffectControl value_effect_control = InlineApiCall(
+ receiver, context, target, frame_state0, &stack_parameters,
+ effect, control, shared_info, function_template_info);
+ value = value_effect_control.value();
+ effect = value_effect_control.effect();
+ control = value_effect_control.control();
+ }
break;
}
}
@@ -1323,6 +1352,65 @@ JSNativeContextSpecialization::BuildElementAccess(
return ValueEffectControl(value, effect, control);
}
+JSNativeContextSpecialization::ValueEffectControl
+JSNativeContextSpecialization::InlineApiCall(
+ Node* receiver, Node* context, Node* target, Node* frame_state,
+ ZoneVector<Node*>* stack_parameters, Node* effect, Node* control,
+ Handle<SharedFunctionInfo> shared_info,
+ Handle<FunctionTemplateInfo> function_template_info) {
+ Handle<CallHandlerInfo> call_handler_info = handle(
+ CallHandlerInfo::cast(function_template_info->call_code()), isolate());
+ Handle<Object> call_data_object(call_handler_info->data(), isolate());
+
+ // The stub always expects the receiver as the first param on the stack.
+ CallApiCallbackStub stub(
+ isolate(), static_cast<int>(stack_parameters->size()),
+ call_data_object->IsUndefined(isolate()),
+ true /* TODO(epertoso): similar to CallOptimization */);
+ CallInterfaceDescriptor call_interface_descriptor =
+ stub.GetCallInterfaceDescriptor();
+ CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
+ isolate(), graph()->zone(), call_interface_descriptor,
+ call_interface_descriptor.GetStackParameterCount() +
+ static_cast<int>(stack_parameters->size()) + 1,
+ CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
+ MachineType::AnyTagged(), 1);
+
+ Node* data = jsgraph()->Constant(call_data_object);
+ ApiFunction function(v8::ToCData<Address>(call_handler_info->callback()));
+ Node* function_reference =
+ graph()->NewNode(common()->ExternalConstant(ExternalReference(
+ &function, ExternalReference::DIRECT_API_CALL, isolate())));
+ Node* code = jsgraph()->HeapConstant(stub.GetCode());
+
+ ZoneVector<Node*> inputs(zone());
+ inputs.push_back(code);
+
+ // CallApiCallbackStub's register arguments.
+ inputs.push_back(target);
+ inputs.push_back(data);
+ inputs.push_back(receiver);
+ inputs.push_back(function_reference);
+
+ // Stack parameters: CallApiCallbackStub expects the first one to be the
+ // receiver.
+ inputs.push_back(receiver);
+ for (Node* node : *stack_parameters) {
+ inputs.push_back(node);
+ }
+ inputs.push_back(context);
+ inputs.push_back(frame_state);
+ inputs.push_back(effect);
+ inputs.push_back(control);
+
+ Node* effect0;
+ Node* value0 = effect0 =
+ graph()->NewNode(common()->Call(call_descriptor),
+ static_cast<int>(inputs.size()), inputs.data());
+ Node* control0 = graph()->NewNode(common()->IfSuccess(), value0);
+ return ValueEffectControl(value0, effect0, control0);
+}
+
Node* JSNativeContextSpecialization::BuildCheckMaps(
Node* receiver, Node* effect, Node* control,
std::vector<Handle<Map>> const& maps) {
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698