Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2458643002: [turbofan] Handle inlining of API getters/setters. (Closed)
Patch Set: Update. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698