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