| 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/bit_vector.h" |     8 #include "vm/bit_vector.h" | 
|     9 #include "vm/code_descriptors.h" |     9 #include "vm/code_descriptors.h" | 
|    10 #include "vm/dart_entry.h" |    10 #include "vm/dart_entry.h" | 
|    11 #include "vm/flags.h" |    11 #include "vm/flags.h" | 
|    12 #include "vm/il_printer.h" |    12 #include "vm/il_printer.h" | 
|    13 #include "vm/intermediate_language.h" |    13 #include "vm/intermediate_language.h" | 
|    14 #include "vm/longjump.h" |    14 #include "vm/longjump.h" | 
|    15 #include "vm/object_store.h" |    15 #include "vm/object_store.h" | 
|    16 #include "vm/os.h" |    16 #include "vm/os.h" | 
|    17 #include "vm/parser.h" |    17 #include "vm/parser.h" | 
|    18 #include "vm/resolver.h" |    18 #include "vm/resolver.h" | 
|    19 #include "vm/stub_code.h" |    19 #include "vm/stub_code.h" | 
 |    20 #include "vm/symbols.h" | 
|    20  |    21  | 
|    21 namespace dart { |    22 namespace dart { | 
|    22  |    23  | 
|    23 DEFINE_FLAG(bool, eliminate_type_checks, true, |    24 DEFINE_FLAG(bool, eliminate_type_checks, true, | 
|    24             "Eliminate type checks when allowed by static type analysis."); |    25             "Eliminate type checks when allowed by static type analysis."); | 
|    25 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); |    26 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); | 
|    26 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); |    27 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); | 
|    27 DEFINE_FLAG(bool, trace_type_check_elimination, false, |    28 DEFINE_FLAG(bool, trace_type_check_elimination, false, | 
|    28             "Trace type check elimination at compile time."); |    29             "Trace type check elimination at compile time."); | 
|    29 #if defined(TARGET_ARCH_X64) |    30 #if defined(TARGET_ARCH_X64) | 
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   349         (kind == RawFunction::kImplicitGetter) || |   350         (kind == RawFunction::kImplicitGetter) || | 
|   350         (kind == RawFunction::kConstImplicitGetter); |   351         (kind == RawFunction::kConstImplicitGetter); | 
|   351     const bool is_static = owner()->parsed_function().function().is_static(); |   352     const bool is_static = owner()->parsed_function().function().is_static(); | 
|   352     // Implicit getters do not need a type check at return, unless they compute |   353     // Implicit getters do not need a type check at return, unless they compute | 
|   353     // the initial value of a static field. |   354     // the initial value of a static field. | 
|   354     if (is_static || !is_implicit_getter) { |   355     if (is_static || !is_implicit_getter) { | 
|   355       const AbstractType& dst_type = |   356       const AbstractType& dst_type = | 
|   356           AbstractType::ZoneHandle( |   357           AbstractType::ZoneHandle( | 
|   357               owner()->parsed_function().function().result_type()); |   358               owner()->parsed_function().function().result_type()); | 
|   358       const String& dst_name = |   359       const String& dst_name = | 
|   359           String::ZoneHandle(String::NewSymbol("function result")); |   360           String::ZoneHandle(Symbols::New("function result")); | 
|   360       return_value = BuildAssignableValue(node->value()->token_pos(), |   361       return_value = BuildAssignableValue(node->value()->token_pos(), | 
|   361                                           return_value, |   362                                           return_value, | 
|   362                                           dst_type, |   363                                           dst_type, | 
|   363                                           dst_name); |   364                                           dst_name); | 
|   364     } |   365     } | 
|   365   } |   366   } | 
|   366  |   367  | 
|   367   intptr_t current_context_level = owner()->context_level(); |   368   intptr_t current_context_level = owner()->context_level(); | 
|   368   ASSERT(current_context_level >= 0); |   369   ASSERT(current_context_level >= 0); | 
|   369   if (owner()->parsed_function().saved_context_var() != NULL) { |   370   if (owner()->parsed_function().saved_context_var() != NULL) { | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   556   } |   557   } | 
|   557   ValueGraphVisitor for_left_value(owner(), temp_index()); |   558   ValueGraphVisitor for_left_value(owner(), temp_index()); | 
|   558   node->left()->Visit(&for_left_value); |   559   node->left()->Visit(&for_left_value); | 
|   559   Append(for_left_value); |   560   Append(for_left_value); | 
|   560   ValueGraphVisitor for_right_value(owner(), temp_index()); |   561   ValueGraphVisitor for_right_value(owner(), temp_index()); | 
|   561   node->right()->Visit(&for_right_value); |   562   node->right()->Visit(&for_right_value); | 
|   562   Append(for_right_value); |   563   Append(for_right_value); | 
|   563   ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |   564   ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 
|   564   arguments->Add(for_left_value.value()); |   565   arguments->Add(for_left_value.value()); | 
|   565   arguments->Add(for_right_value.value()); |   566   arguments->Add(for_right_value.value()); | 
|   566   const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); |   567   const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 
|   567   InstanceCallComp* call = new InstanceCallComp(node->token_pos(), |   568   InstanceCallComp* call = new InstanceCallComp(node->token_pos(), | 
|   568                                                 owner()->try_index(), |   569                                                 owner()->try_index(), | 
|   569                                                 name, |   570                                                 name, | 
|   570                                                 node->kind(), |   571                                                 node->kind(), | 
|   571                                                 arguments, |   572                                                 arguments, | 
|   572                                                 Array::ZoneHandle(), |   573                                                 Array::ZoneHandle(), | 
|   573                                                 2); |   574                                                 2); | 
|   574   ReturnComputation(call); |   575   ReturnComputation(call); | 
|   575 } |   576 } | 
|   576  |   577  | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   717  |   718  | 
|   718  |   719  | 
|   719 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |   720 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 
|   720   ASSERT(Token::IsTypeCastOperator(node->kind())); |   721   ASSERT(Token::IsTypeCastOperator(node->kind())); | 
|   721   const AbstractType& type = node->right()->AsTypeNode()->type(); |   722   const AbstractType& type = node->right()->AsTypeNode()->type(); | 
|   722   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. |   723   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. | 
|   723   ValueGraphVisitor for_value(owner(), temp_index()); |   724   ValueGraphVisitor for_value(owner(), temp_index()); | 
|   724   node->left()->Visit(&for_value); |   725   node->left()->Visit(&for_value); | 
|   725   Append(for_value); |   726   Append(for_value); | 
|   726   const String& dst_name = String::ZoneHandle( |   727   const String& dst_name = String::ZoneHandle( | 
|   727       String::NewSymbol(Exceptions::kCastExceptionDstName)); |   728       Symbols::New(Exceptions::kCastExceptionDstName)); | 
|   728   if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |   729   if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 
|   729     Do(BuildAssertAssignable( |   730     Do(BuildAssertAssignable( | 
|   730         node->token_pos(), for_value.value(), type, dst_name)); |   731         node->token_pos(), for_value.value(), type, dst_name)); | 
|   731   } |   732   } | 
|   732 } |   733 } | 
|   733  |   734  | 
|   734  |   735  | 
|   735 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |   736 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 
|   736   ASSERT(Token::IsTypeTestOperator(node->kind())); |   737   ASSERT(Token::IsTypeTestOperator(node->kind())); | 
|   737   const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |   738   const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   806  |   807  | 
|   807  |   808  | 
|   808 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |   809 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 
|   809   ASSERT(Token::IsTypeCastOperator(node->kind())); |   810   ASSERT(Token::IsTypeCastOperator(node->kind())); | 
|   810   const AbstractType& type = node->right()->AsTypeNode()->type(); |   811   const AbstractType& type = node->right()->AsTypeNode()->type(); | 
|   811   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. |   812   ASSERT(type.IsFinalized());  // The type in a type cast may be malformed. | 
|   812   ValueGraphVisitor for_value(owner(), temp_index()); |   813   ValueGraphVisitor for_value(owner(), temp_index()); | 
|   813   node->left()->Visit(&for_value); |   814   node->left()->Visit(&for_value); | 
|   814   Append(for_value); |   815   Append(for_value); | 
|   815   const String& dst_name = String::ZoneHandle( |   816   const String& dst_name = String::ZoneHandle( | 
|   816       String::NewSymbol(Exceptions::kCastExceptionDstName)); |   817       Symbols::New(Exceptions::kCastExceptionDstName)); | 
|   817   ReturnValue(BuildAssignableValue(node->token_pos(), |   818   ReturnValue(BuildAssignableValue(node->token_pos(), | 
|   818                                    for_value.value(), |   819                                    for_value.value(), | 
|   819                                    type, |   820                                    type, | 
|   820                                    dst_name)); |   821                                    dst_name)); | 
|   821 } |   822 } | 
|   822  |   823  | 
|   823  |   824  | 
|   824 // <Expression> :: Comparison { kind:  Token::Kind |   825 // <Expression> :: Comparison { kind:  Token::Kind | 
|   825 //                              left:  <Expression> |   826 //                              left:  <Expression> | 
|   826 //                              right: <Expression> } |   827 //                              right: <Expression> } | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   911   } |   912   } | 
|   912   ValueGraphVisitor for_value(owner(), temp_index()); |   913   ValueGraphVisitor for_value(owner(), temp_index()); | 
|   913   node->operand()->Visit(&for_value); |   914   node->operand()->Visit(&for_value); | 
|   914   Append(for_value); |   915   Append(for_value); | 
|   915   ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |   916   ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 
|   916   arguments->Add(for_value.value()); |   917   arguments->Add(for_value.value()); | 
|   917   Token::Kind token_kind = |   918   Token::Kind token_kind = | 
|   918       (node->kind() == Token::kSUB) ? Token::kNEGATE : node->kind(); |   919       (node->kind() == Token::kSUB) ? Token::kNEGATE : node->kind(); | 
|   919  |   920  | 
|   920   const String& name = |   921   const String& name = | 
|   921       String::ZoneHandle(String::NewSymbol(Token::Str(token_kind))); |   922       String::ZoneHandle(Symbols::New(Token::Str(token_kind))); | 
|   922   InstanceCallComp* call = new InstanceCallComp( |   923   InstanceCallComp* call = new InstanceCallComp( | 
|   923       node->token_pos(), owner()->try_index(), name, token_kind, |   924       node->token_pos(), owner()->try_index(), name, token_kind, | 
|   924       arguments, Array::ZoneHandle(), 1); |   925       arguments, Array::ZoneHandle(), 1); | 
|   925   ReturnComputation(call); |   926   ReturnComputation(call); | 
|   926 } |   927 } | 
|   927  |   928  | 
|   928  |   929  | 
|   929 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |   930 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 
|   930   TestGraphVisitor for_test(owner(), |   931   TestGraphVisitor for_test(owner(), | 
|   931                             temp_index(), |   932                             temp_index(), | 
| (...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2066       const Function& function = owner()->parsed_function().function(); |  2067       const Function& function = owner()->parsed_function().function(); | 
|  2067       const int num_params = function.NumberOfParameters(); |  2068       const int num_params = function.NumberOfParameters(); | 
|  2068       int param_frame_index = (num_params == function.num_fixed_parameters()) ? |  2069       int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 
|  2069           (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; |  2070           (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; | 
|  2070       for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |  2071       for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 
|  2071         const LocalVariable& parameter = *scope->VariableAt(pos); |  2072         const LocalVariable& parameter = *scope->VariableAt(pos); | 
|  2072         ASSERT(parameter.owner() == scope); |  2073         ASSERT(parameter.owner() == scope); | 
|  2073         if (parameter.is_captured()) { |  2074         if (parameter.is_captured()) { | 
|  2074           // Create a temporary local describing the original position. |  2075           // Create a temporary local describing the original position. | 
|  2075           const String& temp_name = String::ZoneHandle(String::Concat( |  2076           const String& temp_name = String::ZoneHandle(String::Concat( | 
|  2076               parameter.name(), String::Handle(String::NewSymbol("-orig")))); |  2077               parameter.name(), String::Handle(Symbols::New("-orig")))); | 
|  2077           LocalVariable* temp_local = new LocalVariable( |  2078           LocalVariable* temp_local = new LocalVariable( | 
|  2078               0,  // Token index. |  2079               0,  // Token index. | 
|  2079               temp_name, |  2080               temp_name, | 
|  2080               Type::ZoneHandle(Type::DynamicType()));  // Type. |  2081               Type::ZoneHandle(Type::DynamicType()));  // Type. | 
|  2081           temp_local->set_index(param_frame_index); |  2082           temp_local->set_index(param_frame_index); | 
|  2082  |  2083  | 
|  2083           // Copy parameter from local frame to current context. |  2084           // Copy parameter from local frame to current context. | 
|  2084           Value* load = Bind(BuildLoadLocal(*temp_local)); |  2085           Value* load = Bind(BuildLoadLocal(*temp_local)); | 
|  2085           Do(BuildStoreLocal(parameter, load)); |  2086           Do(BuildStoreLocal(parameter, load)); | 
|  2086           // Write NULL to the source location to detect buggy accesses and |  2087           // Write NULL to the source location to detect buggy accesses and | 
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2700   char* chars = reinterpret_cast<char*>( |  2701   char* chars = reinterpret_cast<char*>( | 
|  2701       Isolate::Current()->current_zone()->Allocate(len)); |  2702       Isolate::Current()->current_zone()->Allocate(len)); | 
|  2702   OS::SNPrint(chars, len, kFormat, function_name, reason); |  2703   OS::SNPrint(chars, len, kFormat, function_name, reason); | 
|  2703   const Error& error = Error::Handle( |  2704   const Error& error = Error::Handle( | 
|  2704       LanguageError::New(String::Handle(String::New(chars)))); |  2705       LanguageError::New(String::Handle(String::New(chars)))); | 
|  2705   Isolate::Current()->long_jump_base()->Jump(1, error); |  2706   Isolate::Current()->long_jump_base()->Jump(1, error); | 
|  2706 } |  2707 } | 
|  2707  |  2708  | 
|  2708  |  2709  | 
|  2709 }  // namespace dart |  2710 }  // namespace dart | 
| OLD | NEW |