| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_builder.h" | 5 #include "vm/flow_graph_builder.h" | 
| 6 | 6 | 
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" | 
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" | 
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" | 
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 24             "Eliminate type checks when allowed by static type analysis."); | 24             "Eliminate type checks when allowed by static type analysis."); | 
| 25 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); | 25 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); | 
| 26 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); | 26 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); | 
| 27 DEFINE_FLAG(bool, print_flow_graph_optimized, false, | 27 DEFINE_FLAG(bool, print_flow_graph_optimized, false, | 
| 28             "Print the IR flow graph when optimizing."); | 28             "Print the IR flow graph when optimizing."); | 
| 29 DEFINE_FLAG(bool, trace_type_check_elimination, false, | 29 DEFINE_FLAG(bool, trace_type_check_elimination, false, | 
| 30             "Trace type check elimination at compile time."); | 30             "Trace type check elimination at compile time."); | 
| 31 DECLARE_FLAG(bool, enable_type_checks); | 31 DECLARE_FLAG(bool, enable_type_checks); | 
| 32 | 32 | 
| 33 | 33 | 
|  | 34 static const String& PrivateCoreLibName(const String& str) { | 
|  | 35   const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 
|  | 36   const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); | 
|  | 37   return private_name; | 
|  | 38 } | 
|  | 39 | 
|  | 40 | 
| 34 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function, | 41 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function, | 
| 35                                    InliningContext* inlining_context) | 42                                    InliningContext* inlining_context) | 
| 36   : parsed_function_(parsed_function), | 43   : parsed_function_(parsed_function), | 
| 37     num_copied_params_(parsed_function.num_copied_params()), | 44     num_copied_params_(parsed_function.num_copied_params()), | 
| 38     // All parameters are copied if any parameter is. | 45     // All parameters are copied if any parameter is. | 
| 39     num_non_copied_params_((num_copied_params_ == 0) | 46     num_non_copied_params_((num_copied_params_ == 0) | 
| 40         ? parsed_function.function().num_fixed_parameters() | 47         ? parsed_function.function().num_fixed_parameters() | 
| 41         : 0), | 48         : 0), | 
| 42     num_stack_locals_(parsed_function.num_stack_locals()), | 49     num_stack_locals_(parsed_function.num_stack_locals()), | 
| 43     inlining_context_(inlining_context), | 50     inlining_context_(inlining_context), | 
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 943   PushArgumentInstr* push_instantiator = NULL; | 950   PushArgumentInstr* push_instantiator = NULL; | 
| 944   PushArgumentInstr* push_type_args = NULL; | 951   PushArgumentInstr* push_type_args = NULL; | 
| 945   if (type.IsInstantiated()) { | 952   if (type.IsInstantiated()) { | 
| 946     push_instantiator = PushArgument(BuildNullValue()); | 953     push_instantiator = PushArgument(BuildNullValue()); | 
| 947     push_type_args = PushArgument(BuildNullValue()); | 954     push_type_args = PushArgument(BuildNullValue()); | 
| 948   } else { | 955   } else { | 
| 949     BuildTypecheckPushArguments(node->token_pos(), | 956     BuildTypecheckPushArguments(node->token_pos(), | 
| 950                                 &push_instantiator, | 957                                 &push_instantiator, | 
| 951                                 &push_type_args); | 958                                 &push_type_args); | 
| 952   } | 959   } | 
| 953   const String& name = String::ZoneHandle(Symbols::New("_instanceOf")); |  | 
| 954   ZoneGrowableArray<PushArgumentInstr*>* arguments = | 960   ZoneGrowableArray<PushArgumentInstr*>* arguments = | 
| 955       new ZoneGrowableArray<PushArgumentInstr*>(5); | 961       new ZoneGrowableArray<PushArgumentInstr*>(5); | 
| 956   arguments->Add(push_left); | 962   arguments->Add(push_left); | 
| 957   arguments->Add(push_instantiator); | 963   arguments->Add(push_instantiator); | 
| 958   arguments->Add(push_type_args); | 964   arguments->Add(push_type_args); | 
| 959   ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 965   ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 
| 960   Value* type_arg = Bind( | 966   Value* type_arg = Bind( | 
| 961       new ConstantInstr(node->right()->AsTypeNode()->type())); | 967       new ConstantInstr(node->right()->AsTypeNode()->type())); | 
| 962   arguments->Add(PushArgument(type_arg)); | 968   arguments->Add(PushArgument(type_arg)); | 
| 963   const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() : | 969   const Bool& negate = (node->kind() == Token::kISNOT) ? Bool::True() : | 
| 964                                                          Bool::False(); | 970                                                          Bool::False(); | 
| 965   Value* negate_arg = Bind(new ConstantInstr(negate)); | 971   Value* negate_arg = Bind(new ConstantInstr(negate)); | 
| 966   arguments->Add(PushArgument(negate_arg)); | 972   arguments->Add(PushArgument(negate_arg)); | 
| 967   const intptr_t kNumArgsChecked = 1; | 973   const intptr_t kNumArgsChecked = 1; | 
| 968   InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 974   InstanceCallInstr* call = new InstanceCallInstr( | 
| 969                                                   name, | 975       node->token_pos(), | 
| 970                                                   node->kind(), | 976       PrivateCoreLibName(Symbols::_instanceOf()), | 
| 971                                                   arguments, | 977       node->kind(), | 
| 972                                                   Array::ZoneHandle(), | 978       arguments, | 
| 973                                                   kNumArgsChecked); | 979       Array::ZoneHandle(), | 
|  | 980       kNumArgsChecked); | 
| 974   ReturnDefinition(call); | 981   ReturnDefinition(call); | 
| 975 } | 982 } | 
| 976 | 983 | 
| 977 | 984 | 
| 978 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 985 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 
| 979   ASSERT(Token::IsTypeCastOperator(node->kind())); | 986   ASSERT(Token::IsTypeCastOperator(node->kind())); | 
| 980   const AbstractType& type = node->right()->AsTypeNode()->type(); | 987   const AbstractType& type = node->right()->AsTypeNode()->type(); | 
| 981   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. | 988   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. | 
| 982   ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 989   ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); | 
| 983   node->left()->Visit(&for_value); | 990   node->left()->Visit(&for_value); | 
| (...skipping 1888 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2872     AstNode* receiver, | 2879     AstNode* receiver, | 
| 2873     const String& method_name, | 2880     const String& method_name, | 
| 2874     ArgumentListNode* method_arguments) { | 2881     ArgumentListNode* method_arguments) { | 
| 2875   // Build the graph to allocate an InvocationMirror object by calling | 2882   // Build the graph to allocate an InvocationMirror object by calling | 
| 2876   // the static allocation method. | 2883   // the static allocation method. | 
| 2877   const Library& corelib = Library::Handle(Library::CoreLibrary()); | 2884   const Library& corelib = Library::Handle(Library::CoreLibrary()); | 
| 2878   const Class& mirror_class = Class::Handle( | 2885   const Class& mirror_class = Class::Handle( | 
| 2879       corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); | 2886       corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); | 
| 2880   ASSERT(!mirror_class.IsNull()); | 2887   ASSERT(!mirror_class.IsNull()); | 
| 2881   const Function& allocation_function = Function::ZoneHandle( | 2888   const Function& allocation_function = Function::ZoneHandle( | 
| 2882       Resolver::ResolveStaticByName(mirror_class, | 2889       Resolver::ResolveStaticByName( | 
| 2883                                     Symbols::AllocateInvocationMirror(), | 2890           mirror_class, | 
| 2884                                     Resolver::kIsQualified)); | 2891           PrivateCoreLibName(Symbols::AllocateInvocationMirror()), | 
|  | 2892           Resolver::kIsQualified)); | 
| 2885   ASSERT(!allocation_function.IsNull()); | 2893   ASSERT(!allocation_function.IsNull()); | 
| 2886 | 2894 | 
| 2887   // Evaluate the receiver before the arguments. This will be used | 2895   // Evaluate the receiver before the arguments. This will be used | 
| 2888   // as an argument to the noSuchMethod call. | 2896   // as an argument to the noSuchMethod call. | 
| 2889   ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 2897   ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); | 
| 2890   receiver->Visit(&for_receiver); | 2898   receiver->Visit(&for_receiver); | 
| 2891   Append(for_receiver); | 2899   Append(for_receiver); | 
| 2892   PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2900   PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 
| 2893 | 2901 | 
| 2894   // Allocate the arguments and pass them into the construction | 2902   // Allocate the arguments and pass them into the construction | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2968   Value* existing_argument_names_value = | 2976   Value* existing_argument_names_value = | 
| 2969       Bind(new ConstantInstr(Array::ZoneHandle())); | 2977       Bind(new ConstantInstr(Array::ZoneHandle())); | 
| 2970   arguments->Add(PushArgument(existing_argument_names_value)); | 2978   arguments->Add(PushArgument(existing_argument_names_value)); | 
| 2971   // Resolve and call NoSuchMethodError._throwNew. | 2979   // Resolve and call NoSuchMethodError._throwNew. | 
| 2972   const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 2980   const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 
| 2973   const Class& cls = Class::Handle( | 2981   const Class& cls = Class::Handle( | 
| 2974       core_lib.LookupClass(Symbols::NoSuchMethodError())); | 2982       core_lib.LookupClass(Symbols::NoSuchMethodError())); | 
| 2975   ASSERT(!cls.IsNull()); | 2983   ASSERT(!cls.IsNull()); | 
| 2976   const Function& func = Function::ZoneHandle( | 2984   const Function& func = Function::ZoneHandle( | 
| 2977       Resolver::ResolveStatic(cls, | 2985       Resolver::ResolveStatic(cls, | 
| 2978                               Symbols::ThrowNew(), | 2986                               PrivateCoreLibName(Symbols::ThrowNew()), | 
| 2979                               arguments->length(), | 2987                               arguments->length(), | 
| 2980                               Array::ZoneHandle(), | 2988                               Array::ZoneHandle(), | 
| 2981                               Resolver::kIsQualified)); | 2989                               Resolver::kIsQualified)); | 
| 2982   ASSERT(!func.IsNull()); | 2990   ASSERT(!func.IsNull()); | 
| 2983   return new StaticCallInstr(token_pos, | 2991   return new StaticCallInstr(token_pos, | 
| 2984                              func, | 2992                              func, | 
| 2985                              Array::ZoneHandle(),  // No names. | 2993                              Array::ZoneHandle(),  // No names. | 
| 2986                              arguments); | 2994                              arguments); | 
| 2987 } | 2995 } | 
| 2988 | 2996 | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3095   intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3103   intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 
| 3096   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3104   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 
| 3097   OS::SNPrint(chars, len, kFormat, function_name, reason); | 3105   OS::SNPrint(chars, len, kFormat, function_name, reason); | 
| 3098   const Error& error = Error::Handle( | 3106   const Error& error = Error::Handle( | 
| 3099       LanguageError::New(String::Handle(String::New(chars)))); | 3107       LanguageError::New(String::Handle(String::New(chars)))); | 
| 3100   Isolate::Current()->long_jump_base()->Jump(1, error); | 3108   Isolate::Current()->long_jump_base()->Jump(1, error); | 
| 3101 } | 3109 } | 
| 3102 | 3110 | 
| 3103 | 3111 | 
| 3104 }  // namespace dart | 3112 }  // namespace dart | 
| OLD | NEW | 
|---|