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 |