| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/flow_graph.h" | 9 #include "vm/flow_graph.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 // Create a parameter stub for each fixed positional parameter. | 543 // Create a parameter stub for each fixed positional parameter. |
| 544 for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) { | 544 for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) { |
| 545 param_stubs->Add(CreateParameterStub(i, (*arguments)[i], callee_graph)); | 545 param_stubs->Add(CreateParameterStub(i, (*arguments)[i], callee_graph)); |
| 546 } | 546 } |
| 547 | 547 |
| 548 // If the callee has optional parameters, rebuild the argument and stub | 548 // If the callee has optional parameters, rebuild the argument and stub |
| 549 // arrays so that actual arguments are in one-to-one with the formal | 549 // arrays so that actual arguments are in one-to-one with the formal |
| 550 // parameters. | 550 // parameters. |
| 551 if (function.HasOptionalParameters()) { | 551 if (function.HasOptionalParameters()) { |
| 552 TRACE_INLINING(OS::Print(" adjusting for optional parameters\n")); | 552 TRACE_INLINING(OS::Print(" adjusting for optional parameters\n")); |
| 553 AdjustForOptionalParameters(*parsed_function, | 553 if (!AdjustForOptionalParameters(*parsed_function, |
| 554 argument_names, | 554 argument_names, |
| 555 arguments, | 555 arguments, |
| 556 param_stubs, | 556 param_stubs, |
| 557 callee_graph); | 557 callee_graph)) { |
| 558 function.set_is_inlinable(false); |
| 559 TRACE_INLINING(OS::Print(" Bailout: optional arg mismatch\n")); |
| 560 return false; |
| 561 } |
| 558 } | 562 } |
| 559 | 563 |
| 560 // After treating optional parameters the actual/formal count must match. | 564 // After treating optional parameters the actual/formal count must match. |
| 561 ASSERT(arguments->length() == function.NumParameters()); | 565 ASSERT(arguments->length() == function.NumParameters()); |
| 562 ASSERT(param_stubs->length() == callee_graph->parameter_count()); | 566 ASSERT(param_stubs->length() == callee_graph->parameter_count()); |
| 563 | 567 |
| 564 { | 568 { |
| 565 TimerScope timer(FLAG_compiler_stats, | 569 TimerScope timer(FLAG_compiler_stats, |
| 566 &CompilerStats::graphinliner_ssa_timer, | 570 &CompilerStats::graphinliner_ssa_timer, |
| 567 isolate); | 571 isolate); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 } | 826 } |
| 823 InlinedCallData call_data(call, &arguments); | 827 InlinedCallData call_data(call, &arguments); |
| 824 if (TryInlining(target, | 828 if (TryInlining(target, |
| 825 call->instance_call()->argument_names(), | 829 call->instance_call()->argument_names(), |
| 826 &call_data)) { | 830 &call_data)) { |
| 827 InlineCall(&call_data); | 831 InlineCall(&call_data); |
| 828 } | 832 } |
| 829 } | 833 } |
| 830 } | 834 } |
| 831 | 835 |
| 832 void AdjustForOptionalParameters(const ParsedFunction& parsed_function, | 836 bool AdjustForOptionalParameters(const ParsedFunction& parsed_function, |
| 833 const Array& argument_names, | 837 const Array& argument_names, |
| 834 GrowableArray<Value*>* arguments, | 838 GrowableArray<Value*>* arguments, |
| 835 ZoneGrowableArray<Definition*>* param_stubs, | 839 ZoneGrowableArray<Definition*>* param_stubs, |
| 836 FlowGraph* callee_graph) { | 840 FlowGraph* callee_graph) { |
| 837 const Function& function = parsed_function.function(); | 841 const Function& function = parsed_function.function(); |
| 838 // The language and this code does not support both optional positional | 842 // The language and this code does not support both optional positional |
| 839 // and optional named parameters for the same function. | 843 // and optional named parameters for the same function. |
| 840 ASSERT(!function.HasOptionalPositionalParameters() || | 844 ASSERT(!function.HasOptionalPositionalParameters() || |
| 841 !function.HasOptionalNamedParameters()); | 845 !function.HasOptionalNamedParameters()); |
| 842 | 846 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 857 // default value. | 861 // default value. |
| 858 for (intptr_t i = arg_count; i < param_count; ++i) { | 862 for (intptr_t i = arg_count; i < param_count; ++i) { |
| 859 const Object& object = | 863 const Object& object = |
| 860 Object::ZoneHandle( | 864 Object::ZoneHandle( |
| 861 parsed_function.default_parameter_values().At( | 865 parsed_function.default_parameter_values().At( |
| 862 i - fixed_param_count)); | 866 i - fixed_param_count)); |
| 863 ConstantInstr* constant = new ConstantInstr(object); | 867 ConstantInstr* constant = new ConstantInstr(object); |
| 864 arguments->Add(NULL); | 868 arguments->Add(NULL); |
| 865 param_stubs->Add(constant); | 869 param_stubs->Add(constant); |
| 866 } | 870 } |
| 867 return; | 871 return true; |
| 868 } | 872 } |
| 869 | 873 |
| 870 ASSERT(function.HasOptionalNamedParameters()); | 874 ASSERT(function.HasOptionalNamedParameters()); |
| 871 | 875 |
| 872 // Passed arguments must match fixed parameters plus named arguments. | 876 // Passed arguments must match fixed parameters plus named arguments. |
| 873 intptr_t argument_names_count = | 877 intptr_t argument_names_count = |
| 874 (argument_names.IsNull()) ? 0 : argument_names.Length(); | 878 (argument_names.IsNull()) ? 0 : argument_names.Length(); |
| 875 ASSERT(arg_count == (fixed_param_count + argument_names_count)); | 879 ASSERT(arg_count == (fixed_param_count + argument_names_count)); |
| 876 | 880 |
| 877 // Fast path when no optional named parameters are given. | 881 // Fast path when no optional named parameters are given. |
| 878 if (argument_names_count == 0) { | 882 if (argument_names_count == 0) { |
| 879 for (intptr_t i = 0; i < param_count - fixed_param_count; ++i) { | 883 for (intptr_t i = 0; i < param_count - fixed_param_count; ++i) { |
| 880 arguments->Add(NULL); | 884 arguments->Add(NULL); |
| 881 param_stubs->Add(GetDefaultValue(i, parsed_function)); | 885 param_stubs->Add(GetDefaultValue(i, parsed_function)); |
| 882 } | 886 } |
| 883 return; | 887 return true; |
| 884 } | 888 } |
| 885 | 889 |
| 886 // Otherwise, build a collection of name/argument pairs. | 890 // Otherwise, build a collection of name/argument pairs. |
| 887 GrowableArray<NamedArgument> named_args(argument_names_count); | 891 GrowableArray<NamedArgument> named_args(argument_names_count); |
| 888 for (intptr_t i = 0; i < argument_names.Length(); ++i) { | 892 for (intptr_t i = 0; i < argument_names.Length(); ++i) { |
| 889 String& arg_name = String::Handle(Isolate::Current()); | 893 String& arg_name = String::Handle(Isolate::Current()); |
| 890 arg_name ^= argument_names.At(i); | 894 arg_name ^= argument_names.At(i); |
| 891 named_args.Add( | 895 named_args.Add( |
| 892 NamedArgument(&arg_name, (*arguments)[i + fixed_param_count])); | 896 NamedArgument(&arg_name, (*arguments)[i + fixed_param_count])); |
| 893 } | 897 } |
| 894 | 898 |
| 895 // Truncate the arguments array to just fixed parameters. | 899 // Truncate the arguments array to just fixed parameters. |
| 896 arguments->TruncateTo(fixed_param_count); | 900 arguments->TruncateTo(fixed_param_count); |
| 897 | 901 |
| 898 // For each optional named parameter, add the actual argument or its | 902 // For each optional named parameter, add the actual argument or its |
| 899 // default if no argument is passed. | 903 // default if no argument is passed. |
| 904 intptr_t match_count = 0; |
| 900 for (intptr_t i = fixed_param_count; i < param_count; ++i) { | 905 for (intptr_t i = fixed_param_count; i < param_count; ++i) { |
| 901 String& param_name = String::Handle(function.ParameterNameAt(i)); | 906 String& param_name = String::Handle(function.ParameterNameAt(i)); |
| 902 // Search for and add the named argument. | 907 // Search for and add the named argument. |
| 903 Value* arg = NULL; | 908 Value* arg = NULL; |
| 904 for (intptr_t j = 0; j < named_args.length(); ++j) { | 909 for (intptr_t j = 0; j < named_args.length(); ++j) { |
| 905 if (param_name.Equals(*named_args[j].name)) { | 910 if (param_name.Equals(*named_args[j].name)) { |
| 906 arg = named_args[j].value; | 911 arg = named_args[j].value; |
| 912 match_count++; |
| 907 break; | 913 break; |
| 908 } | 914 } |
| 909 } | 915 } |
| 910 arguments->Add(arg); | 916 arguments->Add(arg); |
| 911 // Create a stub for the argument or use the parameter's default value. | 917 // Create a stub for the argument or use the parameter's default value. |
| 912 if (arg != NULL) { | 918 if (arg != NULL) { |
| 913 param_stubs->Add(CreateParameterStub(i, arg, callee_graph)); | 919 param_stubs->Add(CreateParameterStub(i, arg, callee_graph)); |
| 914 } else { | 920 } else { |
| 915 param_stubs->Add( | 921 param_stubs->Add( |
| 916 GetDefaultValue(i - fixed_param_count, parsed_function)); | 922 GetDefaultValue(i - fixed_param_count, parsed_function)); |
| 917 } | 923 } |
| 918 } | 924 } |
| 925 return argument_names_count == match_count; |
| 919 } | 926 } |
| 920 | 927 |
| 921 | 928 |
| 922 FlowGraph* caller_graph_; | 929 FlowGraph* caller_graph_; |
| 923 bool inlined_; | 930 bool inlined_; |
| 924 intptr_t initial_size_; | 931 intptr_t initial_size_; |
| 925 intptr_t inlined_size_; | 932 intptr_t inlined_size_; |
| 926 intptr_t inlining_depth_; | 933 intptr_t inlining_depth_; |
| 927 CallSites* collected_call_sites_; | 934 CallSites* collected_call_sites_; |
| 928 CallSites* inlining_call_sites_; | 935 CallSites* inlining_call_sites_; |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 OS::Print("After Inlining of %s\n", flow_graph_-> | 1375 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 1369 parsed_function().function().ToFullyQualifiedCString()); | 1376 parsed_function().function().ToFullyQualifiedCString()); |
| 1370 FlowGraphPrinter printer(*flow_graph_); | 1377 FlowGraphPrinter printer(*flow_graph_); |
| 1371 printer.PrintBlocks(); | 1378 printer.PrintBlocks(); |
| 1372 } | 1379 } |
| 1373 } | 1380 } |
| 1374 } | 1381 } |
| 1375 } | 1382 } |
| 1376 | 1383 |
| 1377 } // namespace dart | 1384 } // namespace dart |
| OLD | NEW |