Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 63903005: Use the VM's graph builder nesting stack for loop depth and context level. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 24 matching lines...) Expand all
35 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); 35 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
36 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); 36 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
37 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.");
38 DEFINE_FLAG(bool, print_flow_graph_optimized, false, 38 DEFINE_FLAG(bool, print_flow_graph_optimized, false,
39 "Print the IR flow graph when optimizing."); 39 "Print the IR flow graph when optimizing.");
40 DEFINE_FLAG(bool, trace_type_check_elimination, false, 40 DEFINE_FLAG(bool, trace_type_check_elimination, false,
41 "Trace type check elimination at compile time."); 41 "Trace type check elimination at compile time.");
42 DECLARE_FLAG(bool, enable_type_checks); 42 DECLARE_FLAG(bool, enable_type_checks);
43 43
44 44
45 // Base class for a stack of enclosing statements of interest (e.g.,
46 // blocks (breakable) and loops (continuable)).
47 class NestedStatement : public ValueObject {
48 public:
49 NestedStatement(FlowGraphBuilder* owner, const SourceLabel* label)
Florian Schneider 2013/11/19 10:37:05 Since only subclasses of NestedStatement exist (Ne
Kevin Millikin (Google) 2013/11/19 11:36:54 OK.
50 : owner_(owner),
51 label_(label),
52 outer_(owner->nesting_stack_),
53 break_target_(NULL) {
54 // Push on the owner's nesting stack.
55 owner->nesting_stack_ = this;
56 }
57
58 virtual ~NestedStatement() {
59 // Pop from the owner's nesting stack.
60 ASSERT(owner_->nesting_stack_ == this);
61 owner_->nesting_stack_ = outer_;
62 }
63
64 FlowGraphBuilder* owner() const { return owner_; }
65 const SourceLabel* label() const { return label_; }
66 NestedStatement* outer() const { return outer_; }
67 JoinEntryInstr* break_target() const { return break_target_; }
68
69 virtual intptr_t ContextLevel() const;
70
71 virtual JoinEntryInstr* BreakTargetFor(SourceLabel* label);
72 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
73
74 private:
75 FlowGraphBuilder* owner_;
76 const SourceLabel* label_;
77 NestedStatement* outer_;
78
79 JoinEntryInstr* break_target_;
80 };
81
82
83 intptr_t NestedStatement::ContextLevel() const {
84 // Context level is determined by the innermost nested statement having one.
85 return (outer() == NULL) ? 0 : outer()->ContextLevel();
86 }
87
88
89 intptr_t FlowGraphBuilder::context_level() const {
90 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel();
91 }
92
93
45 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) { 94 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
46 if (label != label_) return NULL; 95 if (label != label_) return NULL;
47 if (break_target_ == NULL) { 96 if (break_target_ == NULL) {
48 break_target_ = 97 break_target_ =
49 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 98 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
50 } 99 }
51 return break_target_; 100 return break_target_;
52 } 101 }
53 102
54 103
55 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 104 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
56 return NULL; 105 return NULL;
57 } 106 }
58 107
59 108
109 // A nested statement that has its own context level.
110 class NestedBlock : public NestedStatement {
111 public:
112 NestedBlock(FlowGraphBuilder* owner, SequenceNode* node)
113 : NestedStatement(owner, node->label()), scope_(node->scope()) {}
114
115 virtual intptr_t ContextLevel() const;
116
117 private:
118 LocalScope* scope_;
119 };
120
121
122 intptr_t NestedBlock::ContextLevel() const {
123 return ((scope_ == NULL) || (scope_->num_context_variables() == 0))
124 ? NestedStatement::ContextLevel()
125 : scope_->context_level();
126 }
127
128
60 // A nested statement that can be the target of a continue as well as a 129 // A nested statement that can be the target of a continue as well as a
61 // break. 130 // break.
62 class NestedLoop : public NestedStatement { 131 class NestedLoop : public NestedStatement {
63 public: 132 public:
64 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label) 133 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label)
65 : NestedStatement(owner, label), continue_target_(NULL) { } 134 : NestedStatement(owner, label), continue_target_(NULL) {
135 owner->IncrementLoopDepth();
136 }
137
138 virtual ~NestedLoop() {
139 owner()->DecrementLoopDepth();
140 }
66 141
67 JoinEntryInstr* continue_target() const { return continue_target_; } 142 JoinEntryInstr* continue_target() const { return continue_target_; }
68 143
69 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); 144 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
70 145
71 private: 146 private:
72 JoinEntryInstr* continue_target_; 147 JoinEntryInstr* continue_target_;
73 }; 148 };
74 149
75 150
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 ic_data_array_(ic_data_array), 211 ic_data_array_(ic_data_array),
137 num_copied_params_(parsed_function->num_copied_params()), 212 num_copied_params_(parsed_function->num_copied_params()),
138 // All parameters are copied if any parameter is. 213 // All parameters are copied if any parameter is.
139 num_non_copied_params_((num_copied_params_ == 0) 214 num_non_copied_params_((num_copied_params_ == 0)
140 ? parsed_function->function().num_fixed_parameters() 215 ? parsed_function->function().num_fixed_parameters()
141 : 0), 216 : 0),
142 num_stack_locals_(parsed_function->num_stack_locals()), 217 num_stack_locals_(parsed_function->num_stack_locals()),
143 exit_collector_(exit_collector), 218 exit_collector_(exit_collector),
144 guarded_fields_(new ZoneGrowableArray<const Field*>()), 219 guarded_fields_(new ZoneGrowableArray<const Field*>()),
145 last_used_block_id_(0), // 0 is used for the graph entry. 220 last_used_block_id_(0), // 0 is used for the graph entry.
146 context_level_(0),
147 try_index_(CatchClauseNode::kInvalidTryIndex), 221 try_index_(CatchClauseNode::kInvalidTryIndex),
148 catch_try_index_(CatchClauseNode::kInvalidTryIndex), 222 catch_try_index_(CatchClauseNode::kInvalidTryIndex),
149 loop_depth_(0), 223 loop_depth_(0),
150 graph_entry_(NULL), 224 graph_entry_(NULL),
151 temp_count_(0), 225 temp_count_(0),
152 args_pushed_(0), 226 args_pushed_(0),
153 nesting_stack_(NULL), 227 nesting_stack_(NULL),
154 osr_id_(osr_id) { } 228 osr_id_(osr_id) { }
155 229
156 230
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 Symbols::FunctionResult()); 983 Symbols::FunctionResult());
910 } 984 }
911 } 985 }
912 986
913 intptr_t current_context_level = owner()->context_level(); 987 intptr_t current_context_level = owner()->context_level();
914 ASSERT(current_context_level >= 0); 988 ASSERT(current_context_level >= 0);
915 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { 989 if (owner()->parsed_function()->saved_entry_context_var() != NULL) {
916 // CTX on entry was saved, but not linked as context parent. 990 // CTX on entry was saved, but not linked as context parent.
917 BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var()); 991 BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var());
918 } else { 992 } else {
919 while (current_context_level-- > 0) { 993 UnchainContexts(current_context_level);
920 UnchainContext();
921 }
922 } 994 }
923 995
924 AddReturnExit(node->token_pos(), return_value); 996 AddReturnExit(node->token_pos(), return_value);
925 } 997 }
926 998
927 999
928 // <Expression> ::= Literal { literal: Instance } 1000 // <Expression> ::= Literal { literal: Instance }
929 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1001 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
930 return; 1002 return;
931 } 1003 }
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 // The fragment is composed as follows: 1844 // The fragment is composed as follows:
1773 // a) loop-join 1845 // a) loop-join
1774 // b) [ test ] -> (body-entry-target, loop-exit-target) 1846 // b) [ test ] -> (body-entry-target, loop-exit-target)
1775 // c) body-entry-target 1847 // c) body-entry-target
1776 // d) [ body ] -> (continue-join) 1848 // d) [ body ] -> (continue-join)
1777 // e) continue-join -> (loop-join) 1849 // e) continue-join -> (loop-join)
1778 // f) loop-exit-target 1850 // f) loop-exit-target
1779 // g) break-join (optional) 1851 // g) break-join (optional)
1780 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1852 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1781 NestedLoop nested_loop(owner(), node->label()); 1853 NestedLoop nested_loop(owner(), node->label());
1782 owner()->IncrementLoopDepth();
1783 1854
1784 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1855 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1785 node->condition()->Visit(&for_test); 1856 node->condition()->Visit(&for_test);
1786 ASSERT(!for_test.is_empty()); // Language spec. 1857 ASSERT(!for_test.is_empty()); // Language spec.
1787 1858
1788 EffectGraphVisitor for_body(owner()); 1859 EffectGraphVisitor for_body(owner());
1789 node->body()->Visit(&for_body); 1860 node->body()->Visit(&for_body);
1790 1861
1791 // Labels are set after body traversal. 1862 // Labels are set after body traversal.
1792 JoinEntryInstr* join = nested_loop.continue_target(); 1863 JoinEntryInstr* join = nested_loop.continue_target();
1793 if (join != NULL) { 1864 if (join != NULL) {
1794 if (for_body.is_open()) for_body.Goto(join); 1865 if (for_body.is_open()) for_body.Goto(join);
1795 for_body.exit_ = join; 1866 for_body.exit_ = join;
1796 } 1867 }
1797 TieLoop(node->token_pos(), for_test, for_body); 1868 TieLoop(node->token_pos(), for_test, for_body);
1798 join = nested_loop.break_target(); 1869 join = nested_loop.break_target();
1799 if (join != NULL) { 1870 if (join != NULL) {
1800 Goto(join); 1871 Goto(join);
1801 exit_ = join; 1872 exit_ = join;
1802 } 1873 }
1803 owner()->DecrementLoopDepth();
1804 } 1874 }
1805 1875
1806 1876
1807 // The fragment is composed as follows: 1877 // The fragment is composed as follows:
1808 // a) body-entry-join 1878 // a) body-entry-join
1809 // b) [ body ] 1879 // b) [ body ]
1810 // c) test-entry (continue-join or body-exit-target) 1880 // c) test-entry (continue-join or body-exit-target)
1811 // d) [ test-entry ] -> (back-target, loop-exit-target) 1881 // d) [ test-entry ] -> (back-target, loop-exit-target)
1812 // e) back-target -> (body-entry-join) 1882 // e) back-target -> (body-entry-join)
1813 // f) loop-exit-target 1883 // f) loop-exit-target
1814 // g) break-join 1884 // g) break-join
1815 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1885 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1816 NestedLoop nested_loop(owner(), node->label()); 1886 NestedLoop nested_loop(owner(), node->label());
1817 owner()->IncrementLoopDepth();
1818 1887
1819 // Traverse the body first in order to generate continue and break labels. 1888 // Traverse the body first in order to generate continue and break labels.
1820 EffectGraphVisitor for_body(owner()); 1889 EffectGraphVisitor for_body(owner());
1821 node->body()->Visit(&for_body); 1890 node->body()->Visit(&for_body);
1822 1891
1823 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1892 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1824 node->condition()->Visit(&for_test); 1893 node->condition()->Visit(&for_test);
1825 ASSERT(is_open()); 1894 ASSERT(is_open());
1826 1895
1827 // Tie do-while loop (test is after the body). 1896 // Tie do-while loop (test is after the body).
(...skipping 19 matching lines...) Expand all
1847 } 1916 }
1848 1917
1849 for_test.IfTrueGoto(body_entry_join); 1918 for_test.IfTrueGoto(body_entry_join);
1850 join = nested_loop.break_target(); 1919 join = nested_loop.break_target();
1851 if (join == NULL) { 1920 if (join == NULL) {
1852 exit_ = for_test.CreateFalseSuccessor(); 1921 exit_ = for_test.CreateFalseSuccessor();
1853 } else { 1922 } else {
1854 for_test.IfFalseGoto(join); 1923 for_test.IfFalseGoto(join);
1855 exit_ = join; 1924 exit_ = join;
1856 } 1925 }
1857 owner()->DecrementLoopDepth();
1858 } 1926 }
1859 1927
1860 1928
1861 // A ForNode can contain break and continue jumps. 'break' joins to 1929 // A ForNode can contain break and continue jumps. 'break' joins to
1862 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1930 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1863 // as follows: 1931 // as follows:
1864 // a) [ initializer ] 1932 // a) [ initializer ]
1865 // b) loop-join 1933 // b) loop-join
1866 // c) [ test ] -> (body-entry-target, loop-exit-target) 1934 // c) [ test ] -> (body-entry-target, loop-exit-target)
1867 // d) body-entry-target 1935 // d) body-entry-target
1868 // e) [ body ] 1936 // e) [ body ]
1869 // f) continue-join (optional) 1937 // f) continue-join (optional)
1870 // g) [ increment ] -> (loop-join) 1938 // g) [ increment ] -> (loop-join)
1871 // h) loop-exit-target 1939 // h) loop-exit-target
1872 // i) break-join 1940 // i) break-join
1873 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1941 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1874 EffectGraphVisitor for_initializer(owner()); 1942 EffectGraphVisitor for_initializer(owner());
1875 node->initializer()->Visit(&for_initializer); 1943 node->initializer()->Visit(&for_initializer);
1876 Append(for_initializer); 1944 Append(for_initializer);
1877 ASSERT(is_open()); 1945 ASSERT(is_open());
1878 1946
1879 NestedLoop nested_loop(owner(), node->label()); 1947 NestedLoop nested_loop(owner(), node->label());
1880 owner()->IncrementLoopDepth();
1881 // Compose body to set any jump labels. 1948 // Compose body to set any jump labels.
1882 EffectGraphVisitor for_body(owner()); 1949 EffectGraphVisitor for_body(owner());
1883 node->body()->Visit(&for_body); 1950 node->body()->Visit(&for_body);
1884 1951
1885 EffectGraphVisitor for_increment(owner()); 1952 EffectGraphVisitor for_increment(owner());
1886 node->increment()->Visit(&for_increment); 1953 node->increment()->Visit(&for_increment);
1887 1954
1888 // Join the loop body and increment and then tie the loop. 1955 // Join the loop body and increment and then tie the loop.
1889 JoinEntryInstr* continue_join = nested_loop.continue_target(); 1956 JoinEntryInstr* continue_join = nested_loop.continue_target();
1890 if ((continue_join != NULL) || for_body.is_open()) { 1957 if ((continue_join != NULL) || for_body.is_open()) {
(...skipping 25 matching lines...) Expand all
1916 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); 1983 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor();
1917 AppendFragment(body_entry, for_body); 1984 AppendFragment(body_entry, for_body);
1918 1985
1919 if (nested_loop.break_target() == NULL) { 1986 if (nested_loop.break_target() == NULL) {
1920 exit_ = for_test.CreateFalseSuccessor(); 1987 exit_ = for_test.CreateFalseSuccessor();
1921 } else { 1988 } else {
1922 for_test.IfFalseGoto(nested_loop.break_target()); 1989 for_test.IfFalseGoto(nested_loop.break_target());
1923 exit_ = nested_loop.break_target(); 1990 exit_ = nested_loop.break_target();
1924 } 1991 }
1925 } 1992 }
1926 owner()->DecrementLoopDepth();
1927 } 1993 }
1928 1994
1929 1995
1930 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1996 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1931 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1997 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1932 EffectGraphVisitor for_effect(owner()); 1998 EffectGraphVisitor for_effect(owner());
1933 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1999 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1934 Append(for_effect); 2000 Append(for_effect);
1935 if (!is_open()) return; 2001 if (!is_open()) return;
1936 } 2002 }
(...skipping 15 matching lines...) Expand all
1952 (target_scope->num_context_variables() == 0)) { 2018 (target_scope->num_context_variables() == 0)) {
1953 target_scope = target_scope->parent(); 2019 target_scope = target_scope->parent();
1954 } 2020 }
1955 if (target_scope != NULL) { 2021 if (target_scope != NULL) {
1956 target_context_level = target_scope->context_level(); 2022 target_context_level = target_scope->context_level();
1957 } 2023 }
1958 } 2024 }
1959 ASSERT(target_context_level >= 0); 2025 ASSERT(target_context_level >= 0);
1960 intptr_t current_context_level = owner()->context_level(); 2026 intptr_t current_context_level = owner()->context_level();
1961 ASSERT(current_context_level >= target_context_level); 2027 ASSERT(current_context_level >= target_context_level);
1962 while (current_context_level-- > target_context_level) { 2028 UnchainContexts(current_context_level - target_context_level);
1963 UnchainContext();
1964 }
1965 2029
1966 JoinEntryInstr* jump_target = NULL; 2030 JoinEntryInstr* jump_target = NULL;
1967 if (node->kind() == Token::kBREAK) { 2031 NestedStatement* current = owner()->nesting_stack();
1968 NestedStatement* current = owner()->nesting_stack(); 2032 while (current != NULL) {
1969 while (current != NULL) { 2033 jump_target = (node->kind() == Token::kBREAK)
1970 jump_target = current->BreakTargetFor(node->label()); 2034 ? current->BreakTargetFor(node->label())
1971 if (jump_target != NULL) break; 2035 : current->ContinueTargetFor(node->label());
1972 current = current->outer(); 2036 if (jump_target != NULL) break;
1973 } 2037 current = current->outer();
1974 } else {
1975 NestedStatement* current = owner()->nesting_stack();
1976 while (current != NULL) {
1977 jump_target = current->ContinueTargetFor(node->label());
1978 if (jump_target != NULL) break;
1979 current = current->outer();
1980 }
1981 } 2038 }
1982 ASSERT(jump_target != NULL); 2039 ASSERT(jump_target != NULL);
1983 Goto(jump_target); 2040 Goto(jump_target);
1984 } 2041 }
1985 2042
1986 2043
1987 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 2044 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1988 UNREACHABLE(); 2045 UNREACHABLE();
1989 } 2046 }
1990 2047
(...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); 3507 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
3451 } 3508 }
3452 3509
3453 3510
3454 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 3511 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
3455 return (node == owner()->parsed_function()->node_sequence()) && 3512 return (node == owner()->parsed_function()->node_sequence()) &&
3456 (owner()->parsed_function()->saved_entry_context_var() != NULL); 3513 (owner()->parsed_function()->saved_entry_context_var() != NULL);
3457 } 3514 }
3458 3515
3459 3516
3460 void EffectGraphVisitor::UnchainContext() { 3517 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3461 Value* context = Bind(new CurrentContextInstr()); 3518 if (n > 0) {
3462 Value* parent = Bind( 3519 Value* context = Bind(new CurrentContextInstr());
3463 new LoadFieldInstr(context, 3520 while (n-- > 0) {
3464 Context::parent_offset(), 3521 context = Bind(
3465 Type::ZoneHandle())); // Not an instance, no type. 3522 new LoadFieldInstr(context,
3466 AddInstruction(new StoreContextInstr(parent)); 3523 Context::parent_offset(),
3524 Type::ZoneHandle())); // Not an instance, no type.
3525 }
3526 AddInstruction(new StoreContextInstr(context));
3527 }
3467 } 3528 }
3468 3529
3469 3530
3470 // <Statement> ::= Sequence { scope: LocalScope 3531 // <Statement> ::= Sequence { scope: LocalScope
3471 // nodes: <Statement>* 3532 // nodes: <Statement>*
3472 // label: SourceLabel } 3533 // label: SourceLabel }
3473 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 3534 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
3474 LocalScope* scope = node->scope(); 3535 LocalScope* scope = node->scope();
3475 const intptr_t num_context_variables = 3536 const intptr_t num_context_variables =
3476 (scope != NULL) ? scope->num_context_variables() : 0; 3537 (scope != NULL) ? scope->num_context_variables() : 0;
3477 int previous_context_level = owner()->context_level();
3478 // The outermost function sequence cannot contain a label. 3538 // The outermost function sequence cannot contain a label.
3479 ASSERT((node->label() == NULL) || 3539 ASSERT((node->label() == NULL) ||
3480 (node != owner()->parsed_function()->node_sequence())); 3540 (node != owner()->parsed_function()->node_sequence()));
3481 NestedStatement nested_block(owner(), node->label()); 3541 NestedBlock nested_block(owner(), node);
3482 3542
3483 if (num_context_variables > 0) { 3543 if (num_context_variables > 0) {
3484 // The loop local scope declares variables that are captured. 3544 // The loop local scope declares variables that are captured.
3485 // Allocate and chain a new context. 3545 // Allocate and chain a new context.
3486 // Allocate context computation (uses current CTX) 3546 // Allocate context computation (uses current CTX)
3487 Value* allocated_context = 3547 Value* allocated_context =
3488 Bind(new AllocateContextInstr(node->token_pos(), 3548 Bind(new AllocateContextInstr(node->token_pos(),
3489 num_context_variables)); 3549 num_context_variables));
3490 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); 3550 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
3491 // If this node_sequence is the body of the function being compiled, and 3551 // If this node_sequence is the body of the function being compiled, and
(...skipping 11 matching lines...) Expand all
3503 Value* current_context = Bind(new CurrentContextInstr()); 3563 Value* current_context = Bind(new CurrentContextInstr());
3504 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); 3564 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
3505 Do(new StoreVMFieldInstr(tmp_val, 3565 Do(new StoreVMFieldInstr(tmp_val,
3506 Context::parent_offset(), 3566 Context::parent_offset(),
3507 current_context, 3567 current_context,
3508 Type::ZoneHandle())); 3568 Type::ZoneHandle()));
3509 AddInstruction( 3569 AddInstruction(
3510 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); 3570 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var))));
3511 } 3571 }
3512 3572
3513 owner()->set_context_level(scope->context_level());
3514
3515 // If this node_sequence is the body of the function being compiled, copy 3573 // If this node_sequence is the body of the function being compiled, copy
3516 // the captured parameters from the frame into the context. 3574 // the captured parameters from the frame into the context.
3517 if (node == owner()->parsed_function()->node_sequence()) { 3575 if (node == owner()->parsed_function()->node_sequence()) {
3518 ASSERT(scope->context_level() == 1); 3576 ASSERT(scope->context_level() == 1);
3519 const Function& function = owner()->parsed_function()->function(); 3577 const Function& function = owner()->parsed_function()->function();
3520 const int num_params = function.NumParameters(); 3578 const int num_params = function.NumParameters();
3521 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3579 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3522 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3580 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3523 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3581 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3524 const LocalVariable& parameter = *scope->VariableAt(pos); 3582 const LocalVariable& parameter = *scope->VariableAt(pos);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3593 break; 3651 break;
3594 } 3652 }
3595 } 3653 }
3596 3654
3597 if (is_open()) { 3655 if (is_open()) {
3598 if (MustSaveRestoreContext(node)) { 3656 if (MustSaveRestoreContext(node)) {
3599 ASSERT(num_context_variables > 0); 3657 ASSERT(num_context_variables > 0);
3600 BuildRestoreContext( 3658 BuildRestoreContext(
3601 *owner()->parsed_function()->saved_entry_context_var()); 3659 *owner()->parsed_function()->saved_entry_context_var());
3602 } else if (num_context_variables > 0) { 3660 } else if (num_context_variables > 0) {
3603 UnchainContext(); 3661 UnchainContexts(1);
3604 } 3662 }
3605 } 3663 }
3606 3664
3607 // If this node sequence is labeled, a break out of the sequence will have 3665 // If this node sequence is labeled, a break out of the sequence will have
3608 // taken care of unchaining the context. 3666 // taken care of unchaining the context.
3609 if (nested_block.break_target() != NULL) { 3667 if (nested_block.break_target() != NULL) {
3610 if (is_open()) Goto(nested_block.break_target()); 3668 if (is_open()) Goto(nested_block.break_target());
3611 exit_ = nested_block.break_target(); 3669 exit_ = nested_block.break_target();
3612 } 3670 }
3613
3614 owner()->set_context_level(previous_context_level);
3615 } 3671 }
3616 3672
3617 3673
3618 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 3674 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
3619 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); 3675 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
3620 // Restores CTX from local variable ':saved_context'. 3676 // Restores CTX from local variable ':saved_context'.
3621 BuildRestoreContext(node->context_var()); 3677 BuildRestoreContext(node->context_var());
3622 3678
3623 EffectGraphVisitor for_catch(owner()); 3679 EffectGraphVisitor for_catch(owner());
3624 node->VisitChildren(&for_catch); 3680 node->VisitChildren(&for_catch);
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
3977 LanguageError::kError, 4033 LanguageError::kError,
3978 Heap::kNew, 4034 Heap::kNew,
3979 "FlowGraphBuilder Bailout: %s %s", 4035 "FlowGraphBuilder Bailout: %s %s",
3980 String::Handle(function.name()).ToCString(), 4036 String::Handle(function.name()).ToCString(),
3981 reason)); 4037 reason));
3982 Isolate::Current()->long_jump_base()->Jump(1, error); 4038 Isolate::Current()->long_jump_base()->Jump(1, error);
3983 } 4039 }
3984 4040
3985 4041
3986 } // namespace dart 4042 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698