| 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/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 } else { | 678 } else { |
| 679 JoinEntryInstr* join = | 679 JoinEntryInstr* join = |
| 680 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 680 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 681 true_exit->Goto(join); | 681 true_exit->Goto(join); |
| 682 false_exit->Goto(join); | 682 false_exit->Goto(join); |
| 683 exit_ = join; | 683 exit_ = join; |
| 684 } | 684 } |
| 685 } | 685 } |
| 686 | 686 |
| 687 | 687 |
| 688 void EffectGraphVisitor::TieLoop(intptr_t token_pos, | 688 void EffectGraphVisitor::TieLoop( |
| 689 const TestGraphVisitor& test_fragment, | 689 intptr_t token_pos, |
| 690 const EffectGraphVisitor& body_fragment) { | 690 const TestGraphVisitor& test_fragment, |
| 691 const EffectGraphVisitor& body_fragment, |
| 692 const EffectGraphVisitor& test_preamble_fragment) { |
| 691 // We have: a test graph fragment with zero, one, or two available exits; | 693 // We have: a test graph fragment with zero, one, or two available exits; |
| 692 // and an effect graph fragment with zero or one available exits. We want | 694 // and an effect graph fragment with zero or one available exits. We want |
| 693 // to append the 'while loop' consisting of the test graph fragment as | 695 // to append the 'while loop' consisting of the test graph fragment as |
| 694 // condition and the effect graph fragment as body. | 696 // condition and the effect graph fragment as body. |
| 695 ASSERT(is_open()); | 697 ASSERT(is_open()); |
| 696 | 698 |
| 697 // 1. Connect the body to the test if it is reachable, and if so record | 699 // 1. Connect the body to the test if it is reachable, and if so record |
| 698 // its exit (if any). | 700 // its exit (if any). |
| 699 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); | 701 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); |
| 700 Instruction* body_exit = AppendFragment(body_entry, body_fragment); | 702 Instruction* body_exit = AppendFragment(body_entry, body_fragment); |
| 701 | 703 |
| 702 // 2. Connect the test to this graph, including the body if reachable and | 704 // 2. Connect the test to this graph, including the body if reachable and |
| 703 // using a fresh join node if the body is reachable and has an open exit. | 705 // using a fresh join node if the body is reachable and has an open exit. |
| 704 if (body_exit == NULL) { | 706 if (body_exit == NULL) { |
| 707 Append(test_preamble_fragment); |
| 705 Append(test_fragment); | 708 Append(test_fragment); |
| 706 } else { | 709 } else { |
| 707 JoinEntryInstr* join = | 710 JoinEntryInstr* join = |
| 708 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 711 new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 709 CheckStackOverflowInstr* check = | 712 CheckStackOverflowInstr* check = |
| 710 new(I) CheckStackOverflowInstr(token_pos, owner()->loop_depth()); | 713 new(I) CheckStackOverflowInstr(token_pos, owner()->loop_depth()); |
| 711 join->LinkTo(check); | 714 join->LinkTo(check); |
| 712 check->LinkTo(test_fragment.entry()); | 715 if (!test_preamble_fragment.is_empty()) { |
| 716 check->LinkTo(test_preamble_fragment.entry()); |
| 717 test_preamble_fragment.exit()->LinkTo(test_fragment.entry()); |
| 718 } else { |
| 719 check->LinkTo(test_fragment.entry()); |
| 720 } |
| 713 Goto(join); | 721 Goto(join); |
| 714 body_exit->Goto(join); | 722 body_exit->Goto(join); |
| 715 } | 723 } |
| 716 | 724 |
| 717 // 3. Set the exit to the graph to be the false successor of the test, a | 725 // 3. Set the exit to the graph to be the false successor of the test, a |
| 718 // fresh target node | 726 // fresh target node |
| 719 exit_ = test_fragment.CreateFalseSuccessor(); | 727 exit_ = test_fragment.CreateFalseSuccessor(); |
| 720 } | 728 } |
| 721 | 729 |
| 722 | 730 |
| (...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 ASSERT(!is_open()); | 1968 ASSERT(!is_open()); |
| 1961 exit_ = exit_instruction; | 1969 exit_ = exit_instruction; |
| 1962 } | 1970 } |
| 1963 | 1971 |
| 1964 | 1972 |
| 1965 // <Statement> ::= While { label: SourceLabel | 1973 // <Statement> ::= While { label: SourceLabel |
| 1966 // condition: <Expression> | 1974 // condition: <Expression> |
| 1967 // body: <Sequence> } | 1975 // body: <Sequence> } |
| 1968 // The fragment is composed as follows: | 1976 // The fragment is composed as follows: |
| 1969 // a) loop-join | 1977 // a) loop-join |
| 1970 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1978 // b) [ test_preamble ]? |
| 1971 // c) body-entry-target | 1979 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1972 // d) [ body ] -> (continue-join) | 1980 // d) body-entry-target |
| 1973 // e) continue-join -> (loop-join) | 1981 // e) [ body ] -> (continue-join) |
| 1974 // f) loop-exit-target | 1982 // f) continue-join -> (loop-join) |
| 1975 // g) break-join (optional) | 1983 // g) loop-exit-target |
| 1984 // h) break-join (optional) |
| 1976 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1985 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1977 NestedLoop nested_loop(owner(), node->label()); | 1986 NestedLoop nested_loop(owner(), node->label()); |
| 1978 | 1987 |
| 1988 EffectGraphVisitor for_preamble(owner()); |
| 1989 if (node->condition_preamble() != NULL) { |
| 1990 node->condition_preamble()->Visit(&for_preamble); |
| 1991 } |
| 1992 |
| 1979 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); | 1993 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1980 node->condition()->Visit(&for_test); | 1994 node->condition()->Visit(&for_test); |
| 1981 ASSERT(!for_test.is_empty()); // Language spec. | 1995 ASSERT(!for_test.is_empty()); // Language spec. |
| 1982 | 1996 |
| 1983 EffectGraphVisitor for_body(owner()); | 1997 EffectGraphVisitor for_body(owner()); |
| 1984 node->body()->Visit(&for_body); | 1998 node->body()->Visit(&for_body); |
| 1985 | 1999 |
| 1986 // Labels are set after body traversal. | 2000 // Labels are set after body traversal. |
| 1987 JoinEntryInstr* join = nested_loop.continue_target(); | 2001 JoinEntryInstr* join = nested_loop.continue_target(); |
| 1988 if (join != NULL) { | 2002 if (join != NULL) { |
| 1989 if (for_body.is_open()) for_body.Goto(join); | 2003 if (for_body.is_open()) for_body.Goto(join); |
| 1990 for_body.exit_ = join; | 2004 for_body.exit_ = join; |
| 1991 } | 2005 } |
| 1992 TieLoop(node->token_pos(), for_test, for_body); | 2006 TieLoop(node->token_pos(), for_test, for_body, for_preamble); |
| 1993 join = nested_loop.break_target(); | 2007 join = nested_loop.break_target(); |
| 1994 if (join != NULL) { | 2008 if (join != NULL) { |
| 1995 Goto(join); | 2009 Goto(join); |
| 1996 exit_ = join; | 2010 exit_ = join; |
| 1997 } | 2011 } |
| 1998 } | 2012 } |
| 1999 | 2013 |
| 2000 | 2014 |
| 2001 // The fragment is composed as follows: | 2015 // The fragment is composed as follows: |
| 2002 // a) body-entry-join | 2016 // a) body-entry-join |
| (...skipping 2184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4187 Report::MessageF(Report::kBailout, | 4201 Report::MessageF(Report::kBailout, |
| 4188 Script::Handle(function.script()), | 4202 Script::Handle(function.script()), |
| 4189 function.token_pos(), | 4203 function.token_pos(), |
| 4190 "FlowGraphBuilder Bailout: %s %s", | 4204 "FlowGraphBuilder Bailout: %s %s", |
| 4191 String::Handle(function.name()).ToCString(), | 4205 String::Handle(function.name()).ToCString(), |
| 4192 reason); | 4206 reason); |
| 4193 UNREACHABLE(); | 4207 UNREACHABLE(); |
| 4194 } | 4208 } |
| 4195 | 4209 |
| 4196 } // namespace dart | 4210 } // namespace dart |
| OLD | NEW |