| 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/code_descriptors.h" | 10 #include "vm/class_finalizer.h" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/flags.h" | 12 #include "vm/flags.h" |
| 13 #include "vm/flow_graph.h" |
| 13 #include "vm/flow_graph_compiler.h" | 14 #include "vm/flow_graph_compiler.h" |
| 15 #include "vm/heap.h" |
| 14 #include "vm/il_printer.h" | 16 #include "vm/il_printer.h" |
| 15 #include "vm/intermediate_language.h" | 17 #include "vm/intermediate_language.h" |
| 18 #include "vm/isolate.h" |
| 16 #include "vm/longjump.h" | 19 #include "vm/longjump.h" |
| 17 #include "vm/object_store.h" | 20 #include "vm/object.h" |
| 18 #include "vm/os.h" | 21 #include "vm/os.h" |
| 19 #include "vm/parser.h" | 22 #include "vm/parser.h" |
| 20 #include "vm/resolver.h" | 23 #include "vm/resolver.h" |
| 24 #include "vm/scopes.h" |
| 21 #include "vm/stack_frame.h" | 25 #include "vm/stack_frame.h" |
| 22 #include "vm/stub_code.h" | 26 #include "vm/stub_code.h" |
| 23 #include "vm/symbols.h" | 27 #include "vm/symbols.h" |
| 28 #include "vm/token.h" |
| 29 #include "vm/zone.h" |
| 24 | 30 |
| 25 namespace dart { | 31 namespace dart { |
| 26 | 32 |
| 27 DEFINE_FLAG(bool, eliminate_type_checks, true, | 33 DEFINE_FLAG(bool, eliminate_type_checks, true, |
| 28 "Eliminate type checks when allowed by static type analysis."); | 34 "Eliminate type checks when allowed by static type analysis."); |
| 29 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); | 35 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); |
| 30 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 36 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
| 31 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); | 37 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph."); |
| 32 DEFINE_FLAG(bool, print_flow_graph_optimized, false, | 38 DEFINE_FLAG(bool, print_flow_graph_optimized, false, |
| 33 "Print the IR flow graph when optimizing."); | 39 "Print the IR flow graph when optimizing."); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 49 : 0), | 55 : 0), |
| 50 num_stack_locals_(parsed_function->num_stack_locals()), | 56 num_stack_locals_(parsed_function->num_stack_locals()), |
| 51 exit_collector_(exit_collector), | 57 exit_collector_(exit_collector), |
| 52 guarded_fields_(new ZoneGrowableArray<const Field*>()), | 58 guarded_fields_(new ZoneGrowableArray<const Field*>()), |
| 53 last_used_block_id_(0), // 0 is used for the graph entry. | 59 last_used_block_id_(0), // 0 is used for the graph entry. |
| 54 context_level_(0), | 60 context_level_(0), |
| 55 try_index_(CatchClauseNode::kInvalidTryIndex), | 61 try_index_(CatchClauseNode::kInvalidTryIndex), |
| 56 catch_try_index_(CatchClauseNode::kInvalidTryIndex), | 62 catch_try_index_(CatchClauseNode::kInvalidTryIndex), |
| 57 loop_depth_(0), | 63 loop_depth_(0), |
| 58 graph_entry_(NULL), | 64 graph_entry_(NULL), |
| 65 temp_count_(0), |
| 59 args_pushed_(0), | 66 args_pushed_(0), |
| 60 osr_id_(osr_id) { } | 67 osr_id_(osr_id) { } |
| 61 | 68 |
| 62 | 69 |
| 63 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { | 70 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { |
| 64 graph_entry_->AddCatchEntry(entry); | 71 graph_entry_->AddCatchEntry(entry); |
| 65 } | 72 } |
| 66 | 73 |
| 67 | 74 |
| 68 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { | 75 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 } | 352 } |
| 346 call_->UnuseAllInputs(); | 353 call_->UnuseAllInputs(); |
| 347 } | 354 } |
| 348 | 355 |
| 349 | 356 |
| 350 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 357 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 351 ASSERT(is_open()); | 358 ASSERT(is_open()); |
| 352 if (other_fragment.is_empty()) return; | 359 if (other_fragment.is_empty()) return; |
| 353 if (is_empty()) { | 360 if (is_empty()) { |
| 354 entry_ = other_fragment.entry(); | 361 entry_ = other_fragment.entry(); |
| 355 exit_ = other_fragment.exit(); | |
| 356 } else { | 362 } else { |
| 357 exit()->LinkTo(other_fragment.entry()); | 363 exit()->LinkTo(other_fragment.entry()); |
| 358 exit_ = other_fragment.exit(); | |
| 359 } | 364 } |
| 360 temp_index_ = other_fragment.temp_index(); | 365 exit_ = other_fragment.exit(); |
| 361 } | 366 } |
| 362 | 367 |
| 363 | 368 |
| 364 Value* EffectGraphVisitor::Bind(Definition* definition) { | 369 Value* EffectGraphVisitor::Bind(Definition* definition) { |
| 365 ASSERT(is_open()); | 370 ASSERT(is_open()); |
| 366 DeallocateTempIndex(definition->InputCount()); | 371 owner()->DeallocateTemps(definition->InputCount()); |
| 372 owner()->add_args_pushed(-definition->ArgumentCount()); |
| 367 definition->set_use_kind(Definition::kValue); | 373 definition->set_use_kind(Definition::kValue); |
| 368 definition->set_temp_index(AllocateTempIndex()); | 374 definition->set_temp_index(owner()->AllocateTemp()); |
| 369 owner_->add_args_pushed(-definition->ArgumentCount()); | |
| 370 if (is_empty()) { | 375 if (is_empty()) { |
| 371 entry_ = definition; | 376 entry_ = definition; |
| 372 } else { | 377 } else { |
| 373 exit()->LinkTo(definition); | 378 exit()->LinkTo(definition); |
| 374 } | 379 } |
| 375 exit_ = definition; | 380 exit_ = definition; |
| 376 return new Value(definition); | 381 return new Value(definition); |
| 377 } | 382 } |
| 378 | 383 |
| 379 | 384 |
| 380 void EffectGraphVisitor::Do(Definition* definition) { | 385 void EffectGraphVisitor::Do(Definition* definition) { |
| 381 ASSERT(is_open()); | 386 ASSERT(is_open()); |
| 382 DeallocateTempIndex(definition->InputCount()); | 387 owner()->DeallocateTemps(definition->InputCount()); |
| 388 owner()->add_args_pushed(-definition->ArgumentCount()); |
| 383 definition->set_use_kind(Definition::kEffect); | 389 definition->set_use_kind(Definition::kEffect); |
| 384 owner_->add_args_pushed(-definition->ArgumentCount()); | |
| 385 if (is_empty()) { | 390 if (is_empty()) { |
| 386 entry_ = definition; | 391 entry_ = definition; |
| 387 } else { | 392 } else { |
| 388 exit()->LinkTo(definition); | 393 exit()->LinkTo(definition); |
| 389 } | 394 } |
| 390 exit_ = definition; | 395 exit_ = definition; |
| 391 } | 396 } |
| 392 | 397 |
| 393 | 398 |
| 394 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 399 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 395 ASSERT(is_open()); | 400 ASSERT(is_open()); |
| 396 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); | 401 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); |
| 397 ASSERT(!instruction->IsBlockEntry()); | 402 ASSERT(!instruction->IsBlockEntry()); |
| 398 DeallocateTempIndex(instruction->InputCount()); | 403 owner()->DeallocateTemps(instruction->InputCount()); |
| 399 owner_->add_args_pushed(-instruction->ArgumentCount()); | 404 owner()->add_args_pushed(-instruction->ArgumentCount()); |
| 400 if (is_empty()) { | 405 if (is_empty()) { |
| 401 entry_ = exit_ = instruction; | 406 entry_ = exit_ = instruction; |
| 402 } else { | 407 } else { |
| 403 exit()->LinkTo(instruction); | 408 exit()->LinkTo(instruction); |
| 404 exit_ = instruction; | 409 exit_ = instruction; |
| 405 } | 410 } |
| 406 } | 411 } |
| 407 | 412 |
| 408 | 413 |
| 409 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { | 414 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 // (if any). | 465 // (if any). |
| 461 BlockEntryInstr* true_entry = test_fragment.CreateTrueSuccessor(); | 466 BlockEntryInstr* true_entry = test_fragment.CreateTrueSuccessor(); |
| 462 Instruction* true_exit = AppendFragment(true_entry, true_fragment); | 467 Instruction* true_exit = AppendFragment(true_entry, true_fragment); |
| 463 | 468 |
| 464 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); | 469 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); |
| 465 Instruction* false_exit = AppendFragment(false_entry, false_fragment); | 470 Instruction* false_exit = AppendFragment(false_entry, false_fragment); |
| 466 | 471 |
| 467 // 3. Add a join or select one (or neither) of the arms as exit. | 472 // 3. Add a join or select one (or neither) of the arms as exit. |
| 468 if (true_exit == NULL) { | 473 if (true_exit == NULL) { |
| 469 exit_ = false_exit; // May be NULL. | 474 exit_ = false_exit; // May be NULL. |
| 470 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); | |
| 471 } else if (false_exit == NULL) { | 475 } else if (false_exit == NULL) { |
| 472 exit_ = true_exit; | 476 exit_ = true_exit; |
| 473 temp_index_ = true_fragment.temp_index(); | |
| 474 } else { | 477 } else { |
| 475 JoinEntryInstr* join = | 478 JoinEntryInstr* join = |
| 476 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 479 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 477 true_exit->Goto(join); | 480 true_exit->Goto(join); |
| 478 false_exit->Goto(join); | 481 false_exit->Goto(join); |
| 479 exit_ = join; | 482 exit_ = join; |
| 480 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); | |
| 481 temp_index_ = true_fragment.temp_index(); | |
| 482 } | 483 } |
| 483 } | 484 } |
| 484 | 485 |
| 485 | 486 |
| 486 void EffectGraphVisitor::TieLoop(intptr_t token_pos, | 487 void EffectGraphVisitor::TieLoop(intptr_t token_pos, |
| 487 const TestGraphVisitor& test_fragment, | 488 const TestGraphVisitor& test_fragment, |
| 488 const EffectGraphVisitor& body_fragment) { | 489 const EffectGraphVisitor& body_fragment) { |
| 489 // We have: a test graph fragment with zero, one, or two available exits; | 490 // We have: a test graph fragment with zero, one, or two available exits; |
| 490 // and an effect graph fragment with zero or one available exits. We want | 491 // and an effect graph fragment with zero or one available exits. We want |
| 491 // to append the 'while loop' consisting of the test graph fragment as | 492 // to append the 'while loop' consisting of the test graph fragment as |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 } | 736 } |
| 736 ReturnValue(Bind(definition)); | 737 ReturnValue(Bind(definition)); |
| 737 } | 738 } |
| 738 | 739 |
| 739 | 740 |
| 740 // Special handling for AND/OR. | 741 // Special handling for AND/OR. |
| 741 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 742 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 742 // Operators "&&" and "||" cannot be overloaded therefore do not call | 743 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 743 // operator. | 744 // operator. |
| 744 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 745 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 745 TestGraphVisitor for_left(owner(), | 746 TestGraphVisitor for_left(owner(), node->left()->token_pos()); |
| 746 temp_index(), | |
| 747 node->left()->token_pos()); | |
| 748 node->left()->Visit(&for_left); | 747 node->left()->Visit(&for_left); |
| 749 | 748 |
| 750 TestGraphVisitor for_right(owner(), | 749 TestGraphVisitor for_right(owner(), node->right()->token_pos()); |
| 751 temp_index(), | |
| 752 node->right()->token_pos()); | |
| 753 node->right()->Visit(&for_right); | 750 node->right()->Visit(&for_right); |
| 754 | 751 |
| 755 Append(for_left); | 752 Append(for_left); |
| 756 | 753 |
| 757 if (node->kind() == Token::kAND) { | 754 if (node->kind() == Token::kAND) { |
| 758 AppendFragment(for_left.CreateTrueSuccessor(), for_right); | 755 AppendFragment(for_left.CreateTrueSuccessor(), for_right); |
| 759 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); | 756 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); |
| 760 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); | 757 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); |
| 761 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); | 758 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); |
| 762 } else { | 759 } else { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 780 | 777 |
| 781 void EffectGraphVisitor::InlineBailout(const char* reason) { | 778 void EffectGraphVisitor::InlineBailout(const char* reason) { |
| 782 owner()->parsed_function()->function().set_is_inlinable(false); | 779 owner()->parsed_function()->function().set_is_inlinable(false); |
| 783 if (owner()->IsInlining()) owner()->Bailout(reason); | 780 if (owner()->IsInlining()) owner()->Bailout(reason); |
| 784 } | 781 } |
| 785 | 782 |
| 786 | 783 |
| 787 // <Statement> ::= Return { value: <Expression> | 784 // <Statement> ::= Return { value: <Expression> |
| 788 // inlined_finally_list: <InlinedFinally>* } | 785 // inlined_finally_list: <InlinedFinally>* } |
| 789 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 786 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 790 ValueGraphVisitor for_value(owner(), temp_index()); | 787 ValueGraphVisitor for_value(owner()); |
| 791 node->value()->Visit(&for_value); | 788 node->value()->Visit(&for_value); |
| 792 Append(for_value); | 789 Append(for_value); |
| 793 | 790 |
| 794 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 791 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 795 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); | 792 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); |
| 796 EffectGraphVisitor for_effect(owner(), temp_index()); | 793 EffectGraphVisitor for_effect(owner()); |
| 797 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 794 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 798 Append(for_effect); | 795 Append(for_effect); |
| 799 if (!is_open()) return; | 796 if (!is_open()) { |
| 797 owner()->DeallocateTemps(owner()->temp_count()); |
| 798 return; |
| 799 } |
| 800 } | 800 } |
| 801 | 801 |
| 802 Value* return_value = for_value.value(); | 802 Value* return_value = for_value.value(); |
| 803 if (FLAG_enable_type_checks) { | 803 if (FLAG_enable_type_checks) { |
| 804 const Function& function = owner()->parsed_function()->function(); | 804 const Function& function = owner()->parsed_function()->function(); |
| 805 const bool is_implicit_dynamic_getter = | 805 const bool is_implicit_dynamic_getter = |
| 806 (!function.is_static() && | 806 (!function.is_static() && |
| 807 ((function.kind() == RawFunction::kImplicitGetter) || | 807 ((function.kind() == RawFunction::kImplicitGetter) || |
| 808 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); | 808 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); |
| 809 // Implicit getters do not need a type check at return, unless they compute | 809 // Implicit getters do not need a type check at return, unless they compute |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 eliminated); | 916 eliminated); |
| 917 } | 917 } |
| 918 return eliminated; | 918 return eliminated; |
| 919 } | 919 } |
| 920 | 920 |
| 921 | 921 |
| 922 // <Expression> :: Assignable { expr: <Expression> | 922 // <Expression> :: Assignable { expr: <Expression> |
| 923 // type: AbstractType | 923 // type: AbstractType |
| 924 // dst_name: String } | 924 // dst_name: String } |
| 925 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 925 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 926 ValueGraphVisitor for_value(owner(), temp_index()); | 926 ValueGraphVisitor for_value(owner()); |
| 927 node->expr()->Visit(&for_value); | 927 node->expr()->Visit(&for_value); |
| 928 Append(for_value); | 928 Append(for_value); |
| 929 Definition* checked_value; | 929 Definition* checked_value; |
| 930 if (CanSkipTypeCheck(node->expr()->token_pos(), | 930 if (CanSkipTypeCheck(node->expr()->token_pos(), |
| 931 for_value.value(), | 931 for_value.value(), |
| 932 node->type(), | 932 node->type(), |
| 933 node->dst_name())) { | 933 node->dst_name())) { |
| 934 // Drop the value and 0 additional temporaries. | 934 // Drop the value and 0 additional temporaries. |
| 935 checked_value = new DropTempsInstr(0, for_value.value()); | 935 checked_value = new DropTempsInstr(0, for_value.value()); |
| 936 } else { | 936 } else { |
| 937 checked_value = BuildAssertAssignable(node->expr()->token_pos(), | 937 checked_value = BuildAssertAssignable(node->expr()->token_pos(), |
| 938 for_value.value(), | 938 for_value.value(), |
| 939 node->type(), | 939 node->type(), |
| 940 node->dst_name()); | 940 node->dst_name()); |
| 941 } | 941 } |
| 942 ReturnDefinition(checked_value); | 942 ReturnDefinition(checked_value); |
| 943 } | 943 } |
| 944 | 944 |
| 945 | 945 |
| 946 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 946 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 947 ValueGraphVisitor for_value(owner(), temp_index()); | 947 ValueGraphVisitor for_value(owner()); |
| 948 node->expr()->Visit(&for_value); | 948 node->expr()->Visit(&for_value); |
| 949 Append(for_value); | 949 Append(for_value); |
| 950 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 950 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 951 for_value.value(), | 951 for_value.value(), |
| 952 node->type(), | 952 node->type(), |
| 953 node->dst_name())); | 953 node->dst_name())); |
| 954 } | 954 } |
| 955 | 955 |
| 956 | 956 |
| 957 // <Expression> :: BinaryOp { kind: Token::Kind | 957 // <Expression> :: BinaryOp { kind: Token::Kind |
| 958 // left: <Expression> | 958 // left: <Expression> |
| 959 // right: <Expression> } | 959 // right: <Expression> } |
| 960 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 960 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 961 // Operators "&&" and "||" cannot be overloaded therefore do not call | 961 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 962 // operator. | 962 // operator. |
| 963 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 963 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 964 // See ValueGraphVisitor::VisitBinaryOpNode. | 964 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 965 TestGraphVisitor for_left(owner(), | 965 TestGraphVisitor for_left(owner(), node->left()->token_pos()); |
| 966 temp_index(), | |
| 967 node->left()->token_pos()); | |
| 968 node->left()->Visit(&for_left); | 966 node->left()->Visit(&for_left); |
| 969 EffectGraphVisitor empty(owner(), temp_index()); | 967 EffectGraphVisitor empty(owner()); |
| 970 if (FLAG_enable_type_checks) { | 968 if (FLAG_enable_type_checks) { |
| 971 ValueGraphVisitor for_right(owner(), temp_index()); | 969 ValueGraphVisitor for_right(owner()); |
| 972 node->right()->Visit(&for_right); | 970 node->right()->Visit(&for_right); |
| 973 Value* right_value = for_right.value(); | 971 Value* right_value = for_right.value(); |
| 974 for_right.Do(new AssertBooleanInstr(node->right()->token_pos(), | 972 for_right.Do(new AssertBooleanInstr(node->right()->token_pos(), |
| 975 right_value)); | 973 right_value)); |
| 976 if (node->kind() == Token::kAND) { | 974 if (node->kind() == Token::kAND) { |
| 977 Join(for_left, for_right, empty); | 975 Join(for_left, for_right, empty); |
| 978 } else { | 976 } else { |
| 979 Join(for_left, empty, for_right); | 977 Join(for_left, empty, for_right); |
| 980 } | 978 } |
| 981 } else { | 979 } else { |
| 982 EffectGraphVisitor for_right(owner(), temp_index()); | 980 EffectGraphVisitor for_right(owner()); |
| 983 node->right()->Visit(&for_right); | 981 node->right()->Visit(&for_right); |
| 984 if (node->kind() == Token::kAND) { | 982 if (node->kind() == Token::kAND) { |
| 985 Join(for_left, for_right, empty); | 983 Join(for_left, for_right, empty); |
| 986 } else { | 984 } else { |
| 987 Join(for_left, empty, for_right); | 985 Join(for_left, empty, for_right); |
| 988 } | 986 } |
| 989 } | 987 } |
| 990 return; | 988 return; |
| 991 } | 989 } |
| 992 ValueGraphVisitor for_left_value(owner(), temp_index()); | 990 ValueGraphVisitor for_left_value(owner()); |
| 993 node->left()->Visit(&for_left_value); | 991 node->left()->Visit(&for_left_value); |
| 994 Append(for_left_value); | 992 Append(for_left_value); |
| 995 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 993 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 996 | 994 |
| 997 ValueGraphVisitor for_right_value(owner(), temp_index()); | 995 ValueGraphVisitor for_right_value(owner()); |
| 998 node->right()->Visit(&for_right_value); | 996 node->right()->Visit(&for_right_value); |
| 999 Append(for_right_value); | 997 Append(for_right_value); |
| 1000 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 998 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1001 | 999 |
| 1002 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1000 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1003 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1001 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1004 arguments->Add(push_left); | 1002 arguments->Add(push_left); |
| 1005 arguments->Add(push_right); | 1003 arguments->Add(push_right); |
| 1006 const String& name = String::ZoneHandle(Symbols::New(node->TokenName())); | 1004 const String& name = String::ZoneHandle(Symbols::New(node->TokenName())); |
| 1007 const intptr_t kNumArgsChecked = 2; | 1005 const intptr_t kNumArgsChecked = 2; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1019 // Special handling for AND/OR. | 1017 // Special handling for AND/OR. |
| 1020 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 1018 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 1021 // Operators "&&" and "||" cannot be overloaded therefore do not call | 1019 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 1022 // operator. | 1020 // operator. |
| 1023 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 1021 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 1024 // Implement short-circuit logic: do not evaluate right if evaluation | 1022 // Implement short-circuit logic: do not evaluate right if evaluation |
| 1025 // of left is sufficient. | 1023 // of left is sufficient. |
| 1026 // AND: left ? right === true : false; | 1024 // AND: left ? right === true : false; |
| 1027 // OR: left ? true : right === true; | 1025 // OR: left ? true : right === true; |
| 1028 | 1026 |
| 1029 TestGraphVisitor for_test(owner(), | 1027 TestGraphVisitor for_test(owner(), node->left()->token_pos()); |
| 1030 temp_index(), | |
| 1031 node->left()->token_pos()); | |
| 1032 node->left()->Visit(&for_test); | 1028 node->left()->Visit(&for_test); |
| 1033 | 1029 |
| 1034 ValueGraphVisitor for_right(owner(), temp_index()); | 1030 ValueGraphVisitor for_right(owner()); |
| 1035 node->right()->Visit(&for_right); | 1031 node->right()->Visit(&for_right); |
| 1036 Value* right_value = for_right.value(); | 1032 Value* right_value = for_right.value(); |
| 1037 if (FLAG_enable_type_checks) { | 1033 if (FLAG_enable_type_checks) { |
| 1038 right_value = | 1034 right_value = |
| 1039 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 1035 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 1040 right_value)); | 1036 right_value)); |
| 1041 } | 1037 } |
| 1042 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); | 1038 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); |
| 1043 Value* compare = | 1039 Value* compare = |
| 1044 for_right.Bind(new StrictCompareInstr(node->token_pos(), | 1040 for_right.Bind(new StrictCompareInstr(node->token_pos(), |
| 1045 Token::kEQ_STRICT, | 1041 Token::kEQ_STRICT, |
| 1046 right_value, | 1042 right_value, |
| 1047 constant_true)); | 1043 constant_true)); |
| 1048 for_right.Do(BuildStoreExprTemp(compare)); | 1044 for_right.Do(BuildStoreExprTemp(compare)); |
| 1049 | 1045 |
| 1050 if (node->kind() == Token::kAND) { | 1046 if (node->kind() == Token::kAND) { |
| 1051 ValueGraphVisitor for_false(owner(), temp_index()); | 1047 ValueGraphVisitor for_false(owner()); |
| 1052 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); | 1048 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); |
| 1053 for_false.Do(BuildStoreExprTemp(constant_false)); | 1049 for_false.Do(BuildStoreExprTemp(constant_false)); |
| 1054 Join(for_test, for_right, for_false); | 1050 Join(for_test, for_right, for_false); |
| 1055 } else { | 1051 } else { |
| 1056 ASSERT(node->kind() == Token::kOR); | 1052 ASSERT(node->kind() == Token::kOR); |
| 1057 ValueGraphVisitor for_true(owner(), temp_index()); | 1053 ValueGraphVisitor for_true(owner()); |
| 1058 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); | 1054 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); |
| 1059 for_true.Do(BuildStoreExprTemp(constant_true)); | 1055 for_true.Do(BuildStoreExprTemp(constant_true)); |
| 1060 Join(for_test, for_true, for_right); | 1056 Join(for_test, for_true, for_right); |
| 1061 } | 1057 } |
| 1062 ReturnDefinition(BuildLoadExprTemp()); | 1058 ReturnDefinition(BuildLoadExprTemp()); |
| 1063 return; | 1059 return; |
| 1064 } | 1060 } |
| 1065 EffectGraphVisitor::VisitBinaryOpNode(node); | 1061 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 1066 } | 1062 } |
| 1067 | 1063 |
| 1068 | 1064 |
| 1069 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { | 1065 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { |
| 1070 if (node->kind() == Token::kSHL) { | 1066 if (node->kind() == Token::kSHL) { |
| 1071 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); | 1067 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); |
| 1072 } | 1068 } |
| 1073 UNIMPLEMENTED(); | 1069 UNIMPLEMENTED(); |
| 1074 return String::ZoneHandle(); | 1070 return String::ZoneHandle(); |
| 1075 } | 1071 } |
| 1076 | 1072 |
| 1077 | 1073 |
| 1078 // <Expression> :: BinaryOp { kind: Token::Kind | 1074 // <Expression> :: BinaryOp { kind: Token::Kind |
| 1079 // left: <Expression> | 1075 // left: <Expression> |
| 1080 // right: <Expression> | 1076 // right: <Expression> |
| 1081 // mask32: constant } | 1077 // mask32: constant } |
| 1082 void EffectGraphVisitor::VisitBinaryOpWithMask32Node( | 1078 void EffectGraphVisitor::VisitBinaryOpWithMask32Node( |
| 1083 BinaryOpWithMask32Node* node) { | 1079 BinaryOpWithMask32Node* node) { |
| 1084 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR)); | 1080 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR)); |
| 1085 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1081 ValueGraphVisitor for_left_value(owner()); |
| 1086 node->left()->Visit(&for_left_value); | 1082 node->left()->Visit(&for_left_value); |
| 1087 Append(for_left_value); | 1083 Append(for_left_value); |
| 1088 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1084 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1089 | 1085 |
| 1090 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1086 ValueGraphVisitor for_right_value(owner()); |
| 1091 node->right()->Visit(&for_right_value); | 1087 node->right()->Visit(&for_right_value); |
| 1092 Append(for_right_value); | 1088 Append(for_right_value); |
| 1093 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1089 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1094 | 1090 |
| 1095 Value* mask_value = Bind(new ConstantInstr( | 1091 Value* mask_value = Bind(new ConstantInstr( |
| 1096 Integer::ZoneHandle(Integer::New(node->mask32(), Heap::kOld)))); | 1092 Integer::ZoneHandle(Integer::New(node->mask32(), Heap::kOld)))); |
| 1097 PushArgumentInstr* push_mask = PushArgument(mask_value); | 1093 PushArgumentInstr* push_mask = PushArgument(mask_value); |
| 1098 | 1094 |
| 1099 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1095 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1100 new ZoneGrowableArray<PushArgumentInstr*>(3); | 1096 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 const String& dst_name) { | 1204 const String& dst_name) { |
| 1209 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 1205 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 1210 return value; | 1206 return value; |
| 1211 } | 1207 } |
| 1212 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 1208 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 1213 } | 1209 } |
| 1214 | 1210 |
| 1215 | 1211 |
| 1216 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1212 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1217 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1213 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1218 EffectGraphVisitor for_left_value(owner(), temp_index()); | 1214 EffectGraphVisitor for_left_value(owner()); |
| 1219 node->left()->Visit(&for_left_value); | 1215 node->left()->Visit(&for_left_value); |
| 1220 Append(for_left_value); | 1216 Append(for_left_value); |
| 1221 } | 1217 } |
| 1222 | 1218 |
| 1223 | 1219 |
| 1224 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1220 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1225 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1221 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1226 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1222 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1227 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1223 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); |
| 1228 const bool negate_result = (node->kind() == Token::kISNOT); | 1224 const bool negate_result = (node->kind() == Token::kISNOT); |
| 1229 // All objects are instances of type T if Object type is a subtype of type T. | 1225 // All objects are instances of type T if Object type is a subtype of type T. |
| 1230 const Type& object_type = Type::Handle(Type::ObjectType()); | 1226 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 1231 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 1227 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 1232 // Must evaluate left side. | 1228 // Must evaluate left side. |
| 1233 EffectGraphVisitor for_left_value(owner(), temp_index()); | 1229 EffectGraphVisitor for_left_value(owner()); |
| 1234 node->left()->Visit(&for_left_value); | 1230 node->left()->Visit(&for_left_value); |
| 1235 Append(for_left_value); | 1231 Append(for_left_value); |
| 1236 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); | 1232 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); |
| 1237 return; | 1233 return; |
| 1238 } | 1234 } |
| 1239 | 1235 |
| 1240 // Eliminate the test if it can be performed successfully at compile time. | 1236 // Eliminate the test if it can be performed successfully at compile time. |
| 1241 if ((node->left() != NULL) && | 1237 if ((node->left() != NULL) && |
| 1242 node->left()->IsLiteralNode() && | 1238 node->left()->IsLiteralNode() && |
| 1243 type.IsInstantiated()) { | 1239 type.IsInstantiated()) { |
| 1244 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 1240 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
| 1245 ConstantInstr* result = NULL; | 1241 ConstantInstr* result = NULL; |
| 1246 | 1242 |
| 1247 Error& malformed_error = Error::Handle(); | 1243 Error& malformed_error = Error::Handle(); |
| 1248 if (literal_value.IsInstanceOf(type, | 1244 if (literal_value.IsInstanceOf(type, |
| 1249 TypeArguments::Handle(), | 1245 TypeArguments::Handle(), |
| 1250 &malformed_error)) { | 1246 &malformed_error)) { |
| 1251 result = new ConstantInstr(Bool::Get(!negate_result)); | 1247 result = new ConstantInstr(Bool::Get(!negate_result)); |
| 1252 } else { | 1248 } else { |
| 1253 result = new ConstantInstr(Bool::Get(negate_result)); | 1249 result = new ConstantInstr(Bool::Get(negate_result)); |
| 1254 } | 1250 } |
| 1255 ASSERT(malformed_error.IsNull()); | 1251 ASSERT(malformed_error.IsNull()); |
| 1256 | 1252 |
| 1257 ReturnDefinition(result); | 1253 ReturnDefinition(result); |
| 1258 return; | 1254 return; |
| 1259 } | 1255 } |
| 1260 | 1256 |
| 1261 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1257 ValueGraphVisitor for_left_value(owner()); |
| 1262 node->left()->Visit(&for_left_value); | 1258 node->left()->Visit(&for_left_value); |
| 1263 Append(for_left_value); | 1259 Append(for_left_value); |
| 1264 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1260 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1265 PushArgumentInstr* push_instantiator = NULL; | 1261 PushArgumentInstr* push_instantiator = NULL; |
| 1266 PushArgumentInstr* push_type_args = NULL; | 1262 PushArgumentInstr* push_type_args = NULL; |
| 1267 if (type.IsInstantiated()) { | 1263 if (type.IsInstantiated()) { |
| 1268 push_instantiator = PushArgument(BuildNullValue()); | 1264 push_instantiator = PushArgument(BuildNullValue()); |
| 1269 push_type_args = PushArgument(BuildNullValue()); | 1265 push_type_args = PushArgument(BuildNullValue()); |
| 1270 } else { | 1266 } else { |
| 1271 BuildTypecheckPushArguments(node->token_pos(), | 1267 BuildTypecheckPushArguments(node->token_pos(), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1294 kNumArgsChecked, | 1290 kNumArgsChecked, |
| 1295 owner()->ic_data_array()); | 1291 owner()->ic_data_array()); |
| 1296 ReturnDefinition(call); | 1292 ReturnDefinition(call); |
| 1297 } | 1293 } |
| 1298 | 1294 |
| 1299 | 1295 |
| 1300 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 1296 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1301 ASSERT(Token::IsTypeCastOperator(node->kind())); | 1297 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1302 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1298 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1303 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1299 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); |
| 1304 ValueGraphVisitor for_value(owner(), temp_index()); | 1300 ValueGraphVisitor for_value(owner()); |
| 1305 node->left()->Visit(&for_value); | 1301 node->left()->Visit(&for_value); |
| 1306 Append(for_value); | 1302 Append(for_value); |
| 1307 const String& dst_name = String::ZoneHandle( | 1303 const String& dst_name = String::ZoneHandle( |
| 1308 Symbols::New(Exceptions::kCastErrorDstName)); | 1304 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1309 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 1305 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 1310 // Drop the value and 0 additional temporaries. | 1306 // Drop the value and 0 additional temporaries. |
| 1311 Do(new DropTempsInstr(0, for_value.value())); | 1307 Do(new DropTempsInstr(0, for_value.value())); |
| 1312 } else { | 1308 } else { |
| 1313 Do(BuildAssertAssignable(node->token_pos(), | 1309 Do(BuildAssertAssignable(node->token_pos(), |
| 1314 for_value.value(), | 1310 for_value.value(), |
| 1315 type, | 1311 type, |
| 1316 dst_name)); | 1312 dst_name)); |
| 1317 } | 1313 } |
| 1318 } | 1314 } |
| 1319 | 1315 |
| 1320 | 1316 |
| 1321 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 1317 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 1322 ASSERT(Token::IsTypeCastOperator(node->kind())); | 1318 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 1323 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 1319 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
| 1324 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1320 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1325 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); | 1321 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); |
| 1326 ValueGraphVisitor for_value(owner(), temp_index()); | 1322 ValueGraphVisitor for_value(owner()); |
| 1327 node->left()->Visit(&for_value); | 1323 node->left()->Visit(&for_value); |
| 1328 Append(for_value); | 1324 Append(for_value); |
| 1329 const String& dst_name = String::ZoneHandle( | 1325 const String& dst_name = String::ZoneHandle( |
| 1330 Symbols::New(Exceptions::kCastErrorDstName)); | 1326 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1331 if (CanSkipTypeCheck(node->token_pos(), | 1327 if (CanSkipTypeCheck(node->token_pos(), |
| 1332 for_value.value(), | 1328 for_value.value(), |
| 1333 type, | 1329 type, |
| 1334 dst_name)) { | 1330 dst_name)) { |
| 1335 ReturnValue(for_value.value()); | 1331 ReturnValue(for_value.value()); |
| 1336 return; | 1332 return; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 if (Token::IsTypeTestOperator(node->kind())) { | 1370 if (Token::IsTypeTestOperator(node->kind())) { |
| 1375 BuildTypeTest(node); | 1371 BuildTypeTest(node); |
| 1376 return; | 1372 return; |
| 1377 } | 1373 } |
| 1378 if (Token::IsTypeCastOperator(node->kind())) { | 1374 if (Token::IsTypeCastOperator(node->kind())) { |
| 1379 BuildTypeCast(node); | 1375 BuildTypeCast(node); |
| 1380 return; | 1376 return; |
| 1381 } | 1377 } |
| 1382 if ((node->kind() == Token::kEQ_STRICT) || | 1378 if ((node->kind() == Token::kEQ_STRICT) || |
| 1383 (node->kind() == Token::kNE_STRICT)) { | 1379 (node->kind() == Token::kNE_STRICT)) { |
| 1384 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1380 ValueGraphVisitor for_left_value(owner()); |
| 1385 node->left()->Visit(&for_left_value); | 1381 node->left()->Visit(&for_left_value); |
| 1386 Append(for_left_value); | 1382 Append(for_left_value); |
| 1387 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1383 ValueGraphVisitor for_right_value(owner()); |
| 1388 node->right()->Visit(&for_right_value); | 1384 node->right()->Visit(&for_right_value); |
| 1389 Append(for_right_value); | 1385 Append(for_right_value); |
| 1390 StrictCompareInstr* comp = new StrictCompareInstr(node->token_pos(), | 1386 StrictCompareInstr* comp = new StrictCompareInstr(node->token_pos(), |
| 1391 node->kind(), | 1387 node->kind(), |
| 1392 for_left_value.value(), | 1388 for_left_value.value(), |
| 1393 for_right_value.value()); | 1389 for_right_value.value()); |
| 1394 ReturnDefinition(comp); | 1390 ReturnDefinition(comp); |
| 1395 return; | 1391 return; |
| 1396 } | 1392 } |
| 1397 | 1393 |
| 1398 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 1394 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 1399 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1395 ValueGraphVisitor for_left_value(owner()); |
| 1400 node->left()->Visit(&for_left_value); | 1396 node->left()->Visit(&for_left_value); |
| 1401 Append(for_left_value); | 1397 Append(for_left_value); |
| 1402 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1398 ValueGraphVisitor for_right_value(owner()); |
| 1403 node->right()->Visit(&for_right_value); | 1399 node->right()->Visit(&for_right_value); |
| 1404 Append(for_right_value); | 1400 Append(for_right_value); |
| 1405 if (FLAG_enable_type_checks) { | 1401 if (FLAG_enable_type_checks) { |
| 1406 EqualityCompareInstr* comp = new EqualityCompareInstr( | 1402 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| 1407 node->token_pos(), | 1403 node->token_pos(), |
| 1408 Token::kEQ, | 1404 Token::kEQ, |
| 1409 for_left_value.value(), | 1405 for_left_value.value(), |
| 1410 for_right_value.value(), | 1406 for_right_value.value(), |
| 1411 owner()->ic_data_array()); | 1407 owner()->ic_data_array()); |
| 1412 if (node->kind() == Token::kEQ) { | 1408 if (node->kind() == Token::kEQ) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1424 for_right_value.value(), | 1420 for_right_value.value(), |
| 1425 owner()->ic_data_array()); | 1421 owner()->ic_data_array()); |
| 1426 ReturnDefinition(comp); | 1422 ReturnDefinition(comp); |
| 1427 } | 1423 } |
| 1428 return; | 1424 return; |
| 1429 } | 1425 } |
| 1430 | 1426 |
| 1431 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1427 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1432 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1428 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1433 | 1429 |
| 1434 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1430 ValueGraphVisitor for_left_value(owner()); |
| 1435 node->left()->Visit(&for_left_value); | 1431 node->left()->Visit(&for_left_value); |
| 1436 Append(for_left_value); | 1432 Append(for_left_value); |
| 1437 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1433 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1438 arguments->Add(push_left); | 1434 arguments->Add(push_left); |
| 1439 | 1435 |
| 1440 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1436 ValueGraphVisitor for_right_value(owner()); |
| 1441 node->right()->Visit(&for_right_value); | 1437 node->right()->Visit(&for_right_value); |
| 1442 Append(for_right_value); | 1438 Append(for_right_value); |
| 1443 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1439 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1444 arguments->Add(push_right); | 1440 arguments->Add(push_right); |
| 1445 | 1441 |
| 1446 ASSERT(Token::IsRelationalOperator(node->kind())); | 1442 ASSERT(Token::IsRelationalOperator(node->kind())); |
| 1447 InstanceCallInstr* comp = | 1443 InstanceCallInstr* comp = |
| 1448 new InstanceCallInstr(node->token_pos(), | 1444 new InstanceCallInstr(node->token_pos(), |
| 1449 String::ZoneHandle(Symbols::New(node->TokenName())), | 1445 String::ZoneHandle(Symbols::New(node->TokenName())), |
| 1450 node->kind(), | 1446 node->kind(), |
| 1451 arguments, | 1447 arguments, |
| 1452 Object::null_array(), | 1448 Object::null_array(), |
| 1453 2, | 1449 2, |
| 1454 owner()->ic_data_array()); | 1450 owner()->ic_data_array()); |
| 1455 ReturnDefinition(comp); | 1451 ReturnDefinition(comp); |
| 1456 } | 1452 } |
| 1457 | 1453 |
| 1458 | 1454 |
| 1459 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1455 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 1460 // "!" cannot be overloaded, therefore do not call operator. | 1456 // "!" cannot be overloaded, therefore do not call operator. |
| 1461 if (node->kind() == Token::kNOT) { | 1457 if (node->kind() == Token::kNOT) { |
| 1462 ValueGraphVisitor for_value(owner(), temp_index()); | 1458 ValueGraphVisitor for_value(owner()); |
| 1463 node->operand()->Visit(&for_value); | 1459 node->operand()->Visit(&for_value); |
| 1464 Append(for_value); | 1460 Append(for_value); |
| 1465 Value* value = for_value.value(); | 1461 Value* value = for_value.value(); |
| 1466 if (FLAG_enable_type_checks) { | 1462 if (FLAG_enable_type_checks) { |
| 1467 value = | 1463 value = |
| 1468 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 1464 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 1469 } | 1465 } |
| 1470 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 1466 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 1471 ReturnDefinition(negate); | 1467 ReturnDefinition(negate); |
| 1472 return; | 1468 return; |
| 1473 } | 1469 } |
| 1474 | 1470 |
| 1475 ValueGraphVisitor for_value(owner(), temp_index()); | 1471 ValueGraphVisitor for_value(owner()); |
| 1476 node->operand()->Visit(&for_value); | 1472 node->operand()->Visit(&for_value); |
| 1477 Append(for_value); | 1473 Append(for_value); |
| 1478 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 1474 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 1479 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1475 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1480 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1476 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1481 arguments->Add(push_value); | 1477 arguments->Add(push_value); |
| 1482 InstanceCallInstr* call = | 1478 InstanceCallInstr* call = |
| 1483 new InstanceCallInstr(node->token_pos(), | 1479 new InstanceCallInstr(node->token_pos(), |
| 1484 String::ZoneHandle(Symbols::New(node->TokenName())), | 1480 String::ZoneHandle(Symbols::New(node->TokenName())), |
| 1485 node->kind(), | 1481 node->kind(), |
| 1486 arguments, | 1482 arguments, |
| 1487 Object::null_array(), | 1483 Object::null_array(), |
| 1488 1, | 1484 1, |
| 1489 owner()->ic_data_array()); | 1485 owner()->ic_data_array()); |
| 1490 ReturnDefinition(call); | 1486 ReturnDefinition(call); |
| 1491 } | 1487 } |
| 1492 | 1488 |
| 1493 | 1489 |
| 1494 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1490 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1495 TestGraphVisitor for_test(owner(), | 1491 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1496 temp_index(), | |
| 1497 node->condition()->token_pos()); | |
| 1498 node->condition()->Visit(&for_test); | 1492 node->condition()->Visit(&for_test); |
| 1499 | 1493 |
| 1500 // Translate the subexpressions for their effects. | 1494 // Translate the subexpressions for their effects. |
| 1501 EffectGraphVisitor for_true(owner(), temp_index()); | 1495 EffectGraphVisitor for_true(owner()); |
| 1502 node->true_expr()->Visit(&for_true); | 1496 node->true_expr()->Visit(&for_true); |
| 1503 EffectGraphVisitor for_false(owner(), temp_index()); | 1497 EffectGraphVisitor for_false(owner()); |
| 1504 node->false_expr()->Visit(&for_false); | 1498 node->false_expr()->Visit(&for_false); |
| 1505 | 1499 |
| 1506 Join(for_test, for_true, for_false); | 1500 Join(for_test, for_true, for_false); |
| 1507 } | 1501 } |
| 1508 | 1502 |
| 1509 | 1503 |
| 1510 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1504 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1511 TestGraphVisitor for_test(owner(), | 1505 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1512 temp_index(), | |
| 1513 node->condition()->token_pos()); | |
| 1514 node->condition()->Visit(&for_test); | 1506 node->condition()->Visit(&for_test); |
| 1515 | 1507 |
| 1516 ValueGraphVisitor for_true(owner(), temp_index()); | 1508 ValueGraphVisitor for_true(owner()); |
| 1517 node->true_expr()->Visit(&for_true); | 1509 node->true_expr()->Visit(&for_true); |
| 1518 ASSERT(for_true.is_open()); | 1510 ASSERT(for_true.is_open()); |
| 1519 for_true.Do(BuildStoreExprTemp(for_true.value())); | 1511 for_true.Do(BuildStoreExprTemp(for_true.value())); |
| 1520 | 1512 |
| 1521 ValueGraphVisitor for_false(owner(), temp_index()); | 1513 ValueGraphVisitor for_false(owner()); |
| 1522 node->false_expr()->Visit(&for_false); | 1514 node->false_expr()->Visit(&for_false); |
| 1523 ASSERT(for_false.is_open()); | 1515 ASSERT(for_false.is_open()); |
| 1524 for_false.Do(BuildStoreExprTemp(for_false.value())); | 1516 for_false.Do(BuildStoreExprTemp(for_false.value())); |
| 1525 | 1517 |
| 1526 Join(for_test, for_true, for_false); | 1518 Join(for_test, for_true, for_false); |
| 1527 ReturnDefinition(BuildLoadExprTemp()); | 1519 ReturnDefinition(BuildLoadExprTemp()); |
| 1528 } | 1520 } |
| 1529 | 1521 |
| 1530 | 1522 |
| 1531 // <Statement> ::= If { condition: <Expression> | 1523 // <Statement> ::= If { condition: <Expression> |
| 1532 // true_branch: <Sequence> | 1524 // true_branch: <Sequence> |
| 1533 // false_branch: <Sequence> } | 1525 // false_branch: <Sequence> } |
| 1534 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 1526 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 1535 TestGraphVisitor for_test(owner(), | 1527 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1536 temp_index(), | |
| 1537 node->condition()->token_pos()); | |
| 1538 node->condition()->Visit(&for_test); | 1528 node->condition()->Visit(&for_test); |
| 1539 | 1529 |
| 1540 EffectGraphVisitor for_true(owner(), temp_index()); | 1530 EffectGraphVisitor for_true(owner()); |
| 1541 EffectGraphVisitor for_false(owner(), temp_index()); | 1531 EffectGraphVisitor for_false(owner()); |
| 1542 | 1532 |
| 1543 node->true_branch()->Visit(&for_true); | 1533 node->true_branch()->Visit(&for_true); |
| 1544 // The for_false graph fragment will be empty (default graph fragment) if | 1534 // The for_false graph fragment will be empty (default graph fragment) if |
| 1545 // we do not call Visit. | 1535 // we do not call Visit. |
| 1546 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 1536 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 1547 Join(for_test, for_true, for_false); | 1537 Join(for_test, for_true, for_false); |
| 1548 } | 1538 } |
| 1549 | 1539 |
| 1550 | 1540 |
| 1551 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 1541 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 1552 EffectGraphVisitor switch_body(owner(), temp_index()); | 1542 EffectGraphVisitor switch_body(owner()); |
| 1553 node->body()->Visit(&switch_body); | 1543 node->body()->Visit(&switch_body); |
| 1554 Append(switch_body); | 1544 Append(switch_body); |
| 1555 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 1545 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 1556 if (is_open()) Goto(node->label()->join_for_break()); | 1546 if (is_open()) Goto(node->label()->join_for_break()); |
| 1557 exit_ = node->label()->join_for_break(); | 1547 exit_ = node->label()->join_for_break(); |
| 1558 } | 1548 } |
| 1559 // No continue label allowed. | 1549 // No continue label allowed. |
| 1560 ASSERT((node->label() == NULL) || | 1550 ASSERT((node->label() == NULL) || |
| 1561 (node->label()->join_for_continue() == NULL)); | 1551 (node->label()->join_for_continue() == NULL)); |
| 1562 } | 1552 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1579 // g) case-statements-join | 1569 // g) case-statements-join |
| 1580 // h) [ case-statements ] -> exit-join | 1570 // h) [ case-statements ] -> exit-join |
| 1581 // i) exit-target -> exit-join | 1571 // i) exit-target -> exit-join |
| 1582 // j) exit-join | 1572 // j) exit-join |
| 1583 // | 1573 // |
| 1584 // Note: The specification of switch/case is under discussion and may change | 1574 // Note: The specification of switch/case is under discussion and may change |
| 1585 // drastically. | 1575 // drastically. |
| 1586 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1576 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1587 const intptr_t len = node->case_expressions()->length(); | 1577 const intptr_t len = node->case_expressions()->length(); |
| 1588 // Create case statements instructions. | 1578 // Create case statements instructions. |
| 1589 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 1579 EffectGraphVisitor for_case_statements(owner()); |
| 1590 // Compute start of statements fragment. | 1580 // Compute start of statements fragment. |
| 1591 JoinEntryInstr* statement_start = NULL; | 1581 JoinEntryInstr* statement_start = NULL; |
| 1592 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1582 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1593 // Since a labeled jump continue statement occur in a different case node, | 1583 // Since a labeled jump continue statement occur in a different case node, |
| 1594 // allocate JoinNode here and use it as statement start. | 1584 // allocate JoinNode here and use it as statement start. |
| 1595 statement_start = node->label()->join_for_continue(); | 1585 statement_start = node->label()->join_for_continue(); |
| 1596 if (statement_start == NULL) { | 1586 if (statement_start == NULL) { |
| 1597 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), | 1587 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1598 owner()->try_index()); | 1588 owner()->try_index()); |
| 1599 node->label()->set_join_for_continue(statement_start); | 1589 node->label()->set_join_for_continue(statement_start); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1610 // Default only case node. | 1600 // Default only case node. |
| 1611 Goto(statement_start); | 1601 Goto(statement_start); |
| 1612 exit_ = statement_exit; | 1602 exit_ = statement_exit; |
| 1613 return; | 1603 return; |
| 1614 } | 1604 } |
| 1615 | 1605 |
| 1616 // Generate instructions for all case expressions. | 1606 // Generate instructions for all case expressions. |
| 1617 TargetEntryInstr* next_target = NULL; | 1607 TargetEntryInstr* next_target = NULL; |
| 1618 for (intptr_t i = 0; i < len; i++) { | 1608 for (intptr_t i = 0; i < len; i++) { |
| 1619 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1609 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
| 1620 TestGraphVisitor for_case_expression(owner(), | 1610 TestGraphVisitor for_case_expression(owner(), case_expr->token_pos()); |
| 1621 temp_index(), | |
| 1622 case_expr->token_pos()); | |
| 1623 case_expr->Visit(&for_case_expression); | 1611 case_expr->Visit(&for_case_expression); |
| 1624 if (i == 0) { | 1612 if (i == 0) { |
| 1625 // Append only the first one, everything else is connected from it. | 1613 // Append only the first one, everything else is connected from it. |
| 1626 Append(for_case_expression); | 1614 Append(for_case_expression); |
| 1627 } else { | 1615 } else { |
| 1628 ASSERT(next_target != NULL); | 1616 ASSERT(next_target != NULL); |
| 1629 AppendFragment(next_target, for_case_expression); | 1617 AppendFragment(next_target, for_case_expression); |
| 1630 } | 1618 } |
| 1631 for_case_expression.IfTrueGoto(statement_start); | 1619 for_case_expression.IfTrueGoto(statement_start); |
| 1632 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); | 1620 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 // The fragment is composed as follows: | 1661 // The fragment is composed as follows: |
| 1674 // a) loop-join | 1662 // a) loop-join |
| 1675 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1663 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1676 // c) body-entry-target | 1664 // c) body-entry-target |
| 1677 // d) [ body ] -> (continue-join) | 1665 // d) [ body ] -> (continue-join) |
| 1678 // e) continue-join -> (loop-join) | 1666 // e) continue-join -> (loop-join) |
| 1679 // f) loop-exit-target | 1667 // f) loop-exit-target |
| 1680 // g) break-join (optional) | 1668 // g) break-join (optional) |
| 1681 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1669 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1682 owner()->IncrementLoopDepth(); | 1670 owner()->IncrementLoopDepth(); |
| 1683 TestGraphVisitor for_test(owner(), | 1671 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1684 temp_index(), | |
| 1685 node->condition()->token_pos()); | |
| 1686 node->condition()->Visit(&for_test); | 1672 node->condition()->Visit(&for_test); |
| 1687 ASSERT(!for_test.is_empty()); // Language spec. | 1673 ASSERT(!for_test.is_empty()); // Language spec. |
| 1688 | 1674 |
| 1689 EffectGraphVisitor for_body(owner(), temp_index()); | 1675 EffectGraphVisitor for_body(owner()); |
| 1690 node->body()->Visit(&for_body); | 1676 node->body()->Visit(&for_body); |
| 1691 | 1677 |
| 1692 // Labels are set after body traversal. | 1678 // Labels are set after body traversal. |
| 1693 SourceLabel* lbl = node->label(); | 1679 SourceLabel* lbl = node->label(); |
| 1694 ASSERT(lbl != NULL); | 1680 ASSERT(lbl != NULL); |
| 1695 JoinEntryInstr* join = lbl->join_for_continue(); | 1681 JoinEntryInstr* join = lbl->join_for_continue(); |
| 1696 if (join != NULL) { | 1682 if (join != NULL) { |
| 1697 if (for_body.is_open()) for_body.Goto(join); | 1683 if (for_body.is_open()) for_body.Goto(join); |
| 1698 for_body.exit_ = join; | 1684 for_body.exit_ = join; |
| 1699 } | 1685 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1711 // a) body-entry-join | 1697 // a) body-entry-join |
| 1712 // b) [ body ] | 1698 // b) [ body ] |
| 1713 // c) test-entry (continue-join or body-exit-target) | 1699 // c) test-entry (continue-join or body-exit-target) |
| 1714 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1700 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1715 // e) back-target -> (body-entry-join) | 1701 // e) back-target -> (body-entry-join) |
| 1716 // f) loop-exit-target | 1702 // f) loop-exit-target |
| 1717 // g) break-join | 1703 // g) break-join |
| 1718 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1704 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1719 owner()->IncrementLoopDepth(); | 1705 owner()->IncrementLoopDepth(); |
| 1720 // Traverse body first in order to generate continue and break labels. | 1706 // Traverse body first in order to generate continue and break labels. |
| 1721 EffectGraphVisitor for_body(owner(), temp_index()); | 1707 EffectGraphVisitor for_body(owner()); |
| 1722 node->body()->Visit(&for_body); | 1708 node->body()->Visit(&for_body); |
| 1723 | 1709 |
| 1724 TestGraphVisitor for_test(owner(), | 1710 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1725 temp_index(), | |
| 1726 node->condition()->token_pos()); | |
| 1727 node->condition()->Visit(&for_test); | 1711 node->condition()->Visit(&for_test); |
| 1728 ASSERT(is_open()); | 1712 ASSERT(is_open()); |
| 1729 | 1713 |
| 1730 // Tie do-while loop (test is after the body). | 1714 // Tie do-while loop (test is after the body). |
| 1731 JoinEntryInstr* body_entry_join = | 1715 JoinEntryInstr* body_entry_join = |
| 1732 new JoinEntryInstr(owner()->AllocateBlockId(), | 1716 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1733 owner()->try_index()); | 1717 owner()->try_index()); |
| 1734 Goto(body_entry_join); | 1718 Goto(body_entry_join); |
| 1735 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1719 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1736 | 1720 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1767 // a) [ initializer ] | 1751 // a) [ initializer ] |
| 1768 // b) loop-join | 1752 // b) loop-join |
| 1769 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1753 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1770 // d) body-entry-target | 1754 // d) body-entry-target |
| 1771 // e) [ body ] | 1755 // e) [ body ] |
| 1772 // f) continue-join (optional) | 1756 // f) continue-join (optional) |
| 1773 // g) [ increment ] -> (loop-join) | 1757 // g) [ increment ] -> (loop-join) |
| 1774 // h) loop-exit-target | 1758 // h) loop-exit-target |
| 1775 // i) break-join | 1759 // i) break-join |
| 1776 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1760 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1777 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1761 EffectGraphVisitor for_initializer(owner()); |
| 1778 node->initializer()->Visit(&for_initializer); | 1762 node->initializer()->Visit(&for_initializer); |
| 1779 Append(for_initializer); | 1763 Append(for_initializer); |
| 1780 ASSERT(is_open()); | 1764 ASSERT(is_open()); |
| 1781 | 1765 |
| 1782 owner()->IncrementLoopDepth(); | 1766 owner()->IncrementLoopDepth(); |
| 1783 // Compose body to set any jump labels. | 1767 // Compose body to set any jump labels. |
| 1784 EffectGraphVisitor for_body(owner(), temp_index()); | 1768 EffectGraphVisitor for_body(owner()); |
| 1785 node->body()->Visit(&for_body); | 1769 node->body()->Visit(&for_body); |
| 1786 | 1770 |
| 1787 EffectGraphVisitor for_increment(owner(), temp_index()); | 1771 EffectGraphVisitor for_increment(owner()); |
| 1788 node->increment()->Visit(&for_increment); | 1772 node->increment()->Visit(&for_increment); |
| 1789 | 1773 |
| 1790 // Join the loop body and increment and then tie the loop. | 1774 // Join the loop body and increment and then tie the loop. |
| 1791 JoinEntryInstr* continue_join = node->label()->join_for_continue(); | 1775 JoinEntryInstr* continue_join = node->label()->join_for_continue(); |
| 1792 if ((continue_join != NULL) || for_body.is_open()) { | 1776 if ((continue_join != NULL) || for_body.is_open()) { |
| 1793 JoinEntryInstr* loop_entry = | 1777 JoinEntryInstr* loop_entry = |
| 1794 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1778 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 1795 if (continue_join != NULL) { | 1779 if (continue_join != NULL) { |
| 1796 if (for_body.is_open()) for_body.Goto(continue_join); | 1780 if (for_body.is_open()) for_body.Goto(continue_join); |
| 1797 Instruction* current = AppendFragment(continue_join, for_increment); | 1781 Instruction* current = AppendFragment(continue_join, for_increment); |
| 1798 current->Goto(loop_entry); | 1782 current->Goto(loop_entry); |
| 1799 } else { | 1783 } else { |
| 1800 for_body.Append(for_increment); | 1784 for_body.Append(for_increment); |
| 1801 for_body.Goto(loop_entry); | 1785 for_body.Goto(loop_entry); |
| 1802 } | 1786 } |
| 1803 Goto(loop_entry); | 1787 Goto(loop_entry); |
| 1804 exit_ = loop_entry; | 1788 exit_ = loop_entry; |
| 1805 AddInstruction( | 1789 AddInstruction( |
| 1806 new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth())); | 1790 new CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth())); |
| 1807 } | 1791 } |
| 1808 | 1792 |
| 1809 if (node->condition() == NULL) { | 1793 if (node->condition() == NULL) { |
| 1810 // Endless loop, no test. | 1794 // Endless loop, no test. |
| 1811 Append(for_body); | 1795 Append(for_body); |
| 1812 exit_ = node->label()->join_for_break(); // May be NULL. | 1796 exit_ = node->label()->join_for_break(); // May be NULL. |
| 1813 } else { | 1797 } else { |
| 1814 TestGraphVisitor for_test(owner(), | 1798 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1815 temp_index(), | |
| 1816 node->condition()->token_pos()); | |
| 1817 node->condition()->Visit(&for_test); | 1799 node->condition()->Visit(&for_test); |
| 1818 Append(for_test); | 1800 Append(for_test); |
| 1819 | 1801 |
| 1820 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); | 1802 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); |
| 1821 AppendFragment(body_entry, for_body); | 1803 AppendFragment(body_entry, for_body); |
| 1822 | 1804 |
| 1823 if (node->label()->join_for_break() == NULL) { | 1805 if (node->label()->join_for_break() == NULL) { |
| 1824 exit_ = for_test.CreateFalseSuccessor(); | 1806 exit_ = for_test.CreateFalseSuccessor(); |
| 1825 } else { | 1807 } else { |
| 1826 for_test.IfFalseGoto(node->label()->join_for_break()); | 1808 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1827 exit_ = node->label()->join_for_break(); | 1809 exit_ = node->label()->join_for_break(); |
| 1828 } | 1810 } |
| 1829 } | 1811 } |
| 1830 owner()->DecrementLoopDepth(); | 1812 owner()->DecrementLoopDepth(); |
| 1831 } | 1813 } |
| 1832 | 1814 |
| 1833 | 1815 |
| 1834 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1816 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1835 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1817 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1836 EffectGraphVisitor for_effect(owner(), temp_index()); | 1818 EffectGraphVisitor for_effect(owner()); |
| 1837 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1819 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1838 Append(for_effect); | 1820 Append(for_effect); |
| 1839 if (!is_open()) return; | 1821 if (!is_open()) return; |
| 1840 } | 1822 } |
| 1841 | 1823 |
| 1842 // Unchain the context(s) up to the outer context level of the scope which | 1824 // Unchain the context(s) up to the outer context level of the scope which |
| 1843 // contains the destination label. | 1825 // contains the destination label. |
| 1844 SourceLabel* label = node->label(); | 1826 SourceLabel* label = node->label(); |
| 1845 ASSERT(label->owner() != NULL); | 1827 ASSERT(label->owner() != NULL); |
| 1846 int target_context_level = 0; | 1828 int target_context_level = 0; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1870 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1889 UNREACHABLE(); | 1871 UNREACHABLE(); |
| 1890 } | 1872 } |
| 1891 | 1873 |
| 1892 | 1874 |
| 1893 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 1875 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 1894 return kFirstLocalSlotFromFp | 1876 return kFirstLocalSlotFromFp |
| 1895 - owner()->num_stack_locals() | 1877 - owner()->num_stack_locals() |
| 1896 - owner()->num_copied_params() | 1878 - owner()->num_copied_params() |
| 1897 - owner()->args_pushed() | 1879 - owner()->args_pushed() |
| 1898 - temp_index() + 1; | 1880 - owner()->temp_count() + 1; |
| 1899 } | 1881 } |
| 1900 | 1882 |
| 1901 | 1883 |
| 1902 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { | 1884 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { |
| 1903 Do(new PushTempInstr(value)); | 1885 Do(new PushTempInstr(value)); |
| 1904 AllocateTempIndex(); | 1886 owner()->AllocateTemp(); |
| 1905 | 1887 |
| 1906 ASSERT(value->definition()->temp_index() == temp_index() - 1); | 1888 ASSERT(value->definition()->temp_index() == owner()->temp_count()); |
| 1907 intptr_t index = GetCurrentTempLocalIndex(); | 1889 intptr_t index = GetCurrentTempLocalIndex(); |
| 1908 char name[64]; | 1890 char name[64]; |
| 1909 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 1891 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 1910 LocalVariable* var = | 1892 LocalVariable* var = |
| 1911 new LocalVariable(0, | 1893 new LocalVariable(0, |
| 1912 String::ZoneHandle(Symbols::New(name)), | 1894 String::ZoneHandle(Symbols::New(name)), |
| 1913 *value->Type()->ToAbstractType()); | 1895 *value->Type()->ToAbstractType()); |
| 1914 var->set_index(index); | 1896 var->set_index(index); |
| 1915 return var; | 1897 return var; |
| 1916 } | 1898 } |
| 1917 | 1899 |
| 1918 | 1900 |
| 1919 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { | 1901 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { |
| 1920 Value* tmp = Bind(new LoadLocalInstr(*var)); | 1902 Value* tmp = Bind(new LoadLocalInstr(*var)); |
| 1921 DeallocateTempIndex(1); | 1903 owner()->DeallocateTemps(1); |
| 1922 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 1904 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| 1923 return new DropTempsInstr(1, tmp); | 1905 return new DropTempsInstr(1, tmp); |
| 1924 } | 1906 } |
| 1925 | 1907 |
| 1926 | 1908 |
| 1927 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { | 1909 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 1928 intptr_t num_temps = node->num_temps(); | 1910 intptr_t num_temps = node->num_temps(); |
| 1929 for (intptr_t i = 0; i < num_temps; ++i) { | 1911 for (intptr_t i = 0; i < num_temps; ++i) { |
| 1930 ValueGraphVisitor for_value(owner(), temp_index()); | 1912 ValueGraphVisitor for_value(owner()); |
| 1931 node->InitializerAt(i)->Visit(&for_value); | 1913 node->InitializerAt(i)->Visit(&for_value); |
| 1932 Append(for_value); | 1914 Append(for_value); |
| 1933 Value* temp_val = for_value.value(); | 1915 Value* temp_val = for_value.value(); |
| 1934 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); | 1916 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); |
| 1935 Do(new PushTempInstr(temp_val)); | 1917 Do(new PushTempInstr(temp_val)); |
| 1936 AllocateTempIndex(); | 1918 owner()->AllocateTemp(); |
| 1937 } | 1919 } |
| 1938 } | 1920 } |
| 1939 | 1921 |
| 1940 | 1922 |
| 1941 void EffectGraphVisitor::VisitLetNode(LetNode* node) { | 1923 void EffectGraphVisitor::VisitLetNode(LetNode* node) { |
| 1942 intptr_t num_temps = node->num_temps(); | 1924 intptr_t num_temps = node->num_temps(); |
| 1943 if (num_temps > 0) { | 1925 if (num_temps > 0) { |
| 1944 BuildLetTempExpressions(node); | 1926 BuildLetTempExpressions(node); |
| 1945 // TODO(fschneider): Generate better code for effect context by visiting the | 1927 // TODO(fschneider): Generate better code for effect context by visiting the |
| 1946 // body for effect. Currently, the value of the body expression is | 1928 // body for effect. Currently, the value of the body expression is |
| 1947 // materialized and then dropped. This also requires changing DropTempsInstr | 1929 // materialized and then dropped. This also requires changing DropTempsInstr |
| 1948 // to have zero or one inputs. | 1930 // to have zero or one inputs. |
| 1949 | 1931 |
| 1950 // Visit body. | 1932 // Visit body. |
| 1951 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { | 1933 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { |
| 1952 EffectGraphVisitor for_effect(owner(), temp_index()); | 1934 EffectGraphVisitor for_effect(owner()); |
| 1953 node->nodes()[i]->Visit(&for_effect); | 1935 node->nodes()[i]->Visit(&for_effect); |
| 1954 Append(for_effect); | 1936 Append(for_effect); |
| 1955 } | 1937 } |
| 1956 // Visit the last body expression for value. | 1938 // Visit the last body expression for value. |
| 1957 ValueGraphVisitor for_value(owner(), temp_index()); | 1939 ValueGraphVisitor for_value(owner()); |
| 1958 node->nodes().Last()->Visit(&for_value); | 1940 node->nodes().Last()->Visit(&for_value); |
| 1959 Append(for_value); | 1941 Append(for_value); |
| 1960 Value* result_value = for_value.value(); | 1942 Value* result_value = for_value.value(); |
| 1961 DeallocateTempIndex(num_temps); | 1943 owner()->DeallocateTemps(num_temps); |
| 1962 Do(new DropTempsInstr(num_temps, result_value)); | 1944 Do(new DropTempsInstr(num_temps, result_value)); |
| 1963 } else { | 1945 } else { |
| 1964 ASSERT(num_temps == 0); | 1946 ASSERT(num_temps == 0); |
| 1965 for (intptr_t i = 0; i < node->nodes().length(); ++i) { | 1947 for (intptr_t i = 0; i < node->nodes().length(); ++i) { |
| 1966 EffectGraphVisitor for_effect(owner(), temp_index()); | 1948 EffectGraphVisitor for_effect(owner()); |
| 1967 node->nodes()[i]->Visit(&for_effect); | 1949 node->nodes()[i]->Visit(&for_effect); |
| 1968 Append(for_effect); | 1950 Append(for_effect); |
| 1969 } | 1951 } |
| 1970 } | 1952 } |
| 1971 } | 1953 } |
| 1972 | 1954 |
| 1973 | 1955 |
| 1974 void ValueGraphVisitor::VisitLetNode(LetNode* node) { | 1956 void ValueGraphVisitor::VisitLetNode(LetNode* node) { |
| 1975 BuildLetTempExpressions(node); | 1957 BuildLetTempExpressions(node); |
| 1976 | 1958 |
| 1977 // Visit body. | 1959 // Visit body. |
| 1978 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { | 1960 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { |
| 1979 EffectGraphVisitor for_effect(owner(), temp_index()); | 1961 EffectGraphVisitor for_effect(owner()); |
| 1980 node->nodes()[i]->Visit(&for_effect); | 1962 node->nodes()[i]->Visit(&for_effect); |
| 1981 Append(for_effect); | 1963 Append(for_effect); |
| 1982 } | 1964 } |
| 1983 // Visit the last body expression for value. | 1965 // Visit the last body expression for value. |
| 1984 ValueGraphVisitor for_value(owner(), temp_index()); | 1966 ValueGraphVisitor for_value(owner()); |
| 1985 node->nodes().Last()->Visit(&for_value); | 1967 node->nodes().Last()->Visit(&for_value); |
| 1986 Append(for_value); | 1968 Append(for_value); |
| 1987 Value* result_value = for_value.value(); | 1969 Value* result_value = for_value.value(); |
| 1988 | 1970 |
| 1989 intptr_t num_temps = node->num_temps(); | 1971 intptr_t num_temps = node->num_temps(); |
| 1990 if (num_temps > 0) { | 1972 if (num_temps > 0) { |
| 1991 DeallocateTempIndex(num_temps); | 1973 owner()->DeallocateTemps(num_temps); |
| 1992 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); | 1974 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); |
| 1993 } else { | 1975 } else { |
| 1994 ReturnValue(result_value); | 1976 ReturnValue(result_value); |
| 1995 } | 1977 } |
| 1996 } | 1978 } |
| 1997 | 1979 |
| 1998 | 1980 |
| 1999 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1981 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 2000 const AbstractTypeArguments& type_args = | 1982 const AbstractTypeArguments& type_args = |
| 2001 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1983 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 2002 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1984 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2003 type_args); | 1985 type_args); |
| 2004 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1986 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 2005 node->length(), | 1987 node->length(), |
| 2006 node->type(), | 1988 node->type(), |
| 2007 element_type); | 1989 element_type); |
| 2008 Value* array_val = Bind(create); | 1990 Value* array_val = Bind(create); |
| 2009 | 1991 |
| 2010 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); | 1992 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); |
| 2011 const intptr_t class_id = create->Type()->ToCid(); | 1993 const intptr_t class_id = create->Type()->ToCid(); |
| 2012 const intptr_t deopt_id = Isolate::kNoDeoptId; | 1994 const intptr_t deopt_id = Isolate::kNoDeoptId; |
| 2013 for (int i = 0; i < node->length(); ++i) { | 1995 for (int i = 0; i < node->length(); ++i) { |
| 2014 Value* array = Bind(new LoadLocalInstr(*tmp_var)); | 1996 Value* array = Bind(new LoadLocalInstr(*tmp_var)); |
| 2015 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); | 1997 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); |
| 2016 ValueGraphVisitor for_value(owner(), temp_index()); | 1998 ValueGraphVisitor for_value(owner()); |
| 2017 node->ElementAt(i)->Visit(&for_value); | 1999 node->ElementAt(i)->Visit(&for_value); |
| 2018 Append(for_value); | 2000 Append(for_value); |
| 2019 // No store barrier needed for constants. | 2001 // No store barrier needed for constants. |
| 2020 const StoreBarrierType emit_store_barrier = | 2002 const StoreBarrierType emit_store_barrier = |
| 2021 for_value.value()->BindsToConstant() | 2003 for_value.value()->BindsToConstant() |
| 2022 ? kNoStoreBarrier | 2004 ? kNoStoreBarrier |
| 2023 : kEmitStoreBarrier; | 2005 : kEmitStoreBarrier; |
| 2024 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id); | 2006 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id); |
| 2025 StoreIndexedInstr* store = new StoreIndexedInstr( | 2007 StoreIndexedInstr* store = new StoreIndexedInstr( |
| 2026 array, index, for_value.value(), | 2008 array, index, for_value.value(), |
| 2027 emit_store_barrier, index_scale, class_id, deopt_id); | 2009 emit_store_barrier, index_scale, class_id, deopt_id); |
| 2028 Do(store); | 2010 Do(store); |
| 2029 } | 2011 } |
| 2030 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2012 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 2031 } | 2013 } |
| 2032 } | 2014 } |
| 2033 | 2015 |
| 2034 | 2016 |
| 2035 void EffectGraphVisitor::VisitStringInterpolateNode( | 2017 void EffectGraphVisitor::VisitStringInterpolateNode( |
| 2036 StringInterpolateNode* node) { | 2018 StringInterpolateNode* node) { |
| 2037 ValueGraphVisitor for_argument(owner(), temp_index()); | 2019 ValueGraphVisitor for_argument(owner()); |
| 2038 node->value()->Visit(&for_argument); | 2020 node->value()->Visit(&for_argument); |
| 2039 Append(for_argument); | 2021 Append(for_argument); |
| 2040 StringInterpolateInstr* instr = | 2022 StringInterpolateInstr* instr = |
| 2041 new StringInterpolateInstr(for_argument.value(), node->token_pos()); | 2023 new StringInterpolateInstr(for_argument.value(), node->token_pos()); |
| 2042 ReturnDefinition(instr); | 2024 ReturnDefinition(instr); |
| 2043 } | 2025 } |
| 2044 | 2026 |
| 2045 | 2027 |
| 2046 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 2028 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 2047 const Function& function = node->function(); | 2029 const Function& function = node->function(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | 2128 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2147 Value* context = Bind(new CurrentContextInstr()); | 2129 Value* context = Bind(new CurrentContextInstr()); |
| 2148 Do(new StoreInstanceFieldInstr(context_field, | 2130 Do(new StoreInstanceFieldInstr(context_field, |
| 2149 tmp_val, | 2131 tmp_val, |
| 2150 context, | 2132 context, |
| 2151 kEmitStoreBarrier)); | 2133 kEmitStoreBarrier)); |
| 2152 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2134 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 2153 } | 2135 } |
| 2154 } else { | 2136 } else { |
| 2155 ASSERT(function.IsImplicitInstanceClosureFunction()); | 2137 ASSERT(function.IsImplicitInstanceClosureFunction()); |
| 2156 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2138 ValueGraphVisitor for_receiver(owner()); |
| 2157 node->receiver()->Visit(&for_receiver); | 2139 node->receiver()->Visit(&for_receiver); |
| 2158 Append(for_receiver); | 2140 Append(for_receiver); |
| 2159 Value* receiver = for_receiver.value(); | 2141 Value* receiver = for_receiver.value(); |
| 2160 | 2142 |
| 2161 PushArgumentInstr* push_receiver = PushArgument(receiver); | 2143 PushArgumentInstr* push_receiver = PushArgument(receiver); |
| 2162 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2144 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2163 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2145 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2164 arguments->Add(push_receiver); | 2146 arguments->Add(push_receiver); |
| 2165 ASSERT(function.context_scope() != ContextScope::null()); | 2147 ASSERT(function.context_scope() != ContextScope::null()); |
| 2166 | 2148 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2184 ReturnDefinition( | 2166 ReturnDefinition( |
| 2185 new CreateClosureInstr(node->function(), arguments, node->token_pos())); | 2167 new CreateClosureInstr(node->function(), arguments, node->token_pos())); |
| 2186 } | 2168 } |
| 2187 } | 2169 } |
| 2188 | 2170 |
| 2189 | 2171 |
| 2190 void EffectGraphVisitor::BuildPushArguments( | 2172 void EffectGraphVisitor::BuildPushArguments( |
| 2191 const ArgumentListNode& node, | 2173 const ArgumentListNode& node, |
| 2192 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2174 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 2193 for (intptr_t i = 0; i < node.length(); ++i) { | 2175 for (intptr_t i = 0; i < node.length(); ++i) { |
| 2194 ValueGraphVisitor for_argument(owner(), temp_index()); | 2176 ValueGraphVisitor for_argument(owner()); |
| 2195 node.NodeAt(i)->Visit(&for_argument); | 2177 node.NodeAt(i)->Visit(&for_argument); |
| 2196 Append(for_argument); | 2178 Append(for_argument); |
| 2197 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 2179 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 2198 values->Add(push_arg); | 2180 values->Add(push_arg); |
| 2199 } | 2181 } |
| 2200 } | 2182 } |
| 2201 | 2183 |
| 2202 | 2184 |
| 2203 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 2185 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2204 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2186 ValueGraphVisitor for_receiver(owner()); |
| 2205 node->receiver()->Visit(&for_receiver); | 2187 node->receiver()->Visit(&for_receiver); |
| 2206 Append(for_receiver); | 2188 Append(for_receiver); |
| 2207 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2189 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2208 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2190 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2209 new ZoneGrowableArray<PushArgumentInstr*>( | 2191 new ZoneGrowableArray<PushArgumentInstr*>( |
| 2210 node->arguments()->length() + 1); | 2192 node->arguments()->length() + 1); |
| 2211 arguments->Add(push_receiver); | 2193 arguments->Add(push_receiver); |
| 2212 | 2194 |
| 2213 BuildPushArguments(*node->arguments(), arguments); | 2195 BuildPushArguments(*node->arguments(), arguments); |
| 2214 InstanceCallInstr* call = new InstanceCallInstr( | 2196 InstanceCallInstr* call = new InstanceCallInstr( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 if (node->function().is_native()) { | 2248 if (node->function().is_native()) { |
| 2267 const intptr_t result_cid = GetResultCidOfNative(node->function()); | 2249 const intptr_t result_cid = GetResultCidOfNative(node->function()); |
| 2268 call->set_result_cid(result_cid); | 2250 call->set_result_cid(result_cid); |
| 2269 } | 2251 } |
| 2270 ReturnDefinition(call); | 2252 ReturnDefinition(call); |
| 2271 } | 2253 } |
| 2272 | 2254 |
| 2273 | 2255 |
| 2274 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 2256 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 2275 ClosureCallNode* node) { | 2257 ClosureCallNode* node) { |
| 2276 ValueGraphVisitor for_closure(owner(), temp_index()); | 2258 ValueGraphVisitor for_closure(owner()); |
| 2277 node->closure()->Visit(&for_closure); | 2259 node->closure()->Visit(&for_closure); |
| 2278 Append(for_closure); | 2260 Append(for_closure); |
| 2279 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 2261 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 2280 | 2262 |
| 2281 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2263 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2282 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2264 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2283 arguments->Add(push_closure); | 2265 arguments->Add(push_closure); |
| 2284 BuildPushArguments(*node->arguments(), arguments); | 2266 BuildPushArguments(*node->arguments(), arguments); |
| 2285 | 2267 |
| 2286 // Save context around the call. | 2268 // Save context around the call. |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 Function& outer_function = | 2460 Function& outer_function = |
| 2479 Function::Handle(owner()->parsed_function()->function().raw()); | 2461 Function::Handle(owner()->parsed_function()->function().raw()); |
| 2480 while (outer_function.IsLocalFunction()) { | 2462 while (outer_function.IsLocalFunction()) { |
| 2481 outer_function = outer_function.parent_function(); | 2463 outer_function = outer_function.parent_function(); |
| 2482 } | 2464 } |
| 2483 if (outer_function.IsFactory()) { | 2465 if (outer_function.IsFactory()) { |
| 2484 return NULL; | 2466 return NULL; |
| 2485 } | 2467 } |
| 2486 | 2468 |
| 2487 ASSERT(owner()->parsed_function()->instantiator() != NULL); | 2469 ASSERT(owner()->parsed_function()->instantiator() != NULL); |
| 2488 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 2470 ValueGraphVisitor for_instantiator(owner()); |
| 2489 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); | 2471 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); |
| 2490 Append(for_instantiator); | 2472 Append(for_instantiator); |
| 2491 return for_instantiator.value(); | 2473 return for_instantiator.value(); |
| 2492 } | 2474 } |
| 2493 | 2475 |
| 2494 | 2476 |
| 2495 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2477 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2496 // is not NULL. | 2478 // is not NULL. |
| 2497 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2479 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2498 intptr_t token_pos, | 2480 intptr_t token_pos, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2513 } | 2495 } |
| 2514 Function& outer_function = | 2496 Function& outer_function = |
| 2515 Function::Handle(owner()->parsed_function()->function().raw()); | 2497 Function::Handle(owner()->parsed_function()->function().raw()); |
| 2516 while (outer_function.IsLocalFunction()) { | 2498 while (outer_function.IsLocalFunction()) { |
| 2517 outer_function = outer_function.parent_function(); | 2499 outer_function = outer_function.parent_function(); |
| 2518 } | 2500 } |
| 2519 if (outer_function.IsFactory()) { | 2501 if (outer_function.IsFactory()) { |
| 2520 // No instantiator for factories. | 2502 // No instantiator for factories. |
| 2521 ASSERT(instantiator == NULL); | 2503 ASSERT(instantiator == NULL); |
| 2522 ASSERT(owner()->parsed_function()->instantiator() != NULL); | 2504 ASSERT(owner()->parsed_function()->instantiator() != NULL); |
| 2523 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 2505 ValueGraphVisitor for_instantiator(owner()); |
| 2524 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); | 2506 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); |
| 2525 Append(for_instantiator); | 2507 Append(for_instantiator); |
| 2526 return for_instantiator.value(); | 2508 return for_instantiator.value(); |
| 2527 } | 2509 } |
| 2528 if (instantiator == NULL) { | 2510 if (instantiator == NULL) { |
| 2529 instantiator = BuildInstantiator(); | 2511 instantiator = BuildInstantiator(); |
| 2530 } | 2512 } |
| 2531 // The instantiator is the receiver of the caller, which is not a factory. | 2513 // The instantiator is the receiver of the caller, which is not a factory. |
| 2532 // The receiver cannot be null; extract its AbstractTypeArguments object. | 2514 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 2533 // Note that in the factory case, the instantiator is the first parameter | 2515 // Note that in the factory case, the instantiator is the first parameter |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2651 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); | 2633 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); |
| 2652 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp_var)); | 2634 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp_var)); |
| 2653 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); | 2635 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
| 2654 BuildConstructorCall(node, push_allocated_value); | 2636 BuildConstructorCall(node, push_allocated_value); |
| 2655 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2637 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 2656 } | 2638 } |
| 2657 } | 2639 } |
| 2658 | 2640 |
| 2659 | 2641 |
| 2660 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2642 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 2661 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2643 ValueGraphVisitor for_receiver(owner()); |
| 2662 node->receiver()->Visit(&for_receiver); | 2644 node->receiver()->Visit(&for_receiver); |
| 2663 Append(for_receiver); | 2645 Append(for_receiver); |
| 2664 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2646 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2665 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2647 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2666 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2648 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2667 arguments->Add(push_receiver); | 2649 arguments->Add(push_receiver); |
| 2668 const String& name = | 2650 const String& name = |
| 2669 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 2651 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 2670 InstanceCallInstr* call = new InstanceCallInstr( | 2652 InstanceCallInstr* call = new InstanceCallInstr( |
| 2671 node->token_pos(), | 2653 node->token_pos(), |
| 2672 name, | 2654 name, |
| 2673 Token::kGET, | 2655 Token::kGET, |
| 2674 arguments, Object::null_array(), | 2656 arguments, Object::null_array(), |
| 2675 1, | 2657 1, |
| 2676 owner()->ic_data_array()); | 2658 owner()->ic_data_array()); |
| 2677 ReturnDefinition(call); | 2659 ReturnDefinition(call); |
| 2678 } | 2660 } |
| 2679 | 2661 |
| 2680 | 2662 |
| 2681 void EffectGraphVisitor::BuildInstanceSetterArguments( | 2663 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 2682 InstanceSetterNode* node, | 2664 InstanceSetterNode* node, |
| 2683 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 2665 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 2684 bool result_is_needed) { | 2666 bool result_is_needed) { |
| 2685 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2667 ValueGraphVisitor for_receiver(owner()); |
| 2686 node->receiver()->Visit(&for_receiver); | 2668 node->receiver()->Visit(&for_receiver); |
| 2687 Append(for_receiver); | 2669 Append(for_receiver); |
| 2688 arguments->Add(PushArgument(for_receiver.value())); | 2670 arguments->Add(PushArgument(for_receiver.value())); |
| 2689 | 2671 |
| 2690 ValueGraphVisitor for_value(owner(), temp_index()); | 2672 ValueGraphVisitor for_value(owner()); |
| 2691 node->value()->Visit(&for_value); | 2673 node->value()->Visit(&for_value); |
| 2692 Append(for_value); | 2674 Append(for_value); |
| 2693 | 2675 |
| 2694 Value* value = NULL; | 2676 Value* value = NULL; |
| 2695 if (result_is_needed) { | 2677 if (result_is_needed) { |
| 2696 value = Bind(BuildStoreExprTemp(for_value.value())); | 2678 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2697 } else { | 2679 } else { |
| 2698 value = for_value.value(); | 2680 value = for_value.value(); |
| 2699 } | 2681 } |
| 2700 arguments->Add(PushArgument(value)); | 2682 arguments->Add(PushArgument(value)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2752 StaticCallInstr* call = | 2734 StaticCallInstr* call = |
| 2753 BuildStaticNoSuchMethodCall(node->cls(), | 2735 BuildStaticNoSuchMethodCall(node->cls(), |
| 2754 node->receiver(), | 2736 node->receiver(), |
| 2755 getter_name, | 2737 getter_name, |
| 2756 arguments, | 2738 arguments, |
| 2757 false, // Don't save last argument. | 2739 false, // Don't save last argument. |
| 2758 true); // Super invocation. | 2740 true); // Super invocation. |
| 2759 ReturnDefinition(call); | 2741 ReturnDefinition(call); |
| 2760 return; | 2742 return; |
| 2761 } else { | 2743 } else { |
| 2762 ValueGraphVisitor receiver_value(owner(), temp_index()); | 2744 ValueGraphVisitor receiver_value(owner()); |
| 2763 node->receiver()->Visit(&receiver_value); | 2745 node->receiver()->Visit(&receiver_value); |
| 2764 Append(receiver_value); | 2746 Append(receiver_value); |
| 2765 arguments->Add(PushArgument(receiver_value.value())); | 2747 arguments->Add(PushArgument(receiver_value.value())); |
| 2766 } | 2748 } |
| 2767 } else { | 2749 } else { |
| 2768 getter_function = node->cls().LookupStaticFunction(getter_name); | 2750 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 2769 if (getter_function.IsNull()) { | 2751 if (getter_function.IsNull()) { |
| 2770 // When the parser encounters a reference to a static field materialized | 2752 // When the parser encounters a reference to a static field materialized |
| 2771 // only by a static setter, but no corresponding static getter, it creates | 2753 // only by a static setter, but no corresponding static getter, it creates |
| 2772 // a StaticGetterNode ast node referring to the non-existing static getter | 2754 // a StaticGetterNode ast node referring to the non-existing static getter |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2846 arguments, // Argument is the value passed to the setter. | 2828 arguments, // Argument is the value passed to the setter. |
| 2847 InvocationMirror::EncodeType( | 2829 InvocationMirror::EncodeType( |
| 2848 node->cls().IsTopLevel() ? | 2830 node->cls().IsTopLevel() ? |
| 2849 InvocationMirror::kTopLevel : | 2831 InvocationMirror::kTopLevel : |
| 2850 InvocationMirror::kStatic, | 2832 InvocationMirror::kStatic, |
| 2851 InvocationMirror::kSetter)); | 2833 InvocationMirror::kSetter)); |
| 2852 } | 2834 } |
| 2853 } else { | 2835 } else { |
| 2854 if (is_super_setter) { | 2836 if (is_super_setter) { |
| 2855 // Add receiver of instance getter. | 2837 // Add receiver of instance getter. |
| 2856 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2838 ValueGraphVisitor for_receiver(owner()); |
| 2857 node->receiver()->Visit(&for_receiver); | 2839 node->receiver()->Visit(&for_receiver); |
| 2858 Append(for_receiver); | 2840 Append(for_receiver); |
| 2859 arguments->Add(PushArgument(for_receiver.value())); | 2841 arguments->Add(PushArgument(for_receiver.value())); |
| 2860 } | 2842 } |
| 2861 ValueGraphVisitor for_value(owner(), temp_index()); | 2843 ValueGraphVisitor for_value(owner()); |
| 2862 node->value()->Visit(&for_value); | 2844 node->value()->Visit(&for_value); |
| 2863 Append(for_value); | 2845 Append(for_value); |
| 2864 Value* value = NULL; | 2846 Value* value = NULL; |
| 2865 if (result_is_needed) { | 2847 if (result_is_needed) { |
| 2866 value = Bind(BuildStoreExprTemp(for_value.value())); | 2848 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2867 } else { | 2849 } else { |
| 2868 value = for_value.value(); | 2850 value = for_value.value(); |
| 2869 } | 2851 } |
| 2870 arguments->Add(PushArgument(value)); | 2852 arguments->Add(PushArgument(value)); |
| 2871 | 2853 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3016 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2998 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 3017 Definition* load = BuildLoadLocal(node->local()); | 2999 Definition* load = BuildLoadLocal(node->local()); |
| 3018 ReturnDefinition(load); | 3000 ReturnDefinition(load); |
| 3019 } | 3001 } |
| 3020 | 3002 |
| 3021 | 3003 |
| 3022 // <Expression> ::= StoreLocal { local: LocalVariable | 3004 // <Expression> ::= StoreLocal { local: LocalVariable |
| 3023 // value: <Expression> } | 3005 // value: <Expression> } |
| 3024 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, | 3006 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, |
| 3025 bool result_is_needed) { | 3007 bool result_is_needed) { |
| 3026 ValueGraphVisitor for_value(owner(), temp_index()); | 3008 ValueGraphVisitor for_value(owner()); |
| 3027 node->value()->Visit(&for_value); | 3009 node->value()->Visit(&for_value); |
| 3028 Append(for_value); | 3010 Append(for_value); |
| 3029 Value* store_value = for_value.value(); | 3011 Value* store_value = for_value.value(); |
| 3030 if (FLAG_enable_type_checks) { | 3012 if (FLAG_enable_type_checks) { |
| 3031 store_value = BuildAssignableValue(node->value()->token_pos(), | 3013 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 3032 store_value, | 3014 store_value, |
| 3033 node->local().type(), | 3015 node->local().type(), |
| 3034 node->local().name()); | 3016 node->local().name()); |
| 3035 } | 3017 } |
| 3036 Definition* store = BuildStoreLocal(node->local(), | 3018 Definition* store = BuildStoreLocal(node->local(), |
| 3037 store_value, | 3019 store_value, |
| 3038 result_is_needed); | 3020 result_is_needed); |
| 3039 ReturnDefinition(store); | 3021 ReturnDefinition(store); |
| 3040 } | 3022 } |
| 3041 | 3023 |
| 3042 | 3024 |
| 3043 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 3025 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 3044 HandleStoreLocal(node, kResultNotNeeded); | 3026 HandleStoreLocal(node, kResultNotNeeded); |
| 3045 } | 3027 } |
| 3046 | 3028 |
| 3047 | 3029 |
| 3048 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 3030 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 3049 HandleStoreLocal(node, kResultNeeded); | 3031 HandleStoreLocal(node, kResultNeeded); |
| 3050 } | 3032 } |
| 3051 | 3033 |
| 3052 | 3034 |
| 3053 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 3035 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 3054 LoadInstanceFieldNode* node) { | 3036 LoadInstanceFieldNode* node) { |
| 3055 ValueGraphVisitor for_instance(owner(), temp_index()); | 3037 ValueGraphVisitor for_instance(owner()); |
| 3056 node->instance()->Visit(&for_instance); | 3038 node->instance()->Visit(&for_instance); |
| 3057 Append(for_instance); | 3039 Append(for_instance); |
| 3058 LoadFieldInstr* load = new LoadFieldInstr( | 3040 LoadFieldInstr* load = new LoadFieldInstr( |
| 3059 for_instance.value(), | 3041 for_instance.value(), |
| 3060 node->field().Offset(), | 3042 node->field().Offset(), |
| 3061 AbstractType::ZoneHandle(node->field().type())); | 3043 AbstractType::ZoneHandle(node->field().type())); |
| 3062 load->set_field(&node->field()); | 3044 load->set_field(&node->field()); |
| 3063 if (owner()->exit_collector() != NULL) { | 3045 if (owner()->exit_collector() != NULL) { |
| 3064 // While inlining into an optimized function, the field has | 3046 // While inlining into an optimized function, the field has |
| 3065 // to be added to the list of guarded fields of the caller. | 3047 // to be added to the list of guarded fields of the caller. |
| 3066 if (node->field().guarded_cid() != kIllegalCid) { | 3048 if (node->field().guarded_cid() != kIllegalCid) { |
| 3067 if (!node->field().is_nullable() || | 3049 if (!node->field().is_nullable() || |
| 3068 (node->field().guarded_cid() == kNullCid)) { | 3050 (node->field().guarded_cid() == kNullCid)) { |
| 3069 load->set_result_cid(node->field().guarded_cid()); | 3051 load->set_result_cid(node->field().guarded_cid()); |
| 3070 } | 3052 } |
| 3071 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); | 3053 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); |
| 3072 } | 3054 } |
| 3073 } | 3055 } |
| 3074 ReturnDefinition(load); | 3056 ReturnDefinition(load); |
| 3075 } | 3057 } |
| 3076 | 3058 |
| 3077 | 3059 |
| 3078 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 3060 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 3079 StoreInstanceFieldNode* node) { | 3061 StoreInstanceFieldNode* node) { |
| 3080 ValueGraphVisitor for_instance(owner(), temp_index()); | 3062 ValueGraphVisitor for_instance(owner()); |
| 3081 node->instance()->Visit(&for_instance); | 3063 node->instance()->Visit(&for_instance); |
| 3082 Append(for_instance); | 3064 Append(for_instance); |
| 3083 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 3065 ValueGraphVisitor for_value(owner()); |
| 3084 node->value()->Visit(&for_value); | 3066 node->value()->Visit(&for_value); |
| 3085 Append(for_value); | 3067 Append(for_value); |
| 3086 Value* store_value = for_value.value(); | 3068 Value* store_value = for_value.value(); |
| 3087 if (FLAG_enable_type_checks) { | 3069 if (FLAG_enable_type_checks) { |
| 3088 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 3070 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 3089 const String& dst_name = String::ZoneHandle(node->field().name()); | 3071 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 3090 store_value = BuildAssignableValue(node->value()->token_pos(), | 3072 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 3091 store_value, | 3073 store_value, |
| 3092 type, | 3074 type, |
| 3093 dst_name); | 3075 dst_name); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3126 return ReturnDefinition(result); | 3108 return ReturnDefinition(result); |
| 3127 } | 3109 } |
| 3128 Value* field_value = Bind(new ConstantInstr(node->field())); | 3110 Value* field_value = Bind(new ConstantInstr(node->field())); |
| 3129 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(field_value); | 3111 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(field_value); |
| 3130 ReturnDefinition(load); | 3112 ReturnDefinition(load); |
| 3131 } | 3113 } |
| 3132 | 3114 |
| 3133 | 3115 |
| 3134 Definition* EffectGraphVisitor::BuildStoreStaticField( | 3116 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 3135 StoreStaticFieldNode* node, bool result_is_needed) { | 3117 StoreStaticFieldNode* node, bool result_is_needed) { |
| 3136 ValueGraphVisitor for_value(owner(), temp_index()); | 3118 ValueGraphVisitor for_value(owner()); |
| 3137 node->value()->Visit(&for_value); | 3119 node->value()->Visit(&for_value); |
| 3138 Append(for_value); | 3120 Append(for_value); |
| 3139 Value* store_value = NULL; | 3121 Value* store_value = NULL; |
| 3140 if (result_is_needed) { | 3122 if (result_is_needed) { |
| 3141 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 3123 store_value = Bind(BuildStoreExprTemp(for_value.value())); |
| 3142 } else { | 3124 } else { |
| 3143 store_value = for_value.value(); | 3125 store_value = for_value.value(); |
| 3144 } | 3126 } |
| 3145 if (FLAG_enable_type_checks) { | 3127 if (FLAG_enable_type_checks) { |
| 3146 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 3128 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3191 Symbols::IndexToken(), | 3173 Symbols::IndexToken(), |
| 3192 arguments, | 3174 arguments, |
| 3193 false, // Don't save last arg. | 3175 false, // Don't save last arg. |
| 3194 true); // Super invocation. | 3176 true); // Super invocation. |
| 3195 ReturnDefinition(call); | 3177 ReturnDefinition(call); |
| 3196 return; | 3178 return; |
| 3197 } | 3179 } |
| 3198 } | 3180 } |
| 3199 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3181 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3200 new ZoneGrowableArray<PushArgumentInstr*>(2); | 3182 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 3201 ValueGraphVisitor for_array(owner(), temp_index()); | 3183 ValueGraphVisitor for_array(owner()); |
| 3202 node->array()->Visit(&for_array); | 3184 node->array()->Visit(&for_array); |
| 3203 Append(for_array); | 3185 Append(for_array); |
| 3204 arguments->Add(PushArgument(for_array.value())); | 3186 arguments->Add(PushArgument(for_array.value())); |
| 3205 | 3187 |
| 3206 ValueGraphVisitor for_index(owner(), temp_index()); | 3188 ValueGraphVisitor for_index(owner()); |
| 3207 node->index_expr()->Visit(&for_index); | 3189 node->index_expr()->Visit(&for_index); |
| 3208 Append(for_index); | 3190 Append(for_index); |
| 3209 arguments->Add(PushArgument(for_index.value())); | 3191 arguments->Add(PushArgument(for_index.value())); |
| 3210 | 3192 |
| 3211 if (super_function != NULL) { | 3193 if (super_function != NULL) { |
| 3212 // Generate static call to super operator. | 3194 // Generate static call to super operator. |
| 3213 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), | 3195 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), |
| 3214 *super_function, | 3196 *super_function, |
| 3215 Object::null_array(), | 3197 Object::null_array(), |
| 3216 arguments, | 3198 arguments, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3259 // BuildStaticNoSuchMethodCall stores the value in expression_temp. | 3241 // BuildStaticNoSuchMethodCall stores the value in expression_temp. |
| 3260 return BuildLoadExprTemp(); | 3242 return BuildLoadExprTemp(); |
| 3261 } else { | 3243 } else { |
| 3262 return call; | 3244 return call; |
| 3263 } | 3245 } |
| 3264 } | 3246 } |
| 3265 } | 3247 } |
| 3266 | 3248 |
| 3267 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3249 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3268 new ZoneGrowableArray<PushArgumentInstr*>(3); | 3250 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 3269 ValueGraphVisitor for_array(owner(), temp_index()); | 3251 ValueGraphVisitor for_array(owner()); |
| 3270 node->array()->Visit(&for_array); | 3252 node->array()->Visit(&for_array); |
| 3271 Append(for_array); | 3253 Append(for_array); |
| 3272 arguments->Add(PushArgument(for_array.value())); | 3254 arguments->Add(PushArgument(for_array.value())); |
| 3273 | 3255 |
| 3274 ValueGraphVisitor for_index(owner(), temp_index()); | 3256 ValueGraphVisitor for_index(owner()); |
| 3275 node->index_expr()->Visit(&for_index); | 3257 node->index_expr()->Visit(&for_index); |
| 3276 Append(for_index); | 3258 Append(for_index); |
| 3277 arguments->Add(PushArgument(for_index.value())); | 3259 arguments->Add(PushArgument(for_index.value())); |
| 3278 | 3260 |
| 3279 ValueGraphVisitor for_value(owner(), temp_index()); | 3261 ValueGraphVisitor for_value(owner()); |
| 3280 node->value()->Visit(&for_value); | 3262 node->value()->Visit(&for_value); |
| 3281 Append(for_value); | 3263 Append(for_value); |
| 3282 Value* value = NULL; | 3264 Value* value = NULL; |
| 3283 if (result_is_needed) { | 3265 if (result_is_needed) { |
| 3284 value = Bind(BuildStoreExprTemp(for_value.value())); | 3266 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 3285 } else { | 3267 } else { |
| 3286 value = for_value.value(); | 3268 value = for_value.value(); |
| 3287 } | 3269 } |
| 3288 arguments->Add(PushArgument(value)); | 3270 arguments->Add(PushArgument(value)); |
| 3289 | 3271 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3456 // variable so that ssa renaming detects the dependency and makes use | 3438 // variable so that ssa renaming detects the dependency and makes use |
| 3457 // of the checked type in type propagation. | 3439 // of the checked type in type propagation. |
| 3458 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); | 3440 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); |
| 3459 } | 3441 } |
| 3460 pos++; | 3442 pos++; |
| 3461 } | 3443 } |
| 3462 } | 3444 } |
| 3463 | 3445 |
| 3464 intptr_t i = 0; | 3446 intptr_t i = 0; |
| 3465 while (is_open() && (i < node->length())) { | 3447 while (is_open() && (i < node->length())) { |
| 3466 EffectGraphVisitor for_effect(owner(), temp_index()); | 3448 EffectGraphVisitor for_effect(owner()); |
| 3467 node->NodeAt(i++)->Visit(&for_effect); | 3449 node->NodeAt(i++)->Visit(&for_effect); |
| 3468 Append(for_effect); | 3450 Append(for_effect); |
| 3469 if (!is_open()) { | 3451 if (!is_open()) { |
| 3470 // E.g., because of a JumpNode. | 3452 // E.g., because of a JumpNode. |
| 3471 break; | 3453 break; |
| 3472 } | 3454 } |
| 3473 } | 3455 } |
| 3474 | 3456 |
| 3475 if (is_open()) { | 3457 if (is_open()) { |
| 3476 if (MustSaveRestoreContext(node)) { | 3458 if (MustSaveRestoreContext(node)) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3498 (node != owner()->parsed_function()->node_sequence())); | 3480 (node != owner()->parsed_function()->node_sequence())); |
| 3499 owner()->set_context_level(previous_context_level); | 3481 owner()->set_context_level(previous_context_level); |
| 3500 } | 3482 } |
| 3501 | 3483 |
| 3502 | 3484 |
| 3503 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 3485 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 3504 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 3486 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 3505 // Restores CTX from local variable ':saved_context'. | 3487 // Restores CTX from local variable ':saved_context'. |
| 3506 BuildRestoreContext(node->context_var()); | 3488 BuildRestoreContext(node->context_var()); |
| 3507 | 3489 |
| 3508 EffectGraphVisitor for_catch(owner(), temp_index()); | 3490 EffectGraphVisitor for_catch(owner()); |
| 3509 node->VisitChildren(&for_catch); | 3491 node->VisitChildren(&for_catch); |
| 3510 Append(for_catch); | 3492 Append(for_catch); |
| 3511 } | 3493 } |
| 3512 | 3494 |
| 3513 | 3495 |
| 3514 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 3496 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 3515 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 3497 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 3516 intptr_t original_handler_index = owner()->try_index(); | 3498 intptr_t original_handler_index = owner()->try_index(); |
| 3517 const intptr_t try_handler_index = node->try_index(); | 3499 const intptr_t try_handler_index = node->try_index(); |
| 3518 ASSERT(try_handler_index != original_handler_index); | 3500 ASSERT(try_handler_index != original_handler_index); |
| 3519 owner()->set_try_index(try_handler_index); | 3501 owner()->set_try_index(try_handler_index); |
| 3520 | 3502 |
| 3521 // Preserve CTX into local variable '%saved_context'. | 3503 // Preserve CTX into local variable '%saved_context'. |
| 3522 BuildSaveContext(node->context_var()); | 3504 BuildSaveContext(node->context_var()); |
| 3523 | 3505 |
| 3524 EffectGraphVisitor for_try(owner(), temp_index()); | 3506 EffectGraphVisitor for_try(owner()); |
| 3525 node->try_block()->Visit(&for_try); | 3507 node->try_block()->Visit(&for_try); |
| 3526 | 3508 |
| 3527 if (for_try.is_open()) { | 3509 if (for_try.is_open()) { |
| 3528 JoinEntryInstr* after_try = | 3510 JoinEntryInstr* after_try = |
| 3529 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); | 3511 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); |
| 3530 for_try.Goto(after_try); | 3512 for_try.Goto(after_try); |
| 3531 for_try.exit_ = after_try; | 3513 for_try.exit_ = after_try; |
| 3532 } | 3514 } |
| 3533 | 3515 |
| 3534 JoinEntryInstr* try_entry = | 3516 JoinEntryInstr* try_entry = |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3547 // If there is a finally block, it is the handler for code in the catch | 3529 // If there is a finally block, it is the handler for code in the catch |
| 3548 // block. | 3530 // block. |
| 3549 const intptr_t catch_handler_index = (finally_block == NULL) | 3531 const intptr_t catch_handler_index = (finally_block == NULL) |
| 3550 ? original_handler_index | 3532 ? original_handler_index |
| 3551 : catch_block->catch_handler_index(); | 3533 : catch_block->catch_handler_index(); |
| 3552 | 3534 |
| 3553 const intptr_t prev_catch_try_index = owner()->catch_try_index(); | 3535 const intptr_t prev_catch_try_index = owner()->catch_try_index(); |
| 3554 | 3536 |
| 3555 owner()->set_try_index(catch_handler_index); | 3537 owner()->set_try_index(catch_handler_index); |
| 3556 owner()->set_catch_try_index(try_handler_index); | 3538 owner()->set_catch_try_index(try_handler_index); |
| 3557 EffectGraphVisitor for_catch(owner(), temp_index()); | 3539 EffectGraphVisitor for_catch(owner()); |
| 3558 catch_block->Visit(&for_catch); | 3540 catch_block->Visit(&for_catch); |
| 3559 owner()->set_catch_try_index(prev_catch_try_index); | 3541 owner()->set_catch_try_index(prev_catch_try_index); |
| 3560 | 3542 |
| 3561 // NOTE: The implicit variables ':saved_context', ':exception_var' | 3543 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 3562 // and ':stacktrace_var' can never be captured variables. | 3544 // and ':stacktrace_var' can never be captured variables. |
| 3563 ASSERT(!catch_block->exception_var().is_captured()); | 3545 ASSERT(!catch_block->exception_var().is_captured()); |
| 3564 ASSERT(!catch_block->stacktrace_var().is_captured()); | 3546 ASSERT(!catch_block->stacktrace_var().is_captured()); |
| 3565 | 3547 |
| 3566 CatchBlockEntryInstr* catch_entry = | 3548 CatchBlockEntryInstr* catch_entry = |
| 3567 new CatchBlockEntryInstr(owner()->AllocateBlockId(), | 3549 new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3579 if (join != NULL) { | 3561 if (join != NULL) { |
| 3580 if (is_open()) Goto(join); | 3562 if (is_open()) Goto(join); |
| 3581 exit_ = join; | 3563 exit_ = join; |
| 3582 } | 3564 } |
| 3583 } | 3565 } |
| 3584 | 3566 |
| 3585 if (finally_block != NULL) { | 3567 if (finally_block != NULL) { |
| 3586 // Create a handler for the code in the catch block, containing the | 3568 // Create a handler for the code in the catch block, containing the |
| 3587 // code in the finally block. | 3569 // code in the finally block. |
| 3588 owner()->set_try_index(original_handler_index); | 3570 owner()->set_try_index(original_handler_index); |
| 3589 EffectGraphVisitor for_finally(owner(), temp_index()); | 3571 EffectGraphVisitor for_finally(owner()); |
| 3590 for_finally.BuildRestoreContext(catch_block->context_var()); | 3572 for_finally.BuildRestoreContext(catch_block->context_var()); |
| 3591 | 3573 |
| 3592 finally_block->Visit(&for_finally); | 3574 finally_block->Visit(&for_finally); |
| 3593 if (for_finally.is_open()) { | 3575 if (for_finally.is_open()) { |
| 3594 // Rethrow the exception. Manually build the graph for rethrow. | 3576 // Rethrow the exception. Manually build the graph for rethrow. |
| 3595 Value* exception = for_finally.Bind( | 3577 Value* exception = for_finally.Bind( |
| 3596 for_finally.BuildLoadLocal(catch_block->exception_var())); | 3578 for_finally.BuildLoadLocal(catch_block->exception_var())); |
| 3597 for_finally.PushArgument(exception); | 3579 for_finally.PushArgument(exception); |
| 3598 Value* stacktrace = for_finally.Bind( | 3580 Value* stacktrace = for_finally.Bind( |
| 3599 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); | 3581 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3613 catch_handler_index, | 3595 catch_handler_index, |
| 3614 catch_block->exception_var(), | 3596 catch_block->exception_var(), |
| 3615 catch_block->stacktrace_var(), | 3597 catch_block->stacktrace_var(), |
| 3616 catch_block->needs_stacktrace()); | 3598 catch_block->needs_stacktrace()); |
| 3617 owner()->AddCatchEntry(finally_entry); | 3599 owner()->AddCatchEntry(finally_entry); |
| 3618 AppendFragment(finally_entry, for_finally); | 3600 AppendFragment(finally_entry, for_finally); |
| 3619 } | 3601 } |
| 3620 | 3602 |
| 3621 // Generate code for the finally block if one exists. | 3603 // Generate code for the finally block if one exists. |
| 3622 if ((finally_block != NULL) && is_open()) { | 3604 if ((finally_block != NULL) && is_open()) { |
| 3623 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 3605 EffectGraphVisitor for_finally_block(owner()); |
| 3624 finally_block->Visit(&for_finally_block); | 3606 finally_block->Visit(&for_finally_block); |
| 3625 Append(for_finally_block); | 3607 Append(for_finally_block); |
| 3626 } | 3608 } |
| 3627 } | 3609 } |
| 3628 | 3610 |
| 3629 | 3611 |
| 3630 // Looks up dynamic method noSuchMethod in target_class | 3612 // Looks up dynamic method noSuchMethod in target_class |
| 3631 // (including its super class chain) and builds a static call to it. | 3613 // (including its super class chain) and builds a static call to it. |
| 3632 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( | 3614 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
| 3633 const Class& target_class, | 3615 const Class& target_class, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3688 arguments->Add(PushArgument(member_name_value)); | 3670 arguments->Add(PushArgument(member_name_value)); |
| 3689 // Smi invocation_type. | 3671 // Smi invocation_type. |
| 3690 Value* invocation_type_value = Bind(new ConstantInstr( | 3672 Value* invocation_type_value = Bind(new ConstantInstr( |
| 3691 Smi::ZoneHandle(Smi::New(invocation_type)))); | 3673 Smi::ZoneHandle(Smi::New(invocation_type)))); |
| 3692 arguments->Add(PushArgument(invocation_type_value)); | 3674 arguments->Add(PushArgument(invocation_type_value)); |
| 3693 // List arguments. | 3675 // List arguments. |
| 3694 if (function_arguments == NULL) { | 3676 if (function_arguments == NULL) { |
| 3695 Value* arguments_value = Bind(new ConstantInstr(Array::ZoneHandle())); | 3677 Value* arguments_value = Bind(new ConstantInstr(Array::ZoneHandle())); |
| 3696 arguments->Add(PushArgument(arguments_value)); | 3678 arguments->Add(PushArgument(arguments_value)); |
| 3697 } else { | 3679 } else { |
| 3698 ValueGraphVisitor array_val(owner(), temp_index()); | 3680 ValueGraphVisitor array_val(owner()); |
| 3699 ArrayNode* array = | 3681 ArrayNode* array = |
| 3700 new ArrayNode(token_pos, Type::ZoneHandle(Type::ArrayType()), | 3682 new ArrayNode(token_pos, Type::ZoneHandle(Type::ArrayType()), |
| 3701 function_arguments->nodes()); | 3683 function_arguments->nodes()); |
| 3702 array->Visit(&array_val); | 3684 array->Visit(&array_val); |
| 3703 Append(array_val); | 3685 Append(array_val); |
| 3704 arguments->Add(PushArgument(array_val.value())); | 3686 arguments->Add(PushArgument(array_val.value())); |
| 3705 } | 3687 } |
| 3706 // List argumentNames. | 3688 // List argumentNames. |
| 3707 ConstantInstr* cinstr = new ConstantInstr( | 3689 ConstantInstr* cinstr = new ConstantInstr( |
| 3708 (function_arguments == NULL) ? Array::ZoneHandle() | 3690 (function_arguments == NULL) ? Array::ZoneHandle() |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3727 ASSERT(!func.IsNull()); | 3709 ASSERT(!func.IsNull()); |
| 3728 return new StaticCallInstr(token_pos, | 3710 return new StaticCallInstr(token_pos, |
| 3729 func, | 3711 func, |
| 3730 Object::null_array(), // No names. | 3712 Object::null_array(), // No names. |
| 3731 arguments, | 3713 arguments, |
| 3732 owner()->ic_data_array()); | 3714 owner()->ic_data_array()); |
| 3733 } | 3715 } |
| 3734 | 3716 |
| 3735 | 3717 |
| 3736 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 3718 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 3737 ValueGraphVisitor for_exception(owner(), temp_index()); | 3719 ValueGraphVisitor for_exception(owner()); |
| 3738 node->exception()->Visit(&for_exception); | 3720 node->exception()->Visit(&for_exception); |
| 3739 Append(for_exception); | 3721 Append(for_exception); |
| 3740 PushArgument(for_exception.value()); | 3722 PushArgument(for_exception.value()); |
| 3741 Instruction* instr = NULL; | 3723 Instruction* instr = NULL; |
| 3742 if (node->stacktrace() == NULL) { | 3724 if (node->stacktrace() == NULL) { |
| 3743 instr = new ThrowInstr(node->token_pos()); | 3725 instr = new ThrowInstr(node->token_pos()); |
| 3744 } else { | 3726 } else { |
| 3745 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 3727 ValueGraphVisitor for_stack_trace(owner()); |
| 3746 node->stacktrace()->Visit(&for_stack_trace); | 3728 node->stacktrace()->Visit(&for_stack_trace); |
| 3747 Append(for_stack_trace); | 3729 Append(for_stack_trace); |
| 3748 PushArgument(for_stack_trace.value()); | 3730 PushArgument(for_stack_trace.value()); |
| 3749 instr = new ReThrowInstr(node->token_pos(), owner()->catch_try_index()); | 3731 instr = new ReThrowInstr(node->token_pos(), owner()->catch_try_index()); |
| 3750 } | 3732 } |
| 3751 AddInstruction(instr); | 3733 AddInstruction(instr); |
| 3752 } | 3734 } |
| 3753 | 3735 |
| 3754 | 3736 |
| 3755 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 3737 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3774 // We are about to generate code for an inlined finally block. Exceptions | 3756 // We are about to generate code for an inlined finally block. Exceptions |
| 3775 // thrown in this block of code should be treated as though they are | 3757 // thrown in this block of code should be treated as though they are |
| 3776 // thrown not from the current try block but the outer try block if any. | 3758 // thrown not from the current try block but the outer try block if any. |
| 3777 intptr_t outer_try_index = node->try_index(); | 3759 intptr_t outer_try_index = node->try_index(); |
| 3778 owner()->set_try_index(outer_try_index); | 3760 owner()->set_try_index(outer_try_index); |
| 3779 } | 3761 } |
| 3780 BuildRestoreContext(node->context_var()); | 3762 BuildRestoreContext(node->context_var()); |
| 3781 | 3763 |
| 3782 JoinEntryInstr* finally_entry = | 3764 JoinEntryInstr* finally_entry = |
| 3783 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 3765 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 3784 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 3766 EffectGraphVisitor for_finally_block(owner()); |
| 3785 node->finally_block()->Visit(&for_finally_block); | 3767 node->finally_block()->Visit(&for_finally_block); |
| 3786 | 3768 |
| 3787 if (try_index >= 0) { | 3769 if (try_index >= 0) { |
| 3788 owner()->set_try_index(try_index); | 3770 owner()->set_try_index(try_index); |
| 3789 } | 3771 } |
| 3790 | 3772 |
| 3791 if (for_finally_block.is_open()) { | 3773 if (for_finally_block.is_open()) { |
| 3792 JoinEntryInstr* after_finally = | 3774 JoinEntryInstr* after_finally = |
| 3793 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 3775 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 3794 for_finally_block.Goto(after_finally); | 3776 for_finally_block.Goto(after_finally); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3807 AstPrinter::PrintFunctionNodes(*parsed_function()); | 3789 AstPrinter::PrintFunctionNodes(*parsed_function()); |
| 3808 } | 3790 } |
| 3809 if (FLAG_print_scopes) { | 3791 if (FLAG_print_scopes) { |
| 3810 AstPrinter::PrintFunctionScope(*parsed_function()); | 3792 AstPrinter::PrintFunctionScope(*parsed_function()); |
| 3811 } | 3793 } |
| 3812 const Function& function = parsed_function()->function(); | 3794 const Function& function = parsed_function()->function(); |
| 3813 TargetEntryInstr* normal_entry = | 3795 TargetEntryInstr* normal_entry = |
| 3814 new TargetEntryInstr(AllocateBlockId(), | 3796 new TargetEntryInstr(AllocateBlockId(), |
| 3815 CatchClauseNode::kInvalidTryIndex); | 3797 CatchClauseNode::kInvalidTryIndex); |
| 3816 graph_entry_ = new GraphEntryInstr(parsed_function(), normal_entry, osr_id_); | 3798 graph_entry_ = new GraphEntryInstr(parsed_function(), normal_entry, osr_id_); |
| 3817 EffectGraphVisitor for_effect(this, 0); | 3799 EffectGraphVisitor for_effect(this); |
| 3818 // This check may be deleted if the generated code is leaf. | 3800 // This check may be deleted if the generated code is leaf. |
| 3819 // Native functions don't need a stack check at entry. | 3801 // Native functions don't need a stack check at entry. |
| 3820 if (!function.is_native()) { | 3802 if (!function.is_native()) { |
| 3821 CheckStackOverflowInstr* check = | 3803 CheckStackOverflowInstr* check = |
| 3822 new CheckStackOverflowInstr(function.token_pos(), 0); | 3804 new CheckStackOverflowInstr(function.token_pos(), 0); |
| 3823 // If we are inlining don't actually attach the stack check. We must still | 3805 // If we are inlining don't actually attach the stack check. We must still |
| 3824 // create the stack check in order to allocate a deopt id. | 3806 // create the stack check in order to allocate a deopt id. |
| 3825 if (!IsInlining()) for_effect.AddInstruction(check); | 3807 if (!IsInlining()) for_effect.AddInstruction(check); |
| 3826 } | 3808 } |
| 3827 parsed_function()->node_sequence()->Visit(&for_effect); | 3809 parsed_function()->node_sequence()->Visit(&for_effect); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3841 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3860 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3842 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3861 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3843 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3862 const Error& error = Error::Handle( | 3844 const Error& error = Error::Handle( |
| 3863 LanguageError::New(String::Handle(String::New(chars)))); | 3845 LanguageError::New(String::Handle(String::New(chars)))); |
| 3864 Isolate::Current()->long_jump_base()->Jump(1, error); | 3846 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3865 } | 3847 } |
| 3866 | 3848 |
| 3867 | 3849 |
| 3868 } // namespace dart | 3850 } // namespace dart |
| OLD | NEW |