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