Chromium Code Reviews| 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..927f7df9055806a235ea3de60ec522f324b9eba1 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 { |
| + CHECK(access_info.constant()->IsFunctionTemplateInfo()); |
|
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
|
| + Handle<FunctionTemplateInfo> function_template_info( |
| + Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
| + CHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
|
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
|
| + 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 { |
| + CHECK(access_info.constant()->IsFunctionTemplateInfo()); |
|
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
|
| + Handle<FunctionTemplateInfo> function_template_info( |
| + Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
| + CHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
|
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
|
| + 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) { |