OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/js-native-context-specialization.h" | 5 #include "src/compiler/js-native-context-specialization.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 Node* frame_state0 = graph()->NewNode( | 1000 Node* frame_state0 = graph()->NewNode( |
1001 common()->FrameState(BailoutId::None(), | 1001 common()->FrameState(BailoutId::None(), |
1002 OutputFrameStateCombine::Ignore(), | 1002 OutputFrameStateCombine::Ignore(), |
1003 frame_info0), | 1003 frame_info0), |
1004 graph()->NewNode(common()->StateValues(1, SparseInputMask::Dense()), | 1004 graph()->NewNode(common()->StateValues(1, SparseInputMask::Dense()), |
1005 receiver), | 1005 receiver), |
1006 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 1006 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
1007 context, target, frame_state); | 1007 context, target, frame_state); |
1008 | 1008 |
1009 // Introduce the call to the getter function. | 1009 // Introduce the call to the getter function. |
1010 if (CanInlineApiCall(access_info)) { | 1010 if (access_info.constant()->IsJSFunction()) { |
| 1011 value = effect = graph()->NewNode( |
| 1012 javascript()->CallFunction( |
| 1013 2, 0.0f, VectorSlotPair(), |
| 1014 ConvertReceiverMode::kNotNullOrUndefined), |
| 1015 target, receiver, context, frame_state0, effect, control); |
| 1016 control = graph()->NewNode(common()->IfSuccess(), value); |
| 1017 } else { |
1011 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1018 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1012 Handle<FunctionTemplateInfo> function_template_info( | 1019 Handle<FunctionTemplateInfo> function_template_info( |
1013 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1020 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1014 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1021 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1015 ValueEffectControl value_effect_control = InlineApiCall( | 1022 ValueEffectControl value_effect_control = InlineApiCall( |
1016 receiver, context, target, frame_state0, nullptr, effect, control, | 1023 receiver, context, target, frame_state0, nullptr, effect, control, |
1017 shared_info, function_template_info); | 1024 shared_info, function_template_info); |
1018 value = value_effect_control.value(); | 1025 value = value_effect_control.value(); |
1019 effect = value_effect_control.effect(); | 1026 effect = value_effect_control.effect(); |
1020 control = value_effect_control.control(); | 1027 control = value_effect_control.control(); |
1021 } else { | |
1022 value = effect = graph()->NewNode( | |
1023 javascript()->CallFunction( | |
1024 2, 0.0f, VectorSlotPair(), | |
1025 ConvertReceiverMode::kNotNullOrUndefined), | |
1026 target, receiver, context, frame_state0, effect, control); | |
1027 control = graph()->NewNode(common()->IfSuccess(), value); | |
1028 } | 1028 } |
1029 break; | 1029 break; |
1030 } | 1030 } |
1031 case AccessMode::kStore: { | 1031 case AccessMode::kStore: { |
1032 // We need a FrameState for the setter stub to restore the correct | 1032 // We need a FrameState for the setter stub to restore the correct |
1033 // context and return the appropriate value to fullcodegen. | 1033 // context and return the appropriate value to fullcodegen. |
1034 FrameStateFunctionInfo const* frame_info0 = | 1034 FrameStateFunctionInfo const* frame_info0 = |
1035 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, | 1035 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, |
1036 2, 0, shared_info); | 1036 2, 0, shared_info); |
1037 Node* frame_state0 = graph()->NewNode( | 1037 Node* frame_state0 = graph()->NewNode( |
1038 common()->FrameState(BailoutId::None(), | 1038 common()->FrameState(BailoutId::None(), |
1039 OutputFrameStateCombine::Ignore(), | 1039 OutputFrameStateCombine::Ignore(), |
1040 frame_info0), | 1040 frame_info0), |
1041 graph()->NewNode(common()->StateValues(2, SparseInputMask::Dense()), | 1041 graph()->NewNode(common()->StateValues(2, SparseInputMask::Dense()), |
1042 receiver, value), | 1042 receiver, value), |
1043 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 1043 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
1044 context, target, frame_state); | 1044 context, target, frame_state); |
1045 | 1045 |
1046 // Introduce the call to the setter function. | 1046 // Introduce the call to the setter function. |
1047 if (CanInlineApiCall(access_info)) { | 1047 if (access_info.constant()->IsJSFunction()) { |
| 1048 effect = graph()->NewNode( |
| 1049 javascript()->CallFunction( |
| 1050 3, 0.0f, VectorSlotPair(), |
| 1051 ConvertReceiverMode::kNotNullOrUndefined), |
| 1052 target, receiver, value, context, frame_state0, effect, control); |
| 1053 control = graph()->NewNode(common()->IfSuccess(), effect); |
| 1054 } else { |
1048 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1055 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1049 Handle<FunctionTemplateInfo> function_template_info( | 1056 Handle<FunctionTemplateInfo> function_template_info( |
1050 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1057 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1051 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1058 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1052 ValueEffectControl value_effect_control = InlineApiCall( | 1059 ValueEffectControl value_effect_control = InlineApiCall( |
1053 receiver, context, target, frame_state0, value, effect, control, | 1060 receiver, context, target, frame_state0, value, effect, control, |
1054 shared_info, function_template_info); | 1061 shared_info, function_template_info); |
1055 value = value_effect_control.value(); | 1062 value = value_effect_control.value(); |
1056 effect = value_effect_control.effect(); | 1063 effect = value_effect_control.effect(); |
1057 control = value_effect_control.control(); | 1064 control = value_effect_control.control(); |
1058 } else { | |
1059 effect = graph()->NewNode( | |
1060 javascript()->CallFunction( | |
1061 3, 0.0f, VectorSlotPair(), | |
1062 ConvertReceiverMode::kNotNullOrUndefined), | |
1063 target, receiver, value, context, frame_state0, effect, control); | |
1064 control = graph()->NewNode(common()->IfSuccess(), effect); | |
1065 } | 1065 } |
1066 break; | 1066 break; |
1067 } | 1067 } |
1068 } | 1068 } |
1069 } else if (access_info.IsDataField()) { | 1069 } else if (access_info.IsDataField()) { |
1070 FieldIndex const field_index = access_info.field_index(); | 1070 FieldIndex const field_index = access_info.field_index(); |
1071 Type* const field_type = access_info.field_type(); | 1071 Type* const field_type = access_info.field_type(); |
1072 MachineRepresentation const field_representation = | 1072 MachineRepresentation const field_representation = |
1073 access_info.field_representation(); | 1073 access_info.field_representation(); |
1074 if (access_mode == AccessMode::kLoad) { | 1074 if (access_mode == AccessMode::kLoad) { |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1566 | 1566 |
1567 // Perform the actual element access. | 1567 // Perform the actual element access. |
1568 effect = graph()->NewNode(simplified()->StoreElement(element_access), | 1568 effect = graph()->NewNode(simplified()->StoreElement(element_access), |
1569 elements, index, value, effect, control); | 1569 elements, index, value, effect, control); |
1570 } | 1570 } |
1571 } | 1571 } |
1572 | 1572 |
1573 return ValueEffectControl(value, effect, control); | 1573 return ValueEffectControl(value, effect, control); |
1574 } | 1574 } |
1575 | 1575 |
1576 bool JSNativeContextSpecialization::CanInlineApiCall( | |
1577 PropertyAccessInfo const& access_info) { | |
1578 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; | |
1579 return access_info.IsAccessorConstant() && | |
1580 access_info.constant()->IsFunctionTemplateInfo(); | |
1581 } | |
1582 | |
1583 JSNativeContextSpecialization::ValueEffectControl | 1576 JSNativeContextSpecialization::ValueEffectControl |
1584 JSNativeContextSpecialization::InlineApiCall( | 1577 JSNativeContextSpecialization::InlineApiCall( |
1585 Node* receiver, Node* context, Node* target, Node* frame_state, Node* value, | 1578 Node* receiver, Node* context, Node* target, Node* frame_state, Node* value, |
1586 Node* effect, Node* control, Handle<SharedFunctionInfo> shared_info, | 1579 Node* effect, Node* control, Handle<SharedFunctionInfo> shared_info, |
1587 Handle<FunctionTemplateInfo> function_template_info) { | 1580 Handle<FunctionTemplateInfo> function_template_info) { |
1588 Handle<CallHandlerInfo> call_handler_info = handle( | 1581 Handle<CallHandlerInfo> call_handler_info = handle( |
1589 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); | 1582 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); |
1590 Handle<Object> call_data_object(call_handler_info->data(), isolate()); | 1583 Handle<Object> call_data_object(call_handler_info->data(), isolate()); |
1591 | 1584 |
1592 // Only setters have a value. | 1585 // Only setters have a value. |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 return jsgraph()->javascript(); | 1832 return jsgraph()->javascript(); |
1840 } | 1833 } |
1841 | 1834 |
1842 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1835 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1843 return jsgraph()->simplified(); | 1836 return jsgraph()->simplified(); |
1844 } | 1837 } |
1845 | 1838 |
1846 } // namespace compiler | 1839 } // namespace compiler |
1847 } // namespace internal | 1840 } // namespace internal |
1848 } // namespace v8 | 1841 } // namespace v8 |
OLD | NEW |