| 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) {
|
|
|