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 CHECK(access_info.constant()->IsFunctionTemplateInfo()); | |
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
| |
881 Handle<FunctionTemplateInfo> function_template_info( | |
882 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | |
883 CHECK(!function_template_info->call_code()->IsUndefined(isolate())); | |
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
| |
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 CHECK(access_info.constant()->IsFunctionTemplateInfo()); | |
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
| |
918 Handle<FunctionTemplateInfo> function_template_info( | |
919 Handle<FunctionTemplateInfo>::cast(access_info.constant())); | |
920 CHECK(!function_template_info->call_code()->IsUndefined(isolate())); | |
Benedikt Meurer
2016/10/31 09:33:13
Nit: DCHECK
epertoso
2016/10/31 09:44:13
Done.
| |
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 |