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 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1004 1, 0, shared_info); | 1004 1, 0, shared_info); |
1005 Node* frame_state0 = graph()->NewNode( | 1005 Node* frame_state0 = graph()->NewNode( |
1006 common()->FrameState(BailoutId::None(), | 1006 common()->FrameState(BailoutId::None(), |
1007 OutputFrameStateCombine::Ignore(), | 1007 OutputFrameStateCombine::Ignore(), |
1008 frame_info0), | 1008 frame_info0), |
1009 graph()->NewNode(common()->StateValues(1), receiver), | 1009 graph()->NewNode(common()->StateValues(1), receiver), |
1010 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 1010 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
1011 context, target, frame_state); | 1011 context, target, frame_state); |
1012 | 1012 |
1013 // Introduce the call to the getter function. | 1013 // Introduce the call to the getter function. |
1014 if (access_info.constant()->IsJSFunction()) { | 1014 if (CanInlineApiCall(access_info)) { |
1015 value = effect = graph()->NewNode( | |
1016 javascript()->CallFunction( | |
1017 2, 0.0f, VectorSlotPair(), | |
1018 ConvertReceiverMode::kNotNullOrUndefined), | |
1019 target, receiver, context, frame_state0, effect, control); | |
1020 control = graph()->NewNode(common()->IfSuccess(), value); | |
1021 } else { | |
1022 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1015 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1023 Handle<FunctionTemplateInfo> function_template_info( | 1016 Handle<FunctionTemplateInfo> function_template_info( |
1024 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1017 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1025 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1018 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1026 ValueEffectControl value_effect_control = InlineApiCall( | 1019 ValueEffectControl value_effect_control = InlineApiCall( |
1027 receiver, context, target, frame_state0, nullptr, effect, control, | 1020 receiver, context, target, frame_state0, nullptr, effect, control, |
1028 shared_info, function_template_info); | 1021 shared_info, function_template_info); |
1029 value = value_effect_control.value(); | 1022 value = value_effect_control.value(); |
1030 effect = value_effect_control.effect(); | 1023 effect = value_effect_control.effect(); |
1031 control = value_effect_control.control(); | 1024 control = value_effect_control.control(); |
1025 } else { | |
Toon Verwaest
2017/01/10 13:34:57
This is broken; if CanInlineApiCall returns false
| |
1026 value = effect = graph()->NewNode( | |
1027 javascript()->CallFunction( | |
1028 2, 0.0f, VectorSlotPair(), | |
1029 ConvertReceiverMode::kNotNullOrUndefined), | |
1030 target, receiver, context, frame_state0, effect, control); | |
1031 control = graph()->NewNode(common()->IfSuccess(), value); | |
1032 } | 1032 } |
1033 break; | 1033 break; |
1034 } | 1034 } |
1035 case AccessMode::kStore: { | 1035 case AccessMode::kStore: { |
1036 // We need a FrameState for the setter stub to restore the correct | 1036 // We need a FrameState for the setter stub to restore the correct |
1037 // context and return the appropriate value to fullcodegen. | 1037 // context and return the appropriate value to fullcodegen. |
1038 FrameStateFunctionInfo const* frame_info0 = | 1038 FrameStateFunctionInfo const* frame_info0 = |
1039 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, | 1039 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, |
1040 2, 0, shared_info); | 1040 2, 0, shared_info); |
1041 Node* frame_state0 = graph()->NewNode( | 1041 Node* frame_state0 = graph()->NewNode( |
1042 common()->FrameState(BailoutId::None(), | 1042 common()->FrameState(BailoutId::None(), |
1043 OutputFrameStateCombine::Ignore(), | 1043 OutputFrameStateCombine::Ignore(), |
1044 frame_info0), | 1044 frame_info0), |
1045 graph()->NewNode(common()->StateValues(2), receiver, value), | 1045 graph()->NewNode(common()->StateValues(2), receiver, value), |
1046 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 1046 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
1047 context, target, frame_state); | 1047 context, target, frame_state); |
1048 | 1048 |
1049 // Introduce the call to the setter function. | 1049 // Introduce the call to the setter function. |
1050 if (access_info.constant()->IsJSFunction()) { | 1050 if (CanInlineApiCall(access_info)) { |
1051 effect = graph()->NewNode( | |
1052 javascript()->CallFunction( | |
1053 3, 0.0f, VectorSlotPair(), | |
1054 ConvertReceiverMode::kNotNullOrUndefined), | |
1055 target, receiver, value, context, frame_state0, effect, control); | |
1056 control = graph()->NewNode(common()->IfSuccess(), effect); | |
1057 } else { | |
1058 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); | 1051 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
1059 Handle<FunctionTemplateInfo> function_template_info( | 1052 Handle<FunctionTemplateInfo> function_template_info( |
1060 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | 1053 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
1061 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); | 1054 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
1062 ValueEffectControl value_effect_control = InlineApiCall( | 1055 ValueEffectControl value_effect_control = InlineApiCall( |
1063 receiver, context, target, frame_state0, value, effect, control, | 1056 receiver, context, target, frame_state0, value, effect, control, |
1064 shared_info, function_template_info); | 1057 shared_info, function_template_info); |
1065 value = value_effect_control.value(); | 1058 value = value_effect_control.value(); |
1066 effect = value_effect_control.effect(); | 1059 effect = value_effect_control.effect(); |
1067 control = value_effect_control.control(); | 1060 control = value_effect_control.control(); |
1061 } else { | |
1062 effect = graph()->NewNode( | |
1063 javascript()->CallFunction( | |
1064 3, 0.0f, VectorSlotPair(), | |
1065 ConvertReceiverMode::kNotNullOrUndefined), | |
1066 target, receiver, value, context, frame_state0, effect, control); | |
1067 control = graph()->NewNode(common()->IfSuccess(), effect); | |
1068 } | 1068 } |
1069 break; | 1069 break; |
1070 } | 1070 } |
1071 } | 1071 } |
1072 } else if (access_info.IsDataField()) { | 1072 } else if (access_info.IsDataField()) { |
1073 FieldIndex const field_index = access_info.field_index(); | 1073 FieldIndex const field_index = access_info.field_index(); |
1074 Type* const field_type = access_info.field_type(); | 1074 Type* const field_type = access_info.field_type(); |
1075 MachineRepresentation const field_representation = | 1075 MachineRepresentation const field_representation = |
1076 access_info.field_representation(); | 1076 access_info.field_representation(); |
1077 if (access_mode == AccessMode::kLoad) { | 1077 if (access_mode == AccessMode::kLoad) { |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1551 | 1551 |
1552 // Perform the actual element access. | 1552 // Perform the actual element access. |
1553 effect = graph()->NewNode(simplified()->StoreElement(element_access), | 1553 effect = graph()->NewNode(simplified()->StoreElement(element_access), |
1554 elements, index, value, effect, control); | 1554 elements, index, value, effect, control); |
1555 } | 1555 } |
1556 } | 1556 } |
1557 | 1557 |
1558 return ValueEffectControl(value, effect, control); | 1558 return ValueEffectControl(value, effect, control); |
1559 } | 1559 } |
1560 | 1560 |
1561 bool JSNativeContextSpecialization::CanInlineApiCall( | |
1562 PropertyAccessInfo const& access_info) { | |
1563 if (V8_UNLIKELY(FLAG_runtime_stats)) return false; | |
1564 return access_info.IsAccessorConstant() && | |
1565 access_info.constant()->IsFunctionTemplateInfo(); | |
1566 } | |
1567 | |
1561 JSNativeContextSpecialization::ValueEffectControl | 1568 JSNativeContextSpecialization::ValueEffectControl |
1562 JSNativeContextSpecialization::InlineApiCall( | 1569 JSNativeContextSpecialization::InlineApiCall( |
1563 Node* receiver, Node* context, Node* target, Node* frame_state, Node* value, | 1570 Node* receiver, Node* context, Node* target, Node* frame_state, Node* value, |
1564 Node* effect, Node* control, Handle<SharedFunctionInfo> shared_info, | 1571 Node* effect, Node* control, Handle<SharedFunctionInfo> shared_info, |
1565 Handle<FunctionTemplateInfo> function_template_info) { | 1572 Handle<FunctionTemplateInfo> function_template_info) { |
1566 Handle<CallHandlerInfo> call_handler_info = handle( | 1573 Handle<CallHandlerInfo> call_handler_info = handle( |
1567 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); | 1574 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); |
1568 Handle<Object> call_data_object(call_handler_info->data(), isolate()); | 1575 Handle<Object> call_data_object(call_handler_info->data(), isolate()); |
1569 | 1576 |
1570 // Only setters have a value. | 1577 // Only setters have a value. |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1820 return jsgraph()->javascript(); | 1827 return jsgraph()->javascript(); |
1821 } | 1828 } |
1822 | 1829 |
1823 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1830 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1824 return jsgraph()->simplified(); | 1831 return jsgraph()->simplified(); |
1825 } | 1832 } |
1826 | 1833 |
1827 } // namespace compiler | 1834 } // namespace compiler |
1828 } // namespace internal | 1835 } // namespace internal |
1829 } // namespace v8 | 1836 } // namespace v8 |
OLD | NEW |