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 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 1, 0, shared_info); | 862 1, 0, shared_info); |
863 Node* frame_state0 = graph()->NewNode( | 863 Node* frame_state0 = graph()->NewNode( |
864 common()->FrameState(BailoutId::None(), | 864 common()->FrameState(BailoutId::None(), |
865 OutputFrameStateCombine::Ignore(), | 865 OutputFrameStateCombine::Ignore(), |
866 frame_info0), | 866 frame_info0), |
867 graph()->NewNode(common()->StateValues(1), receiver), | 867 graph()->NewNode(common()->StateValues(1), receiver), |
868 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 868 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
869 context, target, frame_state); | 869 context, target, frame_state); |
870 | 870 |
871 // Introduce the call to the getter function. | 871 // Introduce the call to the getter function. |
872 value = effect = graph()->NewNode( | 872 if (access_info.constant()->IsJSFunction()) { |
873 javascript()->CallFunction( | 873 value = effect = graph()->NewNode( |
874 2, 0.0f, VectorSlotPair(), | 874 javascript()->CallFunction( |
875 ConvertReceiverMode::kNotNullOrUndefined), | 875 2, 0.0f, VectorSlotPair(), |
876 target, receiver, context, frame_state0, effect, control); | 876 ConvertReceiverMode::kNotNullOrUndefined), |
877 control = graph()->NewNode(common()->IfSuccess(), value); | 877 target, receiver, context, frame_state0, effect, control); |
| 878 control = graph()->NewNode(common()->IfSuccess(), value); |
| 879 } else { |
| 880 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
| 881 Handle<FunctionTemplateInfo> function_template_info( |
| 882 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
| 883 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
| 884 ZoneVector<Node*> stack_parameters(graph()->zone()); |
| 885 ValueEffectControl value_effect_control = InlineApiCall( |
| 886 receiver, context, target, frame_state0, &stack_parameters, |
| 887 effect, control, shared_info, function_template_info); |
| 888 value = value_effect_control.value(); |
| 889 effect = value_effect_control.effect(); |
| 890 control = value_effect_control.control(); |
| 891 } |
878 break; | 892 break; |
879 } | 893 } |
880 case AccessMode::kStore: { | 894 case AccessMode::kStore: { |
881 // We need a FrameState for the setter stub to restore the correct | 895 // We need a FrameState for the setter stub to restore the correct |
882 // context and return the appropriate value to fullcodegen. | 896 // context and return the appropriate value to fullcodegen. |
883 FrameStateFunctionInfo const* frame_info0 = | 897 FrameStateFunctionInfo const* frame_info0 = |
884 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, | 898 common()->CreateFrameStateFunctionInfo(FrameStateType::kSetterStub, |
885 2, 0, shared_info); | 899 2, 0, shared_info); |
886 Node* frame_state0 = graph()->NewNode( | 900 Node* frame_state0 = graph()->NewNode( |
887 common()->FrameState(BailoutId::None(), | 901 common()->FrameState(BailoutId::None(), |
888 OutputFrameStateCombine::Ignore(), | 902 OutputFrameStateCombine::Ignore(), |
889 frame_info0), | 903 frame_info0), |
890 graph()->NewNode(common()->StateValues(2), receiver, value), | 904 graph()->NewNode(common()->StateValues(2), receiver, value), |
891 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 905 jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
892 context, target, frame_state); | 906 context, target, frame_state); |
893 | 907 |
894 // Introduce the call to the setter function. | 908 // Introduce the call to the setter function. |
895 effect = graph()->NewNode(javascript()->CallFunction( | 909 if (access_info.constant()->IsJSFunction()) { |
896 3, 0.0f, VectorSlotPair(), | 910 effect = graph()->NewNode( |
897 ConvertReceiverMode::kNotNullOrUndefined), | 911 javascript()->CallFunction( |
898 target, receiver, value, context, | 912 3, 0.0f, VectorSlotPair(), |
899 frame_state0, effect, control); | 913 ConvertReceiverMode::kNotNullOrUndefined), |
900 control = graph()->NewNode(common()->IfSuccess(), effect); | 914 target, receiver, value, context, frame_state0, effect, control); |
| 915 control = graph()->NewNode(common()->IfSuccess(), effect); |
| 916 } else { |
| 917 DCHECK(access_info.constant()->IsFunctionTemplateInfo()); |
| 918 Handle<FunctionTemplateInfo> function_template_info( |
| 919 Handle<FunctionTemplateInfo>::cast(access_info.constant())); |
| 920 DCHECK(!function_template_info->call_code()->IsUndefined(isolate())); |
| 921 ZoneVector<Node*> stack_parameters(graph()->zone()); |
| 922 stack_parameters.push_back(value); |
| 923 ValueEffectControl value_effect_control = InlineApiCall( |
| 924 receiver, context, target, frame_state0, &stack_parameters, |
| 925 effect, control, shared_info, function_template_info); |
| 926 value = value_effect_control.value(); |
| 927 effect = value_effect_control.effect(); |
| 928 control = value_effect_control.control(); |
| 929 } |
901 break; | 930 break; |
902 } | 931 } |
903 } | 932 } |
904 } else { | 933 } else { |
905 DCHECK(access_info.IsDataField()); | 934 DCHECK(access_info.IsDataField()); |
906 FieldIndex const field_index = access_info.field_index(); | 935 FieldIndex const field_index = access_info.field_index(); |
907 Type* const field_type = access_info.field_type(); | 936 Type* const field_type = access_info.field_type(); |
908 MachineRepresentation const field_representation = | 937 MachineRepresentation const field_representation = |
909 access_info.field_representation(); | 938 access_info.field_representation(); |
910 if (access_mode == AccessMode::kLoad) { | 939 if (access_mode == AccessMode::kLoad) { |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 | 1345 |
1317 // Perform the actual element access. | 1346 // Perform the actual element access. |
1318 effect = graph()->NewNode(simplified()->StoreElement(element_access), | 1347 effect = graph()->NewNode(simplified()->StoreElement(element_access), |
1319 elements, index, value, effect, control); | 1348 elements, index, value, effect, control); |
1320 } | 1349 } |
1321 } | 1350 } |
1322 | 1351 |
1323 return ValueEffectControl(value, effect, control); | 1352 return ValueEffectControl(value, effect, control); |
1324 } | 1353 } |
1325 | 1354 |
| 1355 JSNativeContextSpecialization::ValueEffectControl |
| 1356 JSNativeContextSpecialization::InlineApiCall( |
| 1357 Node* receiver, Node* context, Node* target, Node* frame_state, |
| 1358 ZoneVector<Node*>* stack_parameters, Node* effect, Node* control, |
| 1359 Handle<SharedFunctionInfo> shared_info, |
| 1360 Handle<FunctionTemplateInfo> function_template_info) { |
| 1361 Handle<CallHandlerInfo> call_handler_info = handle( |
| 1362 CallHandlerInfo::cast(function_template_info->call_code()), isolate()); |
| 1363 Handle<Object> call_data_object(call_handler_info->data(), isolate()); |
| 1364 |
| 1365 // The stub always expects the receiver as the first param on the stack. |
| 1366 CallApiCallbackStub stub( |
| 1367 isolate(), static_cast<int>(stack_parameters->size()), |
| 1368 call_data_object->IsUndefined(isolate()), |
| 1369 true /* TODO(epertoso): similar to CallOptimization */); |
| 1370 CallInterfaceDescriptor call_interface_descriptor = |
| 1371 stub.GetCallInterfaceDescriptor(); |
| 1372 CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor( |
| 1373 isolate(), graph()->zone(), call_interface_descriptor, |
| 1374 call_interface_descriptor.GetStackParameterCount() + |
| 1375 static_cast<int>(stack_parameters->size()) + 1, |
| 1376 CallDescriptor::kNeedsFrameState, Operator::kNoProperties, |
| 1377 MachineType::AnyTagged(), 1); |
| 1378 |
| 1379 Node* data = jsgraph()->Constant(call_data_object); |
| 1380 ApiFunction function(v8::ToCData<Address>(call_handler_info->callback())); |
| 1381 Node* function_reference = |
| 1382 graph()->NewNode(common()->ExternalConstant(ExternalReference( |
| 1383 &function, ExternalReference::DIRECT_API_CALL, isolate()))); |
| 1384 Node* code = jsgraph()->HeapConstant(stub.GetCode()); |
| 1385 |
| 1386 ZoneVector<Node*> inputs(zone()); |
| 1387 inputs.push_back(code); |
| 1388 |
| 1389 // CallApiCallbackStub's register arguments. |
| 1390 inputs.push_back(target); |
| 1391 inputs.push_back(data); |
| 1392 inputs.push_back(receiver); |
| 1393 inputs.push_back(function_reference); |
| 1394 |
| 1395 // Stack parameters: CallApiCallbackStub expects the first one to be the |
| 1396 // receiver. |
| 1397 inputs.push_back(receiver); |
| 1398 for (Node* node : *stack_parameters) { |
| 1399 inputs.push_back(node); |
| 1400 } |
| 1401 inputs.push_back(context); |
| 1402 inputs.push_back(frame_state); |
| 1403 inputs.push_back(effect); |
| 1404 inputs.push_back(control); |
| 1405 |
| 1406 Node* effect0; |
| 1407 Node* value0 = effect0 = |
| 1408 graph()->NewNode(common()->Call(call_descriptor), |
| 1409 static_cast<int>(inputs.size()), inputs.data()); |
| 1410 Node* control0 = graph()->NewNode(common()->IfSuccess(), value0); |
| 1411 return ValueEffectControl(value0, effect0, control0); |
| 1412 } |
| 1413 |
1326 Node* JSNativeContextSpecialization::BuildCheckMaps( | 1414 Node* JSNativeContextSpecialization::BuildCheckMaps( |
1327 Node* receiver, Node* effect, Node* control, | 1415 Node* receiver, Node* effect, Node* control, |
1328 std::vector<Handle<Map>> const& maps) { | 1416 std::vector<Handle<Map>> const& maps) { |
1329 HeapObjectMatcher m(receiver); | 1417 HeapObjectMatcher m(receiver); |
1330 if (m.HasValue()) { | 1418 if (m.HasValue()) { |
1331 Handle<Map> receiver_map(m.Value()->map(), isolate()); | 1419 Handle<Map> receiver_map(m.Value()->map(), isolate()); |
1332 if (receiver_map->is_stable()) { | 1420 if (receiver_map->is_stable()) { |
1333 for (Handle<Map> map : maps) { | 1421 for (Handle<Map> map : maps) { |
1334 if (map.is_identical_to(receiver_map)) { | 1422 if (map.is_identical_to(receiver_map)) { |
1335 dependencies()->AssumeMapStable(receiver_map); | 1423 dependencies()->AssumeMapStable(receiver_map); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 return jsgraph()->javascript(); | 1623 return jsgraph()->javascript(); |
1536 } | 1624 } |
1537 | 1625 |
1538 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1626 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1539 return jsgraph()->simplified(); | 1627 return jsgraph()->simplified(); |
1540 } | 1628 } |
1541 | 1629 |
1542 } // namespace compiler | 1630 } // namespace compiler |
1543 } // namespace internal | 1631 } // namespace internal |
1544 } // namespace v8 | 1632 } // namespace v8 |
OLD | NEW |