| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 DECLARE_FLAG(int, optimization_counter_threshold); | 43 DECLARE_FLAG(int, optimization_counter_threshold); |
| 44 DECLARE_FLAG(bool, profile_vm); | 44 DECLARE_FLAG(bool, profile_vm); |
| 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 46 DECLARE_FLAG(bool, use_field_guards); | 46 DECLARE_FLAG(bool, use_field_guards); |
| 47 | 47 |
| 48 // Quick access to the locally defined zone() method. | 48 // Quick access to the locally defined zone() method. |
| 49 #define Z (zone()) | 49 #define Z (zone()) |
| 50 | 50 |
| 51 // Quick synthetic token position. | 51 // Quick synthetic token position. |
| 52 #define ST(token_pos) Token::ToSynthetic(token_pos) | 52 #define ST(token_pos) TokenDescriptor::ToSynthetic(token_pos) |
| 53 | 53 |
| 54 // TODO(srdjan): Allow compiler to add constants as they are encountered in | 54 // TODO(srdjan): Allow compiler to add constants as they are encountered in |
| 55 // the compilation. | 55 // the compilation. |
| 56 const double kCommonDoubleConstants[] = | 56 const double kCommonDoubleConstants[] = |
| 57 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, | 57 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, |
| 58 10.0, 20.0, 30.0, 64.0, 255.0, NAN, | 58 10.0, 20.0, 30.0, 64.0, 255.0, NAN, |
| 59 // From dart:math | 59 // From dart:math |
| 60 2.718281828459045, 2.302585092994046, 0.6931471805599453, | 60 2.718281828459045, 2.302585092994046, 0.6931471805599453, |
| 61 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, | 61 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, |
| 62 0.7071067811865476, 1.4142135623730951}; | 62 0.7071067811865476, 1.4142135623730951}; |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 TargetEntryInstr* false_block = | 553 TargetEntryInstr* false_block = |
| 554 new(Z) TargetEntryInstr(caller_graph_->allocate_block_id(), | 554 new(Z) TargetEntryInstr(caller_graph_->allocate_block_id(), |
| 555 call_block->try_index()); | 555 call_block->try_index()); |
| 556 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); | 556 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); |
| 557 false_block->LinkTo(call_->next()); | 557 false_block->LinkTo(call_->next()); |
| 558 call_block->ReplaceAsPredecessorWith(false_block); | 558 call_block->ReplaceAsPredecessorWith(false_block); |
| 559 | 559 |
| 560 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); | 560 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); |
| 561 BranchInstr* branch = | 561 BranchInstr* branch = |
| 562 new(Z) BranchInstr( | 562 new(Z) BranchInstr( |
| 563 new(Z) StrictCompareInstr(call_block->start_pos(), | 563 new(Z) StrictCompareInstr(TokenDescriptor(call_block->start_pos()), |
| 564 Token::kEQ_STRICT, | 564 Token::kEQ_STRICT, |
| 565 new(Z) Value(true_const), | 565 new(Z) Value(true_const), |
| 566 new(Z) Value(true_const), | 566 new(Z) Value(true_const), |
| 567 false)); // No number check. | 567 false)); // No number check. |
| 568 branch->InheritDeoptTarget(zone(), call_); | 568 branch->InheritDeoptTarget(zone(), call_); |
| 569 *branch->true_successor_address() = callee_entry; | 569 *branch->true_successor_address() = callee_entry; |
| 570 *branch->false_successor_address() = false_block; | 570 *branch->false_successor_address() = false_block; |
| 571 | 571 |
| 572 call_->previous()->AppendInstruction(branch); | 572 call_->previous()->AppendInstruction(branch); |
| 573 call_block->set_last_instruction(branch); | 573 call_block->set_last_instruction(branch); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 owner()->add_args_pushed(-instruction->ArgumentCount()); | 700 owner()->add_args_pushed(-instruction->ArgumentCount()); |
| 701 if (is_empty()) { | 701 if (is_empty()) { |
| 702 entry_ = exit_ = instruction; | 702 entry_ = exit_ = instruction; |
| 703 } else { | 703 } else { |
| 704 exit()->LinkTo(instruction); | 704 exit()->LinkTo(instruction); |
| 705 exit_ = instruction; | 705 exit_ = instruction; |
| 706 } | 706 } |
| 707 } | 707 } |
| 708 | 708 |
| 709 | 709 |
| 710 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { | 710 void EffectGraphVisitor::AddReturnExit(TokenDescriptor token_pos, |
| 711 Value* value) { |
| 711 ASSERT(is_open()); | 712 ASSERT(is_open()); |
| 712 ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value); | 713 ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value); |
| 713 AddInstruction(return_instr); | 714 AddInstruction(return_instr); |
| 714 InlineExitCollector* exit_collector = owner()->exit_collector(); | 715 InlineExitCollector* exit_collector = owner()->exit_collector(); |
| 715 if (exit_collector != NULL) { | 716 if (exit_collector != NULL) { |
| 716 exit_collector->AddExit(return_instr); | 717 exit_collector->AddExit(return_instr); |
| 717 } | 718 } |
| 718 CloseFragment(); | 719 CloseFragment(); |
| 719 } | 720 } |
| 720 | 721 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 JoinEntryInstr* join = | 775 JoinEntryInstr* join = |
| 775 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 776 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 776 true_exit->Goto(join); | 777 true_exit->Goto(join); |
| 777 false_exit->Goto(join); | 778 false_exit->Goto(join); |
| 778 exit_ = join; | 779 exit_ = join; |
| 779 } | 780 } |
| 780 } | 781 } |
| 781 | 782 |
| 782 | 783 |
| 783 void EffectGraphVisitor::TieLoop( | 784 void EffectGraphVisitor::TieLoop( |
| 784 intptr_t token_pos, | 785 TokenDescriptor token_pos, |
| 785 const TestGraphVisitor& test_fragment, | 786 const TestGraphVisitor& test_fragment, |
| 786 const EffectGraphVisitor& body_fragment, | 787 const EffectGraphVisitor& body_fragment, |
| 787 const EffectGraphVisitor& test_preamble_fragment) { | 788 const EffectGraphVisitor& test_preamble_fragment) { |
| 788 // We have: a test graph fragment with zero, one, or two available exits; | 789 // We have: a test graph fragment with zero, one, or two available exits; |
| 789 // and an effect graph fragment with zero or one available exits. We want | 790 // and an effect graph fragment with zero or one available exits. We want |
| 790 // to append the 'while loop' consisting of the test graph fragment as | 791 // to append the 'while loop' consisting of the test graph fragment as |
| 791 // condition and the effect graph fragment as body. | 792 // condition and the effect graph fragment as body. |
| 792 ASSERT(is_open()); | 793 ASSERT(is_open()); |
| 793 | 794 |
| 794 // 1. Connect the body to the test if it is reachable, and if so record | 795 // 1. Connect the body to the test if it is reachable, and if so record |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { | 827 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { |
| 827 owner_->add_args_pushed(1); | 828 owner_->add_args_pushed(1); |
| 828 PushArgumentInstr* result = new(Z) PushArgumentInstr(value); | 829 PushArgumentInstr* result = new(Z) PushArgumentInstr(value); |
| 829 AddInstruction(result); | 830 AddInstruction(result); |
| 830 return result; | 831 return result; |
| 831 } | 832 } |
| 832 | 833 |
| 833 | 834 |
| 834 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, | 835 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, |
| 835 Value* value, | 836 Value* value, |
| 836 intptr_t token_pos) { | 837 TokenDescriptor token_pos) { |
| 837 ASSERT(!local.is_captured()); | 838 ASSERT(!local.is_captured()); |
| 838 ASSERT(!Token::IsClassifying(token_pos)); | 839 ASSERT(!TokenDescriptor(token_pos).IsClassifying()); |
| 839 return new(Z) StoreLocalInstr(local, value, ST(token_pos)); | 840 return new(Z) StoreLocalInstr(local, value, ST(token_pos)); |
| 840 } | 841 } |
| 841 | 842 |
| 842 | 843 |
| 843 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value, | 844 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value, |
| 844 intptr_t token_pos) { | 845 TokenDescriptor token_pos) { |
| 845 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), | 846 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), |
| 846 value, | 847 value, |
| 847 token_pos); | 848 token_pos); |
| 848 } | 849 } |
| 849 | 850 |
| 850 | 851 |
| 851 Definition* EffectGraphVisitor::BuildLoadExprTemp(intptr_t token_pos) { | 852 Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenDescriptor token_pos) { |
| 852 ASSERT(!Token::IsClassifying(token_pos)); | 853 ASSERT(!TokenDescriptor(token_pos).IsClassifying()); |
| 853 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), | 854 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), |
| 854 token_pos); | 855 token_pos); |
| 855 } | 856 } |
| 856 | 857 |
| 857 | 858 |
| 858 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 859 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
| 859 Value* value, | 860 Value* value, |
| 860 intptr_t token_pos) { | 861 TokenDescriptor token_pos) { |
| 861 if (local.is_captured()) { | 862 if (local.is_captured()) { |
| 862 LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos); | 863 LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos); |
| 863 intptr_t delta = | 864 intptr_t delta = |
| 864 owner()->context_level() - local.owner()->context_level(); | 865 owner()->context_level() - local.owner()->context_level(); |
| 865 ASSERT(delta >= 0); | 866 ASSERT(delta >= 0); |
| 866 Value* context = Bind(BuildCurrentContext(token_pos)); | 867 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 867 while (delta-- > 0) { | 868 while (delta-- > 0) { |
| 868 context = Bind(new(Z) LoadFieldInstr( | 869 context = Bind(new(Z) LoadFieldInstr( |
| 869 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 870 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 870 token_pos)); | 871 token_pos)); |
| 871 } | 872 } |
| 872 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); | 873 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); |
| 873 StoreInstanceFieldInstr* store = | 874 StoreInstanceFieldInstr* store = |
| 874 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 875 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 875 context, | 876 context, |
| 876 tmp_val, | 877 tmp_val, |
| 877 kEmitStoreBarrier, | 878 kEmitStoreBarrier, |
| 878 token_pos); | 879 token_pos); |
| 879 Do(store); | 880 Do(store); |
| 880 return ExitTempLocalScope(tmp_var, token_pos); | 881 return ExitTempLocalScope(tmp_var, token_pos); |
| 881 } else { | 882 } else { |
| 882 return new(Z) StoreLocalInstr(local, value, token_pos); | 883 return new(Z) StoreLocalInstr(local, value, token_pos); |
| 883 } | 884 } |
| 884 } | 885 } |
| 885 | 886 |
| 886 | 887 |
| 887 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, | 888 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, |
| 888 intptr_t token_pos) { | 889 TokenDescriptor token_pos) { |
| 889 if (local.IsConst()) { | 890 if (local.IsConst()) { |
| 890 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); | 891 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); |
| 891 } else if (local.is_captured()) { | 892 } else if (local.is_captured()) { |
| 892 intptr_t delta = | 893 intptr_t delta = |
| 893 owner()->context_level() - local.owner()->context_level(); | 894 owner()->context_level() - local.owner()->context_level(); |
| 894 ASSERT(delta >= 0); | 895 ASSERT(delta >= 0); |
| 895 Value* context = Bind(BuildCurrentContext(token_pos)); | 896 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 896 while (delta-- > 0) { | 897 while (delta-- > 0) { |
| 897 context = Bind(new(Z) LoadFieldInstr( | 898 context = Bind(new(Z) LoadFieldInstr( |
| 898 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 899 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 899 token_pos)); | 900 token_pos)); |
| 900 } | 901 } |
| 901 return new(Z) LoadFieldInstr(context, | 902 return new(Z) LoadFieldInstr(context, |
| 902 Context::variable_offset(local.index()), | 903 Context::variable_offset(local.index()), |
| 903 local.type(), | 904 local.type(), |
| 904 token_pos); | 905 token_pos); |
| 905 } else { | 906 } else { |
| 906 return new(Z) LoadLocalInstr(local, token_pos); | 907 return new(Z) LoadLocalInstr(local, token_pos); |
| 907 } | 908 } |
| 908 } | 909 } |
| 909 | 910 |
| 910 | 911 |
| 911 // Stores current context into the 'variable' | 912 // Stores current context into the 'variable' |
| 912 void EffectGraphVisitor::BuildSaveContext( | 913 void EffectGraphVisitor::BuildSaveContext( |
| 913 const LocalVariable& variable, | 914 const LocalVariable& variable, |
| 914 intptr_t token_pos) { | 915 TokenDescriptor token_pos) { |
| 915 ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos)); | 916 ASSERT(TokenDescriptor(token_pos).IsSynthetic() || |
| 917 TokenDescriptor(token_pos).IsNoSource()); |
| 916 Value* context = Bind(BuildCurrentContext(token_pos)); | 918 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 917 Do(BuildStoreLocal(variable, context, token_pos)); | 919 Do(BuildStoreLocal(variable, context, token_pos)); |
| 918 } | 920 } |
| 919 | 921 |
| 920 | 922 |
| 921 // Loads context saved in 'context_variable' into the current context. | 923 // Loads context saved in 'context_variable' into the current context. |
| 922 void EffectGraphVisitor::BuildRestoreContext( | 924 void EffectGraphVisitor::BuildRestoreContext( |
| 923 const LocalVariable& variable, | 925 const LocalVariable& variable, |
| 924 intptr_t token_pos) { | 926 TokenDescriptor token_pos) { |
| 925 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); | 927 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); |
| 926 Do(BuildStoreContext(load_saved_context, token_pos)); | 928 Do(BuildStoreContext(load_saved_context, token_pos)); |
| 927 } | 929 } |
| 928 | 930 |
| 929 | 931 |
| 930 Definition* EffectGraphVisitor::BuildStoreContext( | 932 Definition* EffectGraphVisitor::BuildStoreContext( |
| 931 Value* value, intptr_t token_pos) { | 933 Value* value, TokenDescriptor token_pos) { |
| 932 return new(Z) StoreLocalInstr( | 934 return new(Z) StoreLocalInstr( |
| 933 *owner()->parsed_function().current_context_var(), value, token_pos); | 935 *owner()->parsed_function().current_context_var(), value, token_pos); |
| 934 } | 936 } |
| 935 | 937 |
| 936 | 938 |
| 937 Definition* EffectGraphVisitor::BuildCurrentContext(intptr_t token_pos) { | 939 Definition* EffectGraphVisitor::BuildCurrentContext(TokenDescriptor token_pos) { |
| 938 return new(Z) LoadLocalInstr( | 940 return new(Z) LoadLocalInstr( |
| 939 *owner()->parsed_function().current_context_var(), | 941 *owner()->parsed_function().current_context_var(), |
| 940 token_pos); | 942 token_pos); |
| 941 } | 943 } |
| 942 | 944 |
| 943 | 945 |
| 944 void TestGraphVisitor::ConnectBranchesTo( | 946 void TestGraphVisitor::ConnectBranchesTo( |
| 945 const GrowableArray<TargetEntryInstr**>& branches, | 947 const GrowableArray<TargetEntryInstr**>& branches, |
| 946 JoinEntryInstr* join) const { | 948 JoinEntryInstr* join) const { |
| 947 ASSERT(!branches.is_empty()); | 949 ASSERT(!branches.is_empty()); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 Append(for_value); | 1127 Append(for_value); |
| 1126 Value* return_value = for_value.value(); | 1128 Value* return_value = for_value.value(); |
| 1127 | 1129 |
| 1128 // Call to stub that checks whether the debugger is in single | 1130 // Call to stub that checks whether the debugger is in single |
| 1129 // step mode. This call must happen before the contexts are | 1131 // step mode. This call must happen before the contexts are |
| 1130 // unchained so that captured variables can be inspected. | 1132 // unchained so that captured variables can be inspected. |
| 1131 // No debugger check is done in native functions or for return | 1133 // No debugger check is done in native functions or for return |
| 1132 // statements for which there is no associated source position. | 1134 // statements for which there is no associated source position. |
| 1133 const Function& function = owner()->function(); | 1135 const Function& function = owner()->function(); |
| 1134 if (FLAG_support_debugger && | 1136 if (FLAG_support_debugger && |
| 1135 Token::IsDebugPause(node->token_pos()) && !function.is_native()) { | 1137 TokenDescriptor(node->token_pos()).IsDebugPause() && |
| 1138 !function.is_native()) { |
| 1136 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), | 1139 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), |
| 1137 RawPcDescriptors::kRuntimeCall)); | 1140 RawPcDescriptors::kRuntimeCall)); |
| 1138 } | 1141 } |
| 1139 | 1142 |
| 1140 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); | 1143 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); |
| 1141 | 1144 |
| 1142 if (node->inlined_finally_list_length() > 0) { | 1145 if (node->inlined_finally_list_length() > 0) { |
| 1143 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); | 1146 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); |
| 1144 ASSERT(temp != NULL); | 1147 ASSERT(temp != NULL); |
| 1145 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); | 1148 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1259 node->token_pos(), instantiator_class, NULL); | 1262 node->token_pos(), instantiator_class, NULL); |
| 1260 ReturnDefinition(new(Z) InstantiateTypeInstr( | 1263 ReturnDefinition(new(Z) InstantiateTypeInstr( |
| 1261 node->token_pos(), type, instantiator_class, instantiator_value)); | 1264 node->token_pos(), type, instantiator_class, instantiator_value)); |
| 1262 } | 1265 } |
| 1263 } | 1266 } |
| 1264 | 1267 |
| 1265 | 1268 |
| 1266 // Returns true if the type check can be skipped, for example, if the | 1269 // Returns true if the type check can be skipped, for example, if the |
| 1267 // destination type is dynamic or if the compile type of the value is a subtype | 1270 // destination type is dynamic or if the compile type of the value is a subtype |
| 1268 // of the destination type. | 1271 // of the destination type. |
| 1269 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 1272 bool EffectGraphVisitor::CanSkipTypeCheck(TokenDescriptor token_pos, |
| 1270 Value* value, | 1273 Value* value, |
| 1271 const AbstractType& dst_type, | 1274 const AbstractType& dst_type, |
| 1272 const String& dst_name) { | 1275 const String& dst_name) { |
| 1273 ASSERT(!dst_type.IsNull()); | 1276 ASSERT(!dst_type.IsNull()); |
| 1274 ASSERT(dst_type.IsFinalized()); | 1277 ASSERT(dst_type.IsFinalized()); |
| 1275 | 1278 |
| 1276 // If the destination type is malformed or malbounded, a dynamic type error | 1279 // If the destination type is malformed or malbounded, a dynamic type error |
| 1277 // must be thrown at run time. | 1280 // must be thrown at run time. |
| 1278 if (dst_type.IsMalformedOrMalbounded()) { | 1281 if (dst_type.IsMalformedOrMalbounded()) { |
| 1279 return false; | 1282 return false; |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1500 Token::kILLEGAL, | 1503 Token::kILLEGAL, |
| 1501 arguments, | 1504 arguments, |
| 1502 Object::null_array(), | 1505 Object::null_array(), |
| 1503 kNumArgsChecked, | 1506 kNumArgsChecked, |
| 1504 owner()->ic_data_array()); | 1507 owner()->ic_data_array()); |
| 1505 ReturnDefinition(call); | 1508 ReturnDefinition(call); |
| 1506 } | 1509 } |
| 1507 | 1510 |
| 1508 | 1511 |
| 1509 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1512 void EffectGraphVisitor::BuildTypecheckPushArguments( |
| 1510 intptr_t token_pos, | 1513 TokenDescriptor token_pos, |
| 1511 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1514 PushArgumentInstr** push_instantiator_type_arguments_result) { |
| 1512 const Class& instantiator_class = Class::Handle( | 1515 const Class& instantiator_class = Class::Handle( |
| 1513 Z, owner()->function().Owner()); | 1516 Z, owner()->function().Owner()); |
| 1514 // Since called only when type tested against is not instantiated. | 1517 // Since called only when type tested against is not instantiated. |
| 1515 ASSERT(instantiator_class.IsGeneric()); | 1518 ASSERT(instantiator_class.IsGeneric()); |
| 1516 Value* instantiator_type_arguments = NULL; | 1519 Value* instantiator_type_arguments = NULL; |
| 1517 Value* instantiator = BuildInstantiator(token_pos); | 1520 Value* instantiator = BuildInstantiator(token_pos); |
| 1518 if (instantiator == NULL) { | 1521 if (instantiator == NULL) { |
| 1519 // No instantiator when inside factory. | 1522 // No instantiator when inside factory. |
| 1520 instantiator_type_arguments = | 1523 instantiator_type_arguments = |
| 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1524 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1522 } else { | 1525 } else { |
| 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1526 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1524 token_pos, instantiator_class, instantiator); | 1527 token_pos, instantiator_class, instantiator); |
| 1525 } | 1528 } |
| 1526 *push_instantiator_type_arguments_result = | 1529 *push_instantiator_type_arguments_result = |
| 1527 PushArgument(instantiator_type_arguments); | 1530 PushArgument(instantiator_type_arguments); |
| 1528 } | 1531 } |
| 1529 | 1532 |
| 1530 | 1533 |
| 1531 | 1534 |
| 1532 void EffectGraphVisitor::BuildTypecheckArguments( | 1535 void EffectGraphVisitor::BuildTypecheckArguments( |
| 1533 intptr_t token_pos, | 1536 TokenDescriptor token_pos, |
| 1534 Value** instantiator_type_arguments_result) { | 1537 Value** instantiator_type_arguments_result) { |
| 1535 Value* instantiator = NULL; | 1538 Value* instantiator = NULL; |
| 1536 Value* instantiator_type_arguments = NULL; | 1539 Value* instantiator_type_arguments = NULL; |
| 1537 const Class& instantiator_class = Class::Handle( | 1540 const Class& instantiator_class = Class::Handle( |
| 1538 Z, owner()->function().Owner()); | 1541 Z, owner()->function().Owner()); |
| 1539 // Since called only when type tested against is not instantiated. | 1542 // Since called only when type tested against is not instantiated. |
| 1540 ASSERT(instantiator_class.IsGeneric()); | 1543 ASSERT(instantiator_class.IsGeneric()); |
| 1541 instantiator = BuildInstantiator(token_pos); | 1544 instantiator = BuildInstantiator(token_pos); |
| 1542 if (instantiator == NULL) { | 1545 if (instantiator == NULL) { |
| 1543 // No instantiator when inside factory. | 1546 // No instantiator when inside factory. |
| 1544 instantiator_type_arguments = | 1547 instantiator_type_arguments = |
| 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1548 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1546 } else { | 1549 } else { |
| 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1550 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1548 token_pos, instantiator_class, instantiator); | 1551 token_pos, instantiator_class, instantiator); |
| 1549 } | 1552 } |
| 1550 *instantiator_type_arguments_result = instantiator_type_arguments; | 1553 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 1551 } | 1554 } |
| 1552 | 1555 |
| 1553 | 1556 |
| 1554 Value* EffectGraphVisitor::BuildNullValue(intptr_t token_pos) { | 1557 Value* EffectGraphVisitor::BuildNullValue(TokenDescriptor token_pos) { |
| 1555 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), | 1558 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), |
| 1556 token_pos)); | 1559 token_pos)); |
| 1557 } | 1560 } |
| 1558 | 1561 |
| 1559 | 1562 |
| 1560 // Used for testing incoming arguments. | 1563 // Used for testing incoming arguments. |
| 1561 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 1564 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 1562 intptr_t token_pos, | 1565 TokenDescriptor token_pos, |
| 1563 Value* value, | 1566 Value* value, |
| 1564 const AbstractType& dst_type, | 1567 const AbstractType& dst_type, |
| 1565 const String& dst_name) { | 1568 const String& dst_name) { |
| 1566 // Build the type check computation. | 1569 // Build the type check computation. |
| 1567 Value* instantiator_type_arguments = NULL; | 1570 Value* instantiator_type_arguments = NULL; |
| 1568 if (dst_type.IsInstantiated()) { | 1571 if (dst_type.IsInstantiated()) { |
| 1569 instantiator_type_arguments = BuildNullValue(token_pos); | 1572 instantiator_type_arguments = BuildNullValue(token_pos); |
| 1570 } else { | 1573 } else { |
| 1571 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); | 1574 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); |
| 1572 } | 1575 } |
| 1573 | 1576 |
| 1574 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); | 1577 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); |
| 1575 return new(Z) AssertAssignableInstr(token_pos, | 1578 return new(Z) AssertAssignableInstr(token_pos, |
| 1576 value, | 1579 value, |
| 1577 instantiator_type_arguments, | 1580 instantiator_type_arguments, |
| 1578 dst_type, | 1581 dst_type, |
| 1579 dst_name, | 1582 dst_name, |
| 1580 deopt_id); | 1583 deopt_id); |
| 1581 } | 1584 } |
| 1582 | 1585 |
| 1583 | 1586 |
| 1584 // Used for type casts and to test assignments. | 1587 // Used for type casts and to test assignments. |
| 1585 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 1588 Value* EffectGraphVisitor::BuildAssignableValue(TokenDescriptor token_pos, |
| 1586 Value* value, | 1589 Value* value, |
| 1587 const AbstractType& dst_type, | 1590 const AbstractType& dst_type, |
| 1588 const String& dst_name) { | 1591 const String& dst_name) { |
| 1589 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 1592 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 1590 return value; | 1593 return value; |
| 1591 } | 1594 } |
| 1592 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 1595 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 1593 } | 1596 } |
| 1594 | 1597 |
| 1595 | 1598 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1745 Library::PrivateCoreLibName(Symbols::_as()), | 1748 Library::PrivateCoreLibName(Symbols::_as()), |
| 1746 node->kind(), | 1749 node->kind(), |
| 1747 arguments, | 1750 arguments, |
| 1748 Object::null_array(), // No argument names. | 1751 Object::null_array(), // No argument names. |
| 1749 kNumArgsChecked, | 1752 kNumArgsChecked, |
| 1750 owner()->ic_data_array()); | 1753 owner()->ic_data_array()); |
| 1751 ReturnDefinition(call); | 1754 ReturnDefinition(call); |
| 1752 } | 1755 } |
| 1753 | 1756 |
| 1754 | 1757 |
| 1755 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left, | 1758 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare( |
| 1756 AstNode* right, | 1759 AstNode* left, |
| 1757 Token::Kind kind, | 1760 AstNode* right, |
| 1758 intptr_t token_pos) { | 1761 Token::Kind kind, |
| 1762 TokenDescriptor token_pos) { |
| 1759 ValueGraphVisitor for_left_value(owner()); | 1763 ValueGraphVisitor for_left_value(owner()); |
| 1760 left->Visit(&for_left_value); | 1764 left->Visit(&for_left_value); |
| 1761 Append(for_left_value); | 1765 Append(for_left_value); |
| 1762 ValueGraphVisitor for_right_value(owner()); | 1766 ValueGraphVisitor for_right_value(owner()); |
| 1763 right->Visit(&for_right_value); | 1767 right->Visit(&for_right_value); |
| 1764 Append(for_right_value); | 1768 Append(for_right_value); |
| 1765 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos, | 1769 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos, |
| 1766 kind, | 1770 kind, |
| 1767 for_left_value.value(), | 1771 for_left_value.value(), |
| 1768 for_right_value.value(), | 1772 for_right_value.value(), |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2279 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { | 2283 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { |
| 2280 // Await nodes are temporary during parsing. | 2284 // Await nodes are temporary during parsing. |
| 2281 UNREACHABLE(); | 2285 UNREACHABLE(); |
| 2282 } | 2286 } |
| 2283 | 2287 |
| 2284 | 2288 |
| 2285 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { | 2289 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { |
| 2286 // We need to create a new await state which involves: | 2290 // We need to create a new await state which involves: |
| 2287 // * Increase the jump counter. Sanity check against the list of targets. | 2291 // * Increase the jump counter. Sanity check against the list of targets. |
| 2288 // * Save the current context for resuming. | 2292 // * Save the current context for resuming. |
| 2289 ASSERT(Token::IsSynthetic(node->token_pos()) || | 2293 ASSERT(TokenDescriptor(node->token_pos()).IsSynthetic() || |
| 2290 Token::IsNoSource(node->token_pos())); | 2294 TokenDescriptor(node->token_pos()).IsNoSource()); |
| 2291 ASSERT(node->async_scope() != NULL); | 2295 ASSERT(node->async_scope() != NULL); |
| 2292 ASSERT(node->await_scope() != NULL); | 2296 ASSERT(node->await_scope() != NULL); |
| 2293 LocalVariable* jump_var = node->async_scope()->LookupVariable( | 2297 LocalVariable* jump_var = node->async_scope()->LookupVariable( |
| 2294 Symbols::AwaitJumpVar(), false); | 2298 Symbols::AwaitJumpVar(), false); |
| 2295 LocalVariable* ctx_var = node->async_scope()->LookupVariable( | 2299 LocalVariable* ctx_var = node->async_scope()->LookupVariable( |
| 2296 Symbols::AwaitContextVar(), false); | 2300 Symbols::AwaitContextVar(), false); |
| 2297 ASSERT((jump_var != NULL) && jump_var->is_captured()); | 2301 ASSERT((jump_var != NULL) && jump_var->is_captured()); |
| 2298 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); | 2302 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); |
| 2299 const intptr_t jump_count = owner()->next_await_counter(); | 2303 const intptr_t jump_count = owner()->next_await_counter(); |
| 2300 ASSERT(jump_count >= 0); | 2304 ASSERT(jump_count >= 0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2313 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 2317 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 2314 return kFirstLocalSlotFromFp | 2318 return kFirstLocalSlotFromFp |
| 2315 - owner()->num_stack_locals() | 2319 - owner()->num_stack_locals() |
| 2316 - owner()->num_copied_params() | 2320 - owner()->num_copied_params() |
| 2317 - owner()->args_pushed() | 2321 - owner()->args_pushed() |
| 2318 - owner()->temp_count() + 1; | 2322 - owner()->temp_count() + 1; |
| 2319 } | 2323 } |
| 2320 | 2324 |
| 2321 | 2325 |
| 2322 LocalVariable* EffectGraphVisitor::EnterTempLocalScope( | 2326 LocalVariable* EffectGraphVisitor::EnterTempLocalScope( |
| 2323 Value* value, intptr_t token_pos) { | 2327 Value* value, TokenDescriptor token_pos) { |
| 2324 Do(new(Z) PushTempInstr(value)); | 2328 Do(new(Z) PushTempInstr(value)); |
| 2325 owner()->AllocateTemp(); | 2329 owner()->AllocateTemp(); |
| 2326 | 2330 |
| 2327 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); | 2331 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); |
| 2328 intptr_t index = GetCurrentTempLocalIndex(); | 2332 intptr_t index = GetCurrentTempLocalIndex(); |
| 2329 char name[64]; | 2333 char name[64]; |
| 2330 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 2334 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 2331 LocalVariable* var = | 2335 LocalVariable* var = |
| 2332 new(Z) LocalVariable(Token::kNoSourcePos, | 2336 new(Z) LocalVariable(TokenDescriptor::kNoSource, |
| 2333 String::ZoneHandle(Z, Symbols::New(name)), | 2337 String::ZoneHandle(Z, Symbols::New(name)), |
| 2334 *value->Type()->ToAbstractType()); | 2338 *value->Type()->ToAbstractType()); |
| 2335 var->set_index(index); | 2339 var->set_index(index); |
| 2336 return var; | 2340 return var; |
| 2337 } | 2341 } |
| 2338 | 2342 |
| 2339 | 2343 |
| 2340 Definition* EffectGraphVisitor::ExitTempLocalScope( | 2344 Definition* EffectGraphVisitor::ExitTempLocalScope( |
| 2341 LocalVariable* var, intptr_t token_pos) { | 2345 LocalVariable* var, TokenDescriptor token_pos) { |
| 2342 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); | 2346 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); |
| 2343 owner()->DeallocateTemps(1); | 2347 owner()->DeallocateTemps(1); |
| 2344 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 2348 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| 2345 return new(Z) DropTempsInstr(1, tmp); | 2349 return new(Z) DropTempsInstr(1, tmp); |
| 2346 } | 2350 } |
| 2347 | 2351 |
| 2348 | 2352 |
| 2349 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { | 2353 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 2350 intptr_t num_temps = node->num_temps(); | 2354 intptr_t num_temps = node->num_temps(); |
| 2351 for (intptr_t i = 0; i < num_temps; ++i) { | 2355 for (intptr_t i = 0; i < num_temps; ++i) { |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2619 ValueGraphVisitor for_argument(owner()); | 2623 ValueGraphVisitor for_argument(owner()); |
| 2620 node.NodeAt(i)->Visit(&for_argument); | 2624 node.NodeAt(i)->Visit(&for_argument); |
| 2621 Append(for_argument); | 2625 Append(for_argument); |
| 2622 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 2626 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 2623 values->Add(push_arg); | 2627 values->Add(push_arg); |
| 2624 } | 2628 } |
| 2625 } | 2629 } |
| 2626 | 2630 |
| 2627 | 2631 |
| 2628 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { | 2632 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { |
| 2629 const intptr_t token_pos = node->token_pos(); | 2633 const TokenDescriptor token_pos = node->token_pos(); |
| 2630 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 2634 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 2631 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); | 2635 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); |
| 2632 | 2636 |
| 2633 LiteralNode* null_constant = | 2637 LiteralNode* null_constant = |
| 2634 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); | 2638 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 2635 ComparisonNode* check_is_null = | 2639 ComparisonNode* check_is_null = |
| 2636 new(Z) ComparisonNode(ST(token_pos), | 2640 new(Z) ComparisonNode(ST(token_pos), |
| 2637 Token::kEQ, | 2641 Token::kEQ, |
| 2638 load_temp, | 2642 load_temp, |
| 2639 null_constant); | 2643 null_constant); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2911 // t_n+1 <- ctor-arg | 2915 // t_n+1 <- ctor-arg |
| 2912 // t_n+2... <- constructor arguments start here | 2916 // t_n+2... <- constructor arguments start here |
| 2913 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2917 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 2914 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2918 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2915 Value* allocated_value = BuildObjectAllocation(node); | 2919 Value* allocated_value = BuildObjectAllocation(node); |
| 2916 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2920 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2917 BuildConstructorCall(node, push_allocated_value); | 2921 BuildConstructorCall(node, push_allocated_value); |
| 2918 } | 2922 } |
| 2919 | 2923 |
| 2920 | 2924 |
| 2921 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos) { | 2925 Value* EffectGraphVisitor::BuildInstantiator(TokenDescriptor token_pos) { |
| 2922 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2926 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2923 while (outer_function.IsLocalFunction()) { | 2927 while (outer_function.IsLocalFunction()) { |
| 2924 outer_function = outer_function.parent_function(); | 2928 outer_function = outer_function.parent_function(); |
| 2925 } | 2929 } |
| 2926 if (outer_function.IsFactory()) { | 2930 if (outer_function.IsFactory()) { |
| 2927 return NULL; | 2931 return NULL; |
| 2928 } | 2932 } |
| 2929 | 2933 |
| 2930 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2934 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
| 2931 ASSERT(instantiator != NULL); | 2935 ASSERT(instantiator != NULL); |
| 2932 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); | 2936 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); |
| 2933 return result; | 2937 return result; |
| 2934 } | 2938 } |
| 2935 | 2939 |
| 2936 | 2940 |
| 2937 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2941 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2938 // is not NULL. | 2942 // is not NULL. |
| 2939 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2943 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2940 intptr_t token_pos, | 2944 TokenDescriptor token_pos, |
| 2941 const Class& instantiator_class, | 2945 const Class& instantiator_class, |
| 2942 Value* instantiator) { | 2946 Value* instantiator) { |
| 2943 if (!instantiator_class.IsGeneric()) { | 2947 if (!instantiator_class.IsGeneric()) { |
| 2944 // The type arguments are compile time constants. | 2948 // The type arguments are compile time constants. |
| 2945 TypeArguments& type_arguments = | 2949 TypeArguments& type_arguments = |
| 2946 TypeArguments::ZoneHandle(Z, TypeArguments::null()); | 2950 TypeArguments::ZoneHandle(Z, TypeArguments::null()); |
| 2947 // Type is temporary. Only its type arguments are preserved. | 2951 // Type is temporary. Only its type arguments are preserved. |
| 2948 Type& type = Type::Handle( | 2952 Type& type = Type::Handle( |
| 2949 Z, | 2953 Z, |
| 2950 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2954 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2980 | 2984 |
| 2981 return Bind(new(Z) LoadFieldInstr( | 2985 return Bind(new(Z) LoadFieldInstr( |
| 2982 instantiator, | 2986 instantiator, |
| 2983 type_arguments_field_offset, | 2987 type_arguments_field_offset, |
| 2984 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. | 2988 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. |
| 2985 token_pos)); | 2989 token_pos)); |
| 2986 } | 2990 } |
| 2987 | 2991 |
| 2988 | 2992 |
| 2989 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2993 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 2990 intptr_t token_pos, | 2994 TokenDescriptor token_pos, |
| 2991 const TypeArguments& type_arguments) { | 2995 const TypeArguments& type_arguments) { |
| 2992 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2996 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 2993 return Bind(new(Z) ConstantInstr(type_arguments)); | 2997 return Bind(new(Z) ConstantInstr(type_arguments)); |
| 2994 } | 2998 } |
| 2995 // The type arguments are uninstantiated. | 2999 // The type arguments are uninstantiated. |
| 2996 const Class& instantiator_class = Class::ZoneHandle( | 3000 const Class& instantiator_class = Class::ZoneHandle( |
| 2997 Z, owner()->function().Owner()); | 3001 Z, owner()->function().Owner()); |
| 2998 Value* instantiator_value = | 3002 Value* instantiator_value = |
| 2999 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 3003 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 3000 const bool use_instantiator_type_args = | 3004 const bool use_instantiator_type_args = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3032 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); | 3036 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
| 3033 BuildConstructorCall(node, push_allocated_value); | 3037 BuildConstructorCall(node, push_allocated_value); |
| 3034 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); | 3038 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); |
| 3035 } | 3039 } |
| 3036 } | 3040 } |
| 3037 | 3041 |
| 3038 | 3042 |
| 3039 | 3043 |
| 3040 void EffectGraphVisitor::BuildInstanceGetterConditional( | 3044 void EffectGraphVisitor::BuildInstanceGetterConditional( |
| 3041 InstanceGetterNode* node) { | 3045 InstanceGetterNode* node) { |
| 3042 const intptr_t token_pos = node->token_pos(); | 3046 const TokenDescriptor token_pos = node->token_pos(); |
| 3043 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3047 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3044 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); | 3048 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); |
| 3045 | 3049 |
| 3046 LiteralNode* null_constant = | 3050 LiteralNode* null_constant = |
| 3047 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); | 3051 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 3048 ComparisonNode* check_is_null = | 3052 ComparisonNode* check_is_null = |
| 3049 new(Z) ComparisonNode(ST(token_pos), | 3053 new(Z) ComparisonNode(ST(token_pos), |
| 3050 Token::kEQ, | 3054 Token::kEQ, |
| 3051 load_temp, | 3055 load_temp, |
| 3052 null_constant); | 3056 null_constant); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3128 if (result_is_needed) { | 3132 if (result_is_needed) { |
| 3129 value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos())); | 3133 value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos())); |
| 3130 } else { | 3134 } else { |
| 3131 value = for_value.value(); | 3135 value = for_value.value(); |
| 3132 } | 3136 } |
| 3133 arguments->Add(PushArgument(value)); | 3137 arguments->Add(PushArgument(value)); |
| 3134 } | 3138 } |
| 3135 | 3139 |
| 3136 | 3140 |
| 3137 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 3141 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 3138 const intptr_t token_pos = node->token_pos(); | 3142 const TokenDescriptor token_pos = node->token_pos(); |
| 3139 if (node->is_conditional()) { | 3143 if (node->is_conditional()) { |
| 3140 ValueGraphVisitor for_receiver(owner()); | 3144 ValueGraphVisitor for_receiver(owner()); |
| 3141 node->receiver()->Visit(&for_receiver); | 3145 node->receiver()->Visit(&for_receiver); |
| 3142 Append(for_receiver); | 3146 Append(for_receiver); |
| 3143 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); | 3147 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); |
| 3144 | 3148 |
| 3145 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3149 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3146 LoadLocalNode* load_temp = | 3150 LoadLocalNode* load_temp = |
| 3147 new(Z) LoadLocalNode(ST(token_pos), temp_var); | 3151 new(Z) LoadLocalNode(ST(token_pos), temp_var); |
| 3148 LiteralNode* null_constant = | 3152 LiteralNode* null_constant = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3178 Token::kSET, | 3182 Token::kSET, |
| 3179 arguments, | 3183 arguments, |
| 3180 Object::null_array(), | 3184 Object::null_array(), |
| 3181 kNumArgsChecked, | 3185 kNumArgsChecked, |
| 3182 owner()->ic_data_array()); | 3186 owner()->ic_data_array()); |
| 3183 ReturnDefinition(call); | 3187 ReturnDefinition(call); |
| 3184 } | 3188 } |
| 3185 | 3189 |
| 3186 | 3190 |
| 3187 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 3191 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 3188 const intptr_t token_pos = node->token_pos(); | 3192 const TokenDescriptor token_pos = node->token_pos(); |
| 3189 if (node->is_conditional()) { | 3193 if (node->is_conditional()) { |
| 3190 ValueGraphVisitor for_receiver(owner()); | 3194 ValueGraphVisitor for_receiver(owner()); |
| 3191 node->receiver()->Visit(&for_receiver); | 3195 node->receiver()->Visit(&for_receiver); |
| 3192 Append(for_receiver); | 3196 Append(for_receiver); |
| 3193 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); | 3197 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); |
| 3194 | 3198 |
| 3195 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3199 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3196 LoadLocalNode* load_temp = | 3200 LoadLocalNode* load_temp = |
| 3197 new(Z) LoadLocalNode(ST(token_pos), temp_var); | 3201 new(Z) LoadLocalNode(ST(token_pos), temp_var); |
| 3198 LiteralNode* null_constant = | 3202 LiteralNode* null_constant = |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3310 ReturnDefinition(call); | 3314 ReturnDefinition(call); |
| 3311 } | 3315 } |
| 3312 | 3316 |
| 3313 | 3317 |
| 3314 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 3318 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 3315 bool result_is_needed) { | 3319 bool result_is_needed) { |
| 3316 const String& setter_name = | 3320 const String& setter_name = |
| 3317 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); | 3321 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); |
| 3318 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3322 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3319 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | 3323 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 3320 const intptr_t token_pos = node->token_pos(); | 3324 const TokenDescriptor token_pos = node->token_pos(); |
| 3321 // A super setter is an instance setter whose setter function is | 3325 // A super setter is an instance setter whose setter function is |
| 3322 // resolved at compile time (in the caller instance getter's super class). | 3326 // resolved at compile time (in the caller instance getter's super class). |
| 3323 // Unlike a static getter, a super getter has a receiver parameter. | 3327 // Unlike a static getter, a super getter has a receiver parameter. |
| 3324 const bool is_super_setter = (node->receiver() != NULL); | 3328 const bool is_super_setter = (node->receiver() != NULL); |
| 3325 const Function& setter_function = node->function(); | 3329 const Function& setter_function = node->function(); |
| 3326 StaticCallInstr* call; | 3330 StaticCallInstr* call; |
| 3327 if (setter_function.IsNull()) { | 3331 if (setter_function.IsNull()) { |
| 3328 if (is_super_setter) { | 3332 if (is_super_setter) { |
| 3329 ASSERT(node->receiver() != NULL); | 3333 ASSERT(node->receiver() != NULL); |
| 3330 // Resolve and call noSuchMethod. | 3334 // Resolve and call noSuchMethod. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3410 case MethodRecognizer::kGrowableArrayLength: | 3414 case MethodRecognizer::kGrowableArrayLength: |
| 3411 return GrowableObjectArray::length_offset(); | 3415 return GrowableObjectArray::length_offset(); |
| 3412 default: | 3416 default: |
| 3413 UNREACHABLE(); | 3417 UNREACHABLE(); |
| 3414 return 0; | 3418 return 0; |
| 3415 } | 3419 } |
| 3416 } | 3420 } |
| 3417 | 3421 |
| 3418 | 3422 |
| 3419 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar( | 3423 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar( |
| 3420 LocalScope* scope, intptr_t token_pos) { | 3424 LocalScope* scope, TokenDescriptor token_pos) { |
| 3421 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), | 3425 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), |
| 3422 true); // Test only. | 3426 true); // Test only. |
| 3423 return new(Z) LoadLocalInstr(*receiver_var, token_pos); | 3427 return new(Z) LoadLocalInstr(*receiver_var, token_pos); |
| 3424 } | 3428 } |
| 3425 | 3429 |
| 3426 | 3430 |
| 3427 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( | 3431 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( |
| 3428 NativeBodyNode* node, | 3432 NativeBodyNode* node, |
| 3429 MethodRecognizer::Kind kind, | 3433 MethodRecognizer::Kind kind, |
| 3430 intptr_t offset, | 3434 intptr_t offset, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3455 value, | 3459 value, |
| 3456 emit_store_barrier, | 3460 emit_store_barrier, |
| 3457 node->token_pos()); | 3461 node->token_pos()); |
| 3458 Do(store); | 3462 Do(store); |
| 3459 return new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); | 3463 return new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); |
| 3460 } | 3464 } |
| 3461 | 3465 |
| 3462 | 3466 |
| 3463 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 3467 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 3464 const Function& function = owner()->function(); | 3468 const Function& function = owner()->function(); |
| 3465 const intptr_t token_pos = node->token_pos(); | 3469 const TokenDescriptor token_pos = node->token_pos(); |
| 3466 if (!function.IsClosureFunction()) { | 3470 if (!function.IsClosureFunction()) { |
| 3467 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); | 3471 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); |
| 3468 switch (kind) { | 3472 switch (kind) { |
| 3469 case MethodRecognizer::kObjectEquals: { | 3473 case MethodRecognizer::kObjectEquals: { |
| 3470 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); | 3474 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); |
| 3471 LocalVariable* other_var = | 3475 LocalVariable* other_var = |
| 3472 node->scope()->LookupVariable(Symbols::Other(), | 3476 node->scope()->LookupVariable(Symbols::Other(), |
| 3473 true); // Test only. | 3477 true); // Test only. |
| 3474 Value* other = Bind(new(Z) LoadLocalInstr(*other_var, token_pos)); | 3478 Value* other = Bind(new(Z) LoadLocalInstr(*other_var, token_pos)); |
| 3475 // Receiver is not a number because numbers override equality. | 3479 // Receiver is not a number because numbers override equality. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3658 // If the right hand side is an expression that does not contain | 3662 // If the right hand side is an expression that does not contain |
| 3659 // a safe point for the debugger to stop, add an explicit stub | 3663 // a safe point for the debugger to stop, add an explicit stub |
| 3660 // call. Exception: don't do this when assigning to or from internal | 3664 // call. Exception: don't do this when assigning to or from internal |
| 3661 // variables, or for generated code that has no source position. | 3665 // variables, or for generated code that has no source position. |
| 3662 if (FLAG_support_debugger) { | 3666 if (FLAG_support_debugger) { |
| 3663 if ((node->value()->IsLiteralNode() || | 3667 if ((node->value()->IsLiteralNode() || |
| 3664 (node->value()->IsLoadLocalNode() && | 3668 (node->value()->IsLoadLocalNode() && |
| 3665 !node->value()->AsLoadLocalNode()->local().IsInternal()) || | 3669 !node->value()->AsLoadLocalNode()->local().IsInternal()) || |
| 3666 node->value()->IsClosureNode()) && | 3670 node->value()->IsClosureNode()) && |
| 3667 !node->local().IsInternal() && | 3671 !node->local().IsInternal() && |
| 3668 Token::IsDebugPause(node->token_pos())) { | 3672 TokenDescriptor(node->token_pos()).IsDebugPause()) { |
| 3669 AddInstruction(new(Z) DebugStepCheckInstr( | 3673 AddInstruction(new(Z) DebugStepCheckInstr( |
| 3670 node->token_pos(), RawPcDescriptors::kRuntimeCall)); | 3674 node->token_pos(), RawPcDescriptors::kRuntimeCall)); |
| 3671 } | 3675 } |
| 3672 } | 3676 } |
| 3673 | 3677 |
| 3674 ValueGraphVisitor for_value(owner()); | 3678 ValueGraphVisitor for_value(owner()); |
| 3675 node->value()->Visit(&for_value); | 3679 node->value()->Visit(&for_value); |
| 3676 Append(for_value); | 3680 Append(for_value); |
| 3677 Value* store_value = for_value.value(); | 3681 Value* store_value = for_value.value(); |
| 3678 if (Isolate::Current()->flags().type_checks()) { | 3682 if (Isolate::Current()->flags().type_checks()) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3704 load->set_result_cid(node->field().guarded_cid()); | 3708 load->set_result_cid(node->field().guarded_cid()); |
| 3705 } | 3709 } |
| 3706 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); | 3710 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); |
| 3707 } | 3711 } |
| 3708 ReturnDefinition(load); | 3712 ReturnDefinition(load); |
| 3709 } | 3713 } |
| 3710 | 3714 |
| 3711 | 3715 |
| 3712 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 3716 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 3713 StoreInstanceFieldNode* node) { | 3717 StoreInstanceFieldNode* node) { |
| 3714 const intptr_t token_pos = node->token_pos(); | 3718 const TokenDescriptor token_pos = node->token_pos(); |
| 3715 ValueGraphVisitor for_instance(owner()); | 3719 ValueGraphVisitor for_instance(owner()); |
| 3716 node->instance()->Visit(&for_instance); | 3720 node->instance()->Visit(&for_instance); |
| 3717 Append(for_instance); | 3721 Append(for_instance); |
| 3718 ValueGraphVisitor for_value(owner()); | 3722 ValueGraphVisitor for_value(owner()); |
| 3719 node->value()->Visit(&for_value); | 3723 node->value()->Visit(&for_value); |
| 3720 Append(for_value); | 3724 Append(for_value); |
| 3721 Value* store_value = for_value.value(); | 3725 Value* store_value = for_value.value(); |
| 3722 if (Isolate::Current()->flags().type_checks()) { | 3726 if (Isolate::Current()->flags().type_checks()) { |
| 3723 const AbstractType& type = | 3727 const AbstractType& type = |
| 3724 AbstractType::ZoneHandle(Z, node->field().type()); | 3728 AbstractType::ZoneHandle(Z, node->field().type()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3750 store_value, | 3754 store_value, |
| 3751 kEmitStoreBarrier, | 3755 kEmitStoreBarrier, |
| 3752 token_pos); | 3756 token_pos); |
| 3753 // Maybe initializing unboxed store. | 3757 // Maybe initializing unboxed store. |
| 3754 store->set_is_potential_unboxed_initialization(true); | 3758 store->set_is_potential_unboxed_initialization(true); |
| 3755 ReturnDefinition(store); | 3759 ReturnDefinition(store); |
| 3756 } | 3760 } |
| 3757 | 3761 |
| 3758 | 3762 |
| 3759 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 3763 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 3760 const intptr_t token_pos = node->token_pos(); | 3764 const TokenDescriptor token_pos = node->token_pos(); |
| 3761 if (node->field().is_const()) { | 3765 if (node->field().is_const()) { |
| 3762 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); | 3766 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); |
| 3763 ASSERT(node->field().StaticValue() != | 3767 ASSERT(node->field().StaticValue() != |
| 3764 Object::transition_sentinel().raw()); | 3768 Object::transition_sentinel().raw()); |
| 3765 Definition* result = new(Z) ConstantInstr( | 3769 Definition* result = new(Z) ConstantInstr( |
| 3766 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos); | 3770 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos); |
| 3767 return ReturnDefinition(result); | 3771 return ReturnDefinition(result); |
| 3768 } | 3772 } |
| 3769 Value* field_value = Bind(new(Z) ConstantInstr(node->field(), token_pos)); | 3773 Value* field_value = Bind(new(Z) ConstantInstr(node->field(), token_pos)); |
| 3770 LoadStaticFieldInstr* load = | 3774 LoadStaticFieldInstr* load = |
| 3771 new(Z) LoadStaticFieldInstr(field_value, token_pos); | 3775 new(Z) LoadStaticFieldInstr(field_value, token_pos); |
| 3772 ReturnDefinition(load); | 3776 ReturnDefinition(load); |
| 3773 } | 3777 } |
| 3774 | 3778 |
| 3775 | 3779 |
| 3776 Definition* EffectGraphVisitor::BuildStoreStaticField( | 3780 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 3777 StoreStaticFieldNode* node, | 3781 StoreStaticFieldNode* node, |
| 3778 bool result_is_needed, | 3782 bool result_is_needed, |
| 3779 intptr_t token_pos) { | 3783 TokenDescriptor token_pos) { |
| 3780 ValueGraphVisitor for_value(owner()); | 3784 ValueGraphVisitor for_value(owner()); |
| 3781 node->value()->Visit(&for_value); | 3785 node->value()->Visit(&for_value); |
| 3782 Append(for_value); | 3786 Append(for_value); |
| 3783 Value* store_value = NULL; | 3787 Value* store_value = NULL; |
| 3784 if (result_is_needed) { | 3788 if (result_is_needed) { |
| 3785 store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); | 3789 store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); |
| 3786 } else { | 3790 } else { |
| 3787 store_value = for_value.value(); | 3791 store_value = for_value.value(); |
| 3788 } | 3792 } |
| 3789 StoreStaticFieldInstr* store = | 3793 StoreStaticFieldInstr* store = |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3867 owner()->ic_data_array()); | 3871 owner()->ic_data_array()); |
| 3868 ReturnDefinition(load); | 3872 ReturnDefinition(load); |
| 3869 } | 3873 } |
| 3870 } | 3874 } |
| 3871 | 3875 |
| 3872 | 3876 |
| 3873 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 3877 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 3874 StoreIndexedNode* node, | 3878 StoreIndexedNode* node, |
| 3875 bool result_is_needed) { | 3879 bool result_is_needed) { |
| 3876 Function* super_function = NULL; | 3880 Function* super_function = NULL; |
| 3877 const intptr_t token_pos = node->token_pos(); | 3881 const TokenDescriptor token_pos = node->token_pos(); |
| 3878 if (node->IsSuperStore()) { | 3882 if (node->IsSuperStore()) { |
| 3879 // Resolve the store indexed operator in the super class. | 3883 // Resolve the store indexed operator in the super class. |
| 3880 super_function = &Function::ZoneHandle( | 3884 super_function = &Function::ZoneHandle( |
| 3881 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3885 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 3882 Symbols::AssignIndexToken())); | 3886 Symbols::AssignIndexToken())); |
| 3883 if (super_function->IsNull()) { | 3887 if (super_function->IsNull()) { |
| 3884 // Could not resolve super operator. Generate call noSuchMethod() of the | 3888 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3885 // super class instead. | 3889 // super class instead. |
| 3886 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); | 3890 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); |
| 3887 arguments->Add(node->array()); | 3891 arguments->Add(node->array()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3977 | 3981 |
| 3978 bool EffectGraphVisitor::HasContextScope() const { | 3982 bool EffectGraphVisitor::HasContextScope() const { |
| 3979 const ContextScope& context_scope = ContextScope::Handle( | 3983 const ContextScope& context_scope = ContextScope::Handle( |
| 3980 owner()->function().context_scope()); | 3984 owner()->function().context_scope()); |
| 3981 return !context_scope.IsNull() && (context_scope.num_variables() > 0); | 3985 return !context_scope.IsNull() && (context_scope.num_variables() > 0); |
| 3982 } | 3986 } |
| 3983 | 3987 |
| 3984 | 3988 |
| 3985 void EffectGraphVisitor::UnchainContexts(intptr_t n) { | 3989 void EffectGraphVisitor::UnchainContexts(intptr_t n) { |
| 3986 // TODO(johnmccutchan): Pass this in. | 3990 // TODO(johnmccutchan): Pass this in. |
| 3987 const intptr_t token_pos = ClassifyingTokenPositions::kContext; | 3991 const TokenDescriptor token_pos = TokenDescriptor::kContext; |
| 3988 if (n > 0) { | 3992 if (n > 0) { |
| 3989 Value* context = Bind(BuildCurrentContext(token_pos)); | 3993 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 3990 while (n-- > 0) { | 3994 while (n-- > 0) { |
| 3991 context = Bind( | 3995 context = Bind( |
| 3992 new(Z) LoadFieldInstr(context, | 3996 new(Z) LoadFieldInstr(context, |
| 3993 Context::parent_offset(), | 3997 Context::parent_offset(), |
| 3994 // Not an instance, no type. | 3998 // Not an instance, no type. |
| 3995 Type::ZoneHandle(Z, Type::null()), | 3999 Type::ZoneHandle(Z, Type::null()), |
| 3996 token_pos)); | 4000 token_pos)); |
| 3997 } | 4001 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4075 const int num_params = function.NumParameters(); | 4079 const int num_params = function.NumParameters(); |
| 4076 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 4080 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 4077 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 4081 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
| 4078 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 4082 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |
| 4079 const LocalVariable& parameter = *scope->VariableAt(pos); | 4083 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 4080 ASSERT(parameter.owner() == scope); | 4084 ASSERT(parameter.owner() == scope); |
| 4081 if (parameter.is_captured()) { | 4085 if (parameter.is_captured()) { |
| 4082 // Create a temporary local describing the original position. | 4086 // Create a temporary local describing the original position. |
| 4083 const String& temp_name = Symbols::TempParam(); | 4087 const String& temp_name = Symbols::TempParam(); |
| 4084 LocalVariable* temp_local = new(Z) LocalVariable( | 4088 LocalVariable* temp_local = new(Z) LocalVariable( |
| 4085 Token::kNoSourcePos, // Token index. | 4089 TokenDescriptor::kNoSource, // Token index. |
| 4086 temp_name, | 4090 temp_name, |
| 4087 Object::dynamic_type()); // Type. | 4091 Object::dynamic_type()); // Type. |
| 4088 temp_local->set_index(param_frame_index); | 4092 temp_local->set_index(param_frame_index); |
| 4089 | 4093 |
| 4090 // Mark this local as captured parameter so that the optimizer | 4094 // Mark this local as captured parameter so that the optimizer |
| 4091 // correctly handles these when compiling try-catch: Captured | 4095 // correctly handles these when compiling try-catch: Captured |
| 4092 // parameters are not in the stack environment, therefore they | 4096 // parameters are not in the stack environment, therefore they |
| 4093 // must be skipped when emitting sync-code in try-blocks. | 4097 // must be skipped when emitting sync-code in try-blocks. |
| 4094 temp_local->set_is_captured_parameter(true); | 4098 temp_local->set_is_captured_parameter(true); |
| 4095 | 4099 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4110 } | 4114 } |
| 4111 | 4115 |
| 4112 if (FLAG_support_debugger && | 4116 if (FLAG_support_debugger && |
| 4113 is_top_level_sequence && | 4117 is_top_level_sequence && |
| 4114 function.is_debuggable()) { | 4118 function.is_debuggable()) { |
| 4115 // Place a debug check at method entry to ensure breaking on a method always | 4119 // Place a debug check at method entry to ensure breaking on a method always |
| 4116 // happens, even if there are no assignments/calls/runtimecalls in the first | 4120 // happens, even if there are no assignments/calls/runtimecalls in the first |
| 4117 // basic block. Place this check at the last parameter to ensure parameters | 4121 // basic block. Place this check at the last parameter to ensure parameters |
| 4118 // are in scope in the debugger at method entry. | 4122 // are in scope in the debugger at method entry. |
| 4119 const int num_params = function.NumParameters(); | 4123 const int num_params = function.NumParameters(); |
| 4120 intptr_t check_pos = Token::kNoSourcePos; | 4124 TokenDescriptor check_pos = TokenDescriptor::kNoSource; |
| 4121 if (num_params > 0) { | 4125 if (num_params > 0) { |
| 4122 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 4126 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| 4123 check_pos = parameter.token_pos(); | 4127 check_pos = parameter.token_pos(); |
| 4124 } | 4128 } |
| 4125 if (!Token::IsDebugPause(check_pos)) { | 4129 |
| 4130 if (!check_pos.IsDebugPause()) { |
| 4126 // No parameters or synthetic parameters. | 4131 // No parameters or synthetic parameters. |
| 4127 check_pos = node->token_pos(); | 4132 check_pos = node->token_pos(); |
| 4128 ASSERT(Token::IsDebugPause(check_pos)); | 4133 ASSERT(check_pos.IsDebugPause()); |
| 4129 } | 4134 } |
| 4130 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, | 4135 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, |
| 4131 RawPcDescriptors::kRuntimeCall)); | 4136 RawPcDescriptors::kRuntimeCall)); |
| 4132 } | 4137 } |
| 4133 | 4138 |
| 4134 // This check may be deleted if the generated code is leaf. | 4139 // This check may be deleted if the generated code is leaf. |
| 4135 // Native functions don't need a stack check at entry. | 4140 // Native functions don't need a stack check at entry. |
| 4136 if (is_top_level_sequence && !function.is_native()) { | 4141 if (is_top_level_sequence && !function.is_native()) { |
| 4137 // Always allocate CheckOverflowInstr so that deopt-ids match regardless | 4142 // Always allocate CheckOverflowInstr so that deopt-ids match regardless |
| 4138 // if we inline or not. | 4143 // if we inline or not. |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4422 | 4427 |
| 4423 // Looks up dynamic method noSuchMethod in target_class | 4428 // Looks up dynamic method noSuchMethod in target_class |
| 4424 // (including its super class chain) and builds a static call to it. | 4429 // (including its super class chain) and builds a static call to it. |
| 4425 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( | 4430 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
| 4426 const Class& target_class, | 4431 const Class& target_class, |
| 4427 AstNode* receiver, | 4432 AstNode* receiver, |
| 4428 const String& method_name, | 4433 const String& method_name, |
| 4429 ArgumentListNode* method_arguments, | 4434 ArgumentListNode* method_arguments, |
| 4430 bool save_last_arg, | 4435 bool save_last_arg, |
| 4431 bool is_super_invocation) { | 4436 bool is_super_invocation) { |
| 4432 intptr_t args_pos = method_arguments->token_pos(); | 4437 TokenDescriptor args_pos = method_arguments->token_pos(); |
| 4433 LocalVariable* temp = NULL; | 4438 LocalVariable* temp = NULL; |
| 4434 if (save_last_arg) { | 4439 if (save_last_arg) { |
| 4435 temp = owner()->parsed_function().expression_temp_var(); | 4440 temp = owner()->parsed_function().expression_temp_var(); |
| 4436 } | 4441 } |
| 4437 ArgumentListNode* args = | 4442 ArgumentListNode* args = |
| 4438 Parser::BuildNoSuchMethodArguments(args_pos, | 4443 Parser::BuildNoSuchMethodArguments(args_pos, |
| 4439 method_name, | 4444 method_name, |
| 4440 *method_arguments, | 4445 *method_arguments, |
| 4441 temp, | 4446 temp, |
| 4442 is_super_invocation); | 4447 is_super_invocation); |
| 4443 const Function& no_such_method_func = Function::ZoneHandle(Z, | 4448 const Function& no_such_method_func = Function::ZoneHandle(Z, |
| 4444 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); | 4449 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); |
| 4445 // We are guaranteed to find noSuchMethod of class Object. | 4450 // We are guaranteed to find noSuchMethod of class Object. |
| 4446 ASSERT(!no_such_method_func.IsNull()); | 4451 ASSERT(!no_such_method_func.IsNull()); |
| 4447 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = | 4452 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = |
| 4448 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 4453 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 4449 BuildPushArguments(*args, push_arguments); | 4454 BuildPushArguments(*args, push_arguments); |
| 4450 return new(Z) StaticCallInstr(args_pos, | 4455 return new(Z) StaticCallInstr(args_pos, |
| 4451 no_such_method_func, | 4456 no_such_method_func, |
| 4452 Object::null_array(), | 4457 Object::null_array(), |
| 4453 push_arguments, | 4458 push_arguments, |
| 4454 owner()->ic_data_array()); | 4459 owner()->ic_data_array()); |
| 4455 } | 4460 } |
| 4456 | 4461 |
| 4457 | 4462 |
| 4458 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( | 4463 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( |
| 4459 intptr_t token_pos, | 4464 TokenDescriptor token_pos, |
| 4460 const Class& function_class, | 4465 const Class& function_class, |
| 4461 const String& function_name, | 4466 const String& function_name, |
| 4462 ArgumentListNode* function_arguments, | 4467 ArgumentListNode* function_arguments, |
| 4463 int invocation_type) { | 4468 int invocation_type) { |
| 4464 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 4469 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 4465 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); | 4470 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); |
| 4466 // Object receiver, actually a class literal of the unresolved method's owner. | 4471 // Object receiver, actually a class literal of the unresolved method's owner. |
| 4467 AbstractType& type = Type::ZoneHandle( | 4472 AbstractType& type = Type::ZoneHandle( |
| 4468 Z, | 4473 Z, |
| 4469 Type::New(function_class, | 4474 Type::New(function_class, |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4666 Script::Handle(function.script()), | 4671 Script::Handle(function.script()), |
| 4667 function.token_pos(), | 4672 function.token_pos(), |
| 4668 Report::AtLocation, | 4673 Report::AtLocation, |
| 4669 "FlowGraphBuilder Bailout: %s %s", | 4674 "FlowGraphBuilder Bailout: %s %s", |
| 4670 String::Handle(function.name()).ToCString(), | 4675 String::Handle(function.name()).ToCString(), |
| 4671 reason); | 4676 reason); |
| 4672 UNREACHABLE(); | 4677 UNREACHABLE(); |
| 4673 } | 4678 } |
| 4674 | 4679 |
| 4675 } // namespace dart | 4680 } // namespace dart |
| OLD | NEW |