| 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 |