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

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

Issue 10916119: Allow test context to have multiple true and false branch slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months 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 "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/code_descriptors.h" 8 #include "vm/code_descriptors.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // and a pair of effect graph fragments with zero or one available exits. 139 // and a pair of effect graph fragments with zero or one available exits.
140 // We want to append the branch and (if necessary) a join node to this 140 // We want to append the branch and (if necessary) a join node to this
141 // graph fragment. 141 // graph fragment.
142 ASSERT(is_open()); 142 ASSERT(is_open());
143 143
144 // 1. Connect the test to this graph. 144 // 1. Connect the test to this graph.
145 Append(test_fragment); 145 Append(test_fragment);
146 146
147 // 2. Connect the true and false bodies to the test and record their exits 147 // 2. Connect the true and false bodies to the test and record their exits
148 // (if any). 148 // (if any).
149 TargetEntryInstr* true_entry = new TargetEntryInstr(owner()->try_index()); 149 BlockEntryInstr* true_entry = test_fragment.CreateTrueSuccessor();
150 *test_fragment.true_successor_address() = true_entry;
151 Instruction* true_exit = AppendFragment(true_entry, true_fragment); 150 Instruction* true_exit = AppendFragment(true_entry, true_fragment);
152 151
153 TargetEntryInstr* false_entry = new TargetEntryInstr(owner()->try_index()); 152 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor();
154 *test_fragment.false_successor_address() = false_entry;
155 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 153 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
156 154
157 // 3. Add a join or select one (or neither) of the arms as exit. 155 // 3. Add a join or select one (or neither) of the arms as exit.
158 if (true_exit == NULL) { 156 if (true_exit == NULL) {
159 exit_ = false_exit; // May be NULL. 157 exit_ = false_exit; // May be NULL.
160 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 158 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
161 } else if (false_exit == NULL) { 159 } else if (false_exit == NULL) {
162 exit_ = true_exit; 160 exit_ = true_exit;
163 temp_index_ = true_fragment.temp_index(); 161 temp_index_ = true_fragment.temp_index();
164 } else { 162 } else {
(...skipping 10 matching lines...) Expand all
175 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 173 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
176 const EffectGraphVisitor& body_fragment) { 174 const EffectGraphVisitor& body_fragment) {
177 // We have: a test graph fragment with zero, one, or two available exits; 175 // We have: a test graph fragment with zero, one, or two available exits;
178 // and an effect graph fragment with zero or one available exits. We want 176 // and an effect graph fragment with zero or one available exits. We want
179 // to append the 'while loop' consisting of the test graph fragment as 177 // to append the 'while loop' consisting of the test graph fragment as
180 // condition and the effect graph fragment as body. 178 // condition and the effect graph fragment as body.
181 ASSERT(is_open()); 179 ASSERT(is_open());
182 180
183 // 1. Connect the body to the test if it is reachable, and if so record 181 // 1. Connect the body to the test if it is reachable, and if so record
184 // its exit (if any). 182 // its exit (if any).
185 TargetEntryInstr* body_entry = new TargetEntryInstr(owner()->try_index()); 183 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
186 *test_fragment.true_successor_address() = body_entry;
187 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 184 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
188 185
189 // 2. Connect the test to this graph, including the body if reachable and 186 // 2. Connect the test to this graph, including the body if reachable and
190 // using a fresh join node if the body is reachable and has an open exit. 187 // using a fresh join node if the body is reachable and has an open exit.
191 if (body_exit == NULL) { 188 if (body_exit == NULL) {
192 Append(test_fragment); 189 Append(test_fragment);
193 } else { 190 } else {
194 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index()); 191 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
195 join->set_next(test_fragment.entry()); 192 join->set_next(test_fragment.entry());
196 Goto(join); 193 Goto(join);
197 body_exit->Goto(join); 194 body_exit->Goto(join);
198 } 195 }
199 196
200 // 3. Set the exit to the graph to be the false successor of the test, a 197 // 3. Set the exit to the graph to be the false successor of the test, a
201 // fresh target node 198 // fresh target node
202 exit_ = *test_fragment.false_successor_address() = 199
203 new TargetEntryInstr(owner()->try_index()); 200 exit_ = test_fragment.CreateFalseSuccessor();
204 } 201 }
205 202
206 203
207 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 204 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
208 PushArgumentInstr* result = new PushArgumentInstr(value); 205 PushArgumentInstr* result = new PushArgumentInstr(value);
209 AddInstruction(result); 206 AddInstruction(result);
210 return result; 207 return result;
211 } 208 }
212 209
213 210
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 256 }
260 257
261 258
262 // Loads context saved in 'context_variable' into the current context. 259 // Loads context saved in 'context_variable' into the current context.
263 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 260 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
264 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 261 Value* load_saved_context = Bind(BuildLoadLocal(variable));
265 Do(new StoreContextComp(load_saved_context)); 262 Do(new StoreContextComp(load_saved_context));
266 } 263 }
267 264
268 265
266 void TestGraphVisitor::ConnectBranchesTo(
267 const GrowableArray<TargetEntryInstr**>& branches,
268 JoinEntryInstr* join) const {
269 ASSERT(!branches.is_empty());
270 for (intptr_t i = 0; i < branches.length(); i++) {
271 TargetEntryInstr* target = new TargetEntryInstr(owner()->try_index());
272 *(branches[i]) = target;
273 target->Goto(join);
274 }
275 }
276
277
278 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
279 ConnectBranchesTo(true_successor_addresses_, join);
280 }
281
282
283 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
284 ConnectBranchesTo(false_successor_addresses_, join);
285 }
286
287
288 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
289 const GrowableArray<TargetEntryInstr**>& branches) const {
290 ASSERT(!branches.is_empty());
291
292 if (branches.length() == 1) {
293 TargetEntryInstr* target = new TargetEntryInstr(owner()->try_index());
294 *(branches[0]) = target;
295 return target;
296 }
297
298 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
299 ConnectBranchesTo(branches, join);
300 return join;
301 }
302
303
304 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
305 return CreateSuccessorFor(true_successor_addresses_);
306 }
307
308
309 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
310 return CreateSuccessorFor(false_successor_addresses_);
311 }
312
313
269 void TestGraphVisitor::ReturnValue(Value* value) { 314 void TestGraphVisitor::ReturnValue(Value* value) {
270 if (FLAG_enable_type_checks) { 315 if (FLAG_enable_type_checks) {
271 value = Bind(new AssertBooleanComp(condition_token_pos(), value)); 316 value = Bind(new AssertBooleanComp(condition_token_pos(), value));
272 } 317 }
273 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 318 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
274 Value* constant_true = Bind(new ConstantComp(bool_true)); 319 Value* constant_true = Bind(new ConstantComp(bool_true));
275 StrictCompareComp* comp = 320 StrictCompareComp* comp =
276 new StrictCompareComp(Token::kEQ_STRICT, value, constant_true); 321 new StrictCompareComp(Token::kEQ_STRICT, value, constant_true);
277 BranchInstr* branch = new BranchInstr(comp); 322 BranchInstr* branch = new BranchInstr(comp);
278 AddInstruction(branch); 323 AddInstruction(branch);
279 CloseFragment(); 324 CloseFragment();
280 true_successor_address_ = branch->true_successor_address(); 325
281 false_successor_address_ = branch->false_successor_address(); 326 true_successor_addresses_.Add(branch->true_successor_address());
327 false_successor_addresses_.Add(branch->false_successor_address());
282 } 328 }
283 329
284 330
285 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { 331 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) {
286 ASSERT(!FLAG_enable_type_checks); 332 ASSERT(!FLAG_enable_type_checks);
287 ControlInstruction* branch; 333 ControlInstruction* branch;
288 if (Token::IsStrictEqualityOperator(comp->kind())) { 334 if (Token::IsStrictEqualityOperator(comp->kind())) {
289 branch = new BranchInstr(new StrictCompareComp(comp->kind(), 335 branch = new BranchInstr(new StrictCompareComp(comp->kind(),
290 comp->left(), 336 comp->left(),
291 comp->right())); 337 comp->right()));
292 } else if (Token::IsEqualityOperator(comp->kind()) && 338 } else if (Token::IsEqualityOperator(comp->kind()) &&
293 (comp->left()->BindsToConstantNull() || 339 (comp->left()->BindsToConstantNull() ||
294 comp->right()->BindsToConstantNull())) { 340 comp->right()->BindsToConstantNull())) {
295 branch = new BranchInstr(new StrictCompareComp( 341 branch = new BranchInstr(new StrictCompareComp(
296 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 342 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
297 comp->left(), 343 comp->left(),
298 comp->right())); 344 comp->right()));
299 } else { 345 } else {
300 branch = new BranchInstr(comp); 346 branch = new BranchInstr(comp);
301 } 347 }
302 AddInstruction(branch); 348 AddInstruction(branch);
303 CloseFragment(); 349 CloseFragment();
304 true_successor_address_ = branch->true_successor_address(); 350 true_successor_addresses_.Add(branch->true_successor_address());
305 false_successor_address_ = branch->false_successor_address(); 351 false_successor_addresses_.Add(branch->false_successor_address());
306 } 352 }
307 353
308 354
309 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { 355 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) {
310 ASSERT(!FLAG_enable_type_checks); 356 ASSERT(!FLAG_enable_type_checks);
311 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 357 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
312 Value* constant_true = Bind(new ConstantComp(bool_true)); 358 Value* constant_true = Bind(new ConstantComp(bool_true));
313 BranchInstr* branch = new BranchInstr( 359 BranchInstr* branch = new BranchInstr(
314 new StrictCompareComp(Token::kNE_STRICT, 360 new StrictCompareComp(Token::kNE_STRICT,
315 comp->value(), 361 comp->value(),
316 constant_true)); 362 constant_true));
317 AddInstruction(branch); 363 AddInstruction(branch);
318 CloseFragment(); 364 CloseFragment();
319 true_successor_address_ = branch->true_successor_address(); 365 true_successor_addresses_.Add(branch->true_successor_address());
320 false_successor_address_ = branch->false_successor_address(); 366 false_successor_addresses_.Add(branch->false_successor_address());
321 } 367 }
322 368
323 369
324 void TestGraphVisitor::ReturnComputation(Computation* computation) { 370 void TestGraphVisitor::ReturnComputation(Computation* computation) {
325 if (!FLAG_enable_type_checks) { 371 if (!FLAG_enable_type_checks) {
326 if (computation->AsComparison() != NULL) { 372 if (computation->AsComparison() != NULL) {
327 MergeBranchWithComparison(computation->AsComparison()); 373 MergeBranchWithComparison(computation->AsComparison());
328 return; 374 return;
329 } 375 }
330 if (computation->IsBooleanNegate()) { 376 if (computation->IsBooleanNegate()) {
331 MergeBranchWithNegate(computation->AsBooleanNegate()); 377 MergeBranchWithNegate(computation->AsBooleanNegate());
332 return; 378 return;
333 } 379 }
334 } 380 }
335 ReturnValue(Bind(computation)); 381 ReturnValue(Bind(computation));
336 } 382 }
337 383
338 384
385 // Special handling for AND/OR.
386 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
387 InlineBailout("TestGraphVisitor::VisitBinaryOpNode");
388
389 // Operators "&&" and "||" cannot be overloaded therefore do not call
390 // operator.
391 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
392 TestGraphVisitor for_left(owner(),
393 temp_index(),
394 node->left()->token_pos());
395 node->left()->Visit(&for_left);
396
397 TestGraphVisitor for_right(owner(),
398 temp_index(),
399 node->right()->token_pos());
400 node->right()->Visit(&for_right);
401
402 Append(for_left);
403
404 if (node->kind() == Token::kAND) {
405 AppendFragment(for_left.CreateTrueSuccessor(), for_right);
406 true_successor_addresses_.AddArray(for_right.true_successor_addresses_);
407 false_successor_addresses_.AddArray(for_left.false_successor_addresses_);
408 false_successor_addresses_.AddArray(for_right.false_successor_addresses_);
409 } else {
410 ASSERT(node->kind() == Token::kOR);
411 AppendFragment(for_left.CreateFalseSuccessor(), for_right);
412 false_successor_addresses_.AddArray(for_right.false_successor_addresses_);
413 true_successor_addresses_.AddArray(for_left.true_successor_addresses_);
414 true_successor_addresses_.AddArray(for_right.true_successor_addresses_);
415 }
416 CloseFragment();
417 return;
418 }
419 ValueGraphVisitor::VisitBinaryOpNode(node);
420 }
421
422
339 void EffectGraphVisitor::Bailout(const char* reason) { 423 void EffectGraphVisitor::Bailout(const char* reason) {
340 owner()->Bailout(reason); 424 owner()->Bailout(reason);
341 } 425 }
342 426
343 427
344 void EffectGraphVisitor::InlineBailout(const char* reason) { 428 void EffectGraphVisitor::InlineBailout(const char* reason) {
345 if (owner()->InInliningContext()) owner()->Bailout(reason); 429 if (owner()->InInliningContext()) owner()->Bailout(reason);
346 } 430 }
347 431
348 432
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 AppendFragment(statement_start, for_case_statements); 1101 AppendFragment(statement_start, for_case_statements);
1018 if (is_open() && (len == 0)) { 1102 if (is_open() && (len == 0)) {
1019 ASSERT(node->contains_default()); 1103 ASSERT(node->contains_default());
1020 // Default only case node. 1104 // Default only case node.
1021 Goto(statement_start); 1105 Goto(statement_start);
1022 exit_ = statement_exit; 1106 exit_ = statement_exit;
1023 return; 1107 return;
1024 } 1108 }
1025 1109
1026 // Generate instructions for all case expressions. 1110 // Generate instructions for all case expressions.
1027 TargetEntryInstr** previous_false_address = NULL; 1111 TargetEntryInstr* next_target = NULL;
1028 for (intptr_t i = 0; i < len; i++) { 1112 for (intptr_t i = 0; i < len; i++) {
1029 AstNode* case_expr = node->case_expressions()->NodeAt(i); 1113 AstNode* case_expr = node->case_expressions()->NodeAt(i);
1030 TestGraphVisitor for_case_expression(owner(), 1114 TestGraphVisitor for_case_expression(owner(),
1031 temp_index(), 1115 temp_index(),
1032 case_expr->token_pos()); 1116 case_expr->token_pos());
1033 case_expr->Visit(&for_case_expression); 1117 case_expr->Visit(&for_case_expression);
1034 if (i == 0) { 1118 if (i == 0) {
1035 // Append only the first one, everything else is connected from it. 1119 // Append only the first one, everything else is connected from it.
1036 Append(for_case_expression); 1120 Append(for_case_expression);
1037 } else { 1121 } else {
1038 TargetEntryInstr* case_entry_target = 1122 ASSERT(next_target != NULL);
1039 new TargetEntryInstr(owner()->try_index()); 1123 AppendFragment(next_target, for_case_expression);
1040 AppendFragment(case_entry_target, for_case_expression);
1041 *previous_false_address = case_entry_target;
1042 } 1124 }
1043 TargetEntryInstr* true_target = 1125 for_case_expression.IfTrueGoto(statement_start);
1044 new TargetEntryInstr(owner()->try_index()); 1126 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry();
1045 *for_case_expression.true_successor_address() = true_target;
1046 true_target->Goto(statement_start);
1047 previous_false_address = for_case_expression.false_successor_address();
1048 } 1127 }
1049 1128
1050 // Once a test fragment has been added, this fragment is closed. 1129 // Once a test fragment has been added, this fragment is closed.
1051 ASSERT(!is_open()); 1130 ASSERT(!is_open());
1052 1131
1053 Instruction* exit_instruction = NULL; 1132 Instruction* exit_instruction = NULL;
1054 // Handle last (or only) case: false goes to exit or to statement if this 1133 // Handle last (or only) case: false goes to exit or to statement if this
1055 // node contains default. 1134 // node contains default.
1056 if (len > 0) { 1135 if (len > 0) {
1057 TargetEntryInstr* false_target = 1136 ASSERT(next_target != NULL);
1058 new TargetEntryInstr(owner()->try_index());
1059 *previous_false_address = false_target;
1060 if (node->contains_default()) { 1137 if (node->contains_default()) {
1061 // True and false go to statement start. 1138 // True and false go to statement start.
1062 false_target->Goto(statement_start); 1139 next_target->Goto(statement_start);
1063 exit_instruction = statement_exit; 1140 exit_instruction = statement_exit;
1064 } else { 1141 } else {
1065 if (statement_exit != NULL) { 1142 if (statement_exit != NULL) {
1066 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index()); 1143 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
1067 statement_exit->Goto(join); 1144 statement_exit->Goto(join);
1068 false_target->Goto(join); 1145 next_target->Goto(join);
1069 exit_instruction = join; 1146 exit_instruction = join;
1070 } else { 1147 } else {
1071 exit_instruction = false_target; 1148 exit_instruction = next_target;
1072 } 1149 }
1073 } 1150 }
1074 } else { 1151 } else {
1075 // A CaseNode without case expressions must contain default. 1152 // A CaseNode without case expressions must contain default.
1076 ASSERT(node->contains_default()); 1153 ASSERT(node->contains_default());
1077 Goto(statement_start); 1154 Goto(statement_start);
1078 exit_instruction = statement_exit; 1155 exit_instruction = statement_exit;
1079 } 1156 }
1080 1157
1081 ASSERT(!is_open()); 1158 ASSERT(!is_open());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 1230
1154 JoinEntryInstr* join = node->label()->join_for_continue(); 1231 JoinEntryInstr* join = node->label()->join_for_continue();
1155 if ((body_exit != NULL) || (join != NULL)) { 1232 if ((body_exit != NULL) || (join != NULL)) {
1156 if (join == NULL) join = new JoinEntryInstr(owner()->try_index()); 1233 if (join == NULL) join = new JoinEntryInstr(owner()->try_index());
1157 join->set_next(for_test.entry()); 1234 join->set_next(for_test.entry());
1158 if (body_exit != NULL) { 1235 if (body_exit != NULL) {
1159 body_exit->Goto(join); 1236 body_exit->Goto(join);
1160 } 1237 }
1161 } 1238 }
1162 1239
1163 TargetEntryInstr* back_target_entry = 1240
1164 new TargetEntryInstr(owner()->try_index()); 1241 for_test.IfTrueGoto(body_entry_join);
1165 *for_test.true_successor_address() = back_target_entry;
1166 back_target_entry->Goto(body_entry_join);
1167 TargetEntryInstr* loop_exit_target =
1168 new TargetEntryInstr(owner()->try_index());
1169 *for_test.false_successor_address() = loop_exit_target;
1170 if (node->label()->join_for_break() == NULL) { 1242 if (node->label()->join_for_break() == NULL) {
1171 exit_ = loop_exit_target; 1243 exit_ = for_test.CreateFalseSuccessor();
1172 } else { 1244 } else {
1173 loop_exit_target->Goto(node->label()->join_for_break()); 1245 for_test.IfFalseGoto(node->label()->join_for_break());
1174 exit_ = node->label()->join_for_break(); 1246 exit_ = node->label()->join_for_break();
1175 } 1247 }
1176 } 1248 }
1177 1249
1178 1250
1179 // A ForNode can contain break and continue jumps. 'break' joins to 1251 // A ForNode can contain break and continue jumps. 'break' joins to
1180 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1252 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1181 // as follows: 1253 // as follows:
1182 // a) [ initializer ] 1254 // a) [ initializer ]
1183 // b) loop-join 1255 // b) loop-join
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 if (node->condition() == NULL) { 1306 if (node->condition() == NULL) {
1235 // Endless loop, no test. 1307 // Endless loop, no test.
1236 JoinEntryInstr* body_entry = new JoinEntryInstr(owner()->try_index()); 1308 JoinEntryInstr* body_entry = new JoinEntryInstr(owner()->try_index());
1237 AppendFragment(body_entry, for_body); 1309 AppendFragment(body_entry, for_body);
1238 Goto(body_entry); 1310 Goto(body_entry);
1239 if (node->label()->join_for_break() != NULL) { 1311 if (node->label()->join_for_break() != NULL) {
1240 // Control flow of ForLoop continues into join_for_break. 1312 // Control flow of ForLoop continues into join_for_break.
1241 exit_ = node->label()->join_for_break(); 1313 exit_ = node->label()->join_for_break();
1242 } 1314 }
1243 } else { 1315 } else {
1244 TargetEntryInstr* loop_exit = new TargetEntryInstr(owner()->try_index());
1245 TestGraphVisitor for_test(owner(), 1316 TestGraphVisitor for_test(owner(),
1246 temp_index(), 1317 temp_index(),
1247 node->condition()->token_pos()); 1318 node->condition()->token_pos());
1248 node->condition()->Visit(&for_test); 1319 node->condition()->Visit(&for_test);
1249 Append(for_test); 1320 Append(for_test);
1250 TargetEntryInstr* body_entry = new TargetEntryInstr(owner()->try_index()); 1321
1322 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor();
1251 AppendFragment(body_entry, for_body); 1323 AppendFragment(body_entry, for_body);
1252 *for_test.true_successor_address() = body_entry; 1324
1253 *for_test.false_successor_address() = loop_exit;
1254 if (node->label()->join_for_break() == NULL) { 1325 if (node->label()->join_for_break() == NULL) {
1255 exit_ = loop_exit; 1326 exit_ = for_test.CreateFalseSuccessor();
1256 } else { 1327 } else {
1257 loop_exit->Goto(node->label()->join_for_break()); 1328 for_test.IfFalseGoto(node->label()->join_for_break());
1258 exit_ = node->label()->join_for_break(); 1329 exit_ = node->label()->join_for_break();
1259 } 1330 }
1260 } 1331 }
1261 } 1332 }
1262 1333
1263 1334
1264 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1335 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1265 InlineBailout("EffectGraphVisitor::VisitJumpNode"); 1336 InlineBailout("EffectGraphVisitor::VisitJumpNode");
1266 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1337 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1267 EffectGraphVisitor for_effect(owner(), temp_index()); 1338 EffectGraphVisitor for_effect(owner(), temp_index());
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2539 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2610 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2540 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2611 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2541 OS::SNPrint(chars, len, kFormat, function_name, reason); 2612 OS::SNPrint(chars, len, kFormat, function_name, reason);
2542 const Error& error = Error::Handle( 2613 const Error& error = Error::Handle(
2543 LanguageError::New(String::Handle(String::New(chars)))); 2614 LanguageError::New(String::Handle(String::New(chars))));
2544 Isolate::Current()->long_jump_base()->Jump(1, error); 2615 Isolate::Current()->long_jump_base()->Jump(1, error);
2545 } 2616 }
2546 2617
2547 2618
2548 } // namespace dart 2619 } // 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