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

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

Issue 10964012: Revert "A simpler scheme for garbage collection of ureachable phi inputs." (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') | runtime/vm/flow_graph_optimizer.cc » ('j') | 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 19 matching lines...) Expand all
30 30
31 31
32 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function) 32 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function)
33 : parsed_function_(parsed_function), 33 : parsed_function_(parsed_function),
34 num_copied_params_(parsed_function.num_copied_params()), 34 num_copied_params_(parsed_function.num_copied_params()),
35 // All parameters are copied if any parameter is. 35 // All parameters are copied if any parameter is.
36 num_non_copied_params_((num_copied_params_ == 0) 36 num_non_copied_params_((num_copied_params_ == 0)
37 ? parsed_function.function().num_fixed_parameters() 37 ? parsed_function.function().num_fixed_parameters()
38 : 0), 38 : 0),
39 num_stack_locals_(parsed_function.num_stack_locals()), 39 num_stack_locals_(parsed_function.num_stack_locals()),
40 last_used_block_id_(0), // 0 is used for the graph entry.
41 context_level_(0), 40 context_level_(0),
42 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), 41 last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
43 try_index_(CatchClauseNode::kInvalidTryIndex), 42 try_index_(CatchClauseNode::kInvalidTryIndex),
44 graph_entry_(NULL), 43 graph_entry_(NULL),
45 inlining_context_(kNotInlining), 44 inlining_context_(kNotInlining),
46 exits_(NULL) { } 45 exits_(NULL) { }
47 46
48 47
49 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { 48 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) {
50 graph_entry_->AddCatchEntry(entry); 49 graph_entry_->AddCatchEntry(entry);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 153 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
155 154
156 // 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.
157 if (true_exit == NULL) { 156 if (true_exit == NULL) {
158 exit_ = false_exit; // May be NULL. 157 exit_ = false_exit; // May be NULL.
159 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 158 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
160 } else if (false_exit == NULL) { 159 } else if (false_exit == NULL) {
161 exit_ = true_exit; 160 exit_ = true_exit;
162 temp_index_ = true_fragment.temp_index(); 161 temp_index_ = true_fragment.temp_index();
163 } else { 162 } else {
164 JoinEntryInstr* join = 163 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
165 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
166 true_exit->Goto(join); 164 true_exit->Goto(join);
167 false_exit->Goto(join); 165 false_exit->Goto(join);
168 exit_ = join; 166 exit_ = join;
169 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 167 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
170 temp_index_ = true_fragment.temp_index(); 168 temp_index_ = true_fragment.temp_index();
171 } 169 }
172 } 170 }
173 171
174 172
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 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 183 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
186 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 184 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
187 185
188 // 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
189 // 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.
190 if (body_exit == NULL) { 188 if (body_exit == NULL) {
191 Append(test_fragment); 189 Append(test_fragment);
192 } else { 190 } else {
193 JoinEntryInstr* join = 191 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
194 new JoinEntryInstr(owner()->AllocateBlockId(), 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 199
203 exit_ = test_fragment.CreateFalseSuccessor(); 200 exit_ = test_fragment.CreateFalseSuccessor();
204 } 201 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 292 Value* load_saved_context = Bind(BuildLoadLocal(variable));
296 AddInstruction(new StoreContextInstr(load_saved_context)); 293 AddInstruction(new StoreContextInstr(load_saved_context));
297 } 294 }
298 295
299 296
300 void TestGraphVisitor::ConnectBranchesTo( 297 void TestGraphVisitor::ConnectBranchesTo(
301 const GrowableArray<TargetEntryInstr**>& branches, 298 const GrowableArray<TargetEntryInstr**>& branches,
302 JoinEntryInstr* join) const { 299 JoinEntryInstr* join) const {
303 ASSERT(!branches.is_empty()); 300 ASSERT(!branches.is_empty());
304 for (intptr_t i = 0; i < branches.length(); i++) { 301 for (intptr_t i = 0; i < branches.length(); i++) {
305 TargetEntryInstr* target = 302 TargetEntryInstr* target = new TargetEntryInstr(owner()->try_index());
306 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
307 *(branches[i]) = target; 303 *(branches[i]) = target;
308 target->Goto(join); 304 target->Goto(join);
309 } 305 }
310 } 306 }
311 307
312 308
313 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 309 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
314 ConnectBranchesTo(true_successor_addresses_, join); 310 ConnectBranchesTo(true_successor_addresses_, join);
315 } 311 }
316 312
317 313
318 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 314 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
319 ConnectBranchesTo(false_successor_addresses_, join); 315 ConnectBranchesTo(false_successor_addresses_, join);
320 } 316 }
321 317
322 318
323 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 319 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
324 const GrowableArray<TargetEntryInstr**>& branches) const { 320 const GrowableArray<TargetEntryInstr**>& branches) const {
325 ASSERT(!branches.is_empty()); 321 ASSERT(!branches.is_empty());
326 322
327 if (branches.length() == 1) { 323 if (branches.length() == 1) {
328 TargetEntryInstr* target = 324 TargetEntryInstr* target = new TargetEntryInstr(owner()->try_index());
329 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
330 *(branches[0]) = target; 325 *(branches[0]) = target;
331 return target; 326 return target;
332 } 327 }
333 328
334 JoinEntryInstr* join = 329 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
335 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
336 ConnectBranchesTo(branches, join); 330 ConnectBranchesTo(branches, join);
337 return join; 331 return join;
338 } 332 }
339 333
340 334
341 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 335 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
342 return CreateSuccessorFor(true_successor_addresses_); 336 return CreateSuccessorFor(true_successor_addresses_);
343 } 337 }
344 338
345 339
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 const intptr_t len = node->case_expressions()->length(); 1090 const intptr_t len = node->case_expressions()->length();
1097 // Create case statements instructions. 1091 // Create case statements instructions.
1098 EffectGraphVisitor for_case_statements(owner(), temp_index()); 1092 EffectGraphVisitor for_case_statements(owner(), temp_index());
1099 // Compute start of statements fragment. 1093 // Compute start of statements fragment.
1100 JoinEntryInstr* statement_start = NULL; 1094 JoinEntryInstr* statement_start = NULL;
1101 if ((node->label() != NULL) && node->label()->is_continue_target()) { 1095 if ((node->label() != NULL) && node->label()->is_continue_target()) {
1102 // Since a labeled jump continue statement occur in a different case node, 1096 // Since a labeled jump continue statement occur in a different case node,
1103 // allocate JoinNode here and use it as statement start. 1097 // allocate JoinNode here and use it as statement start.
1104 statement_start = node->label()->join_for_continue(); 1098 statement_start = node->label()->join_for_continue();
1105 if (statement_start == NULL) { 1099 if (statement_start == NULL) {
1106 statement_start = 1100 statement_start = new JoinEntryInstr(owner()->try_index());
1107 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1108 node->label()->set_join_for_continue(statement_start); 1101 node->label()->set_join_for_continue(statement_start);
1109 } 1102 }
1110 } else { 1103 } else {
1111 statement_start = 1104 statement_start = new JoinEntryInstr(owner()->try_index());
1112 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1113 } 1105 }
1114 node->statements()->Visit(&for_case_statements); 1106 node->statements()->Visit(&for_case_statements);
1115 Instruction* statement_exit = 1107 Instruction* statement_exit =
1116 AppendFragment(statement_start, for_case_statements); 1108 AppendFragment(statement_start, for_case_statements);
1117 if (is_open() && (len == 0)) { 1109 if (is_open() && (len == 0)) {
1118 ASSERT(node->contains_default()); 1110 ASSERT(node->contains_default());
1119 // Default only case node. 1111 // Default only case node.
1120 Goto(statement_start); 1112 Goto(statement_start);
1121 exit_ = statement_exit; 1113 exit_ = statement_exit;
1122 return; 1114 return;
(...skipping 25 matching lines...) Expand all
1148 // Handle last (or only) case: false goes to exit or to statement if this 1140 // Handle last (or only) case: false goes to exit or to statement if this
1149 // node contains default. 1141 // node contains default.
1150 if (len > 0) { 1142 if (len > 0) {
1151 ASSERT(next_target != NULL); 1143 ASSERT(next_target != NULL);
1152 if (node->contains_default()) { 1144 if (node->contains_default()) {
1153 // True and false go to statement start. 1145 // True and false go to statement start.
1154 next_target->Goto(statement_start); 1146 next_target->Goto(statement_start);
1155 exit_instruction = statement_exit; 1147 exit_instruction = statement_exit;
1156 } else { 1148 } else {
1157 if (statement_exit != NULL) { 1149 if (statement_exit != NULL) {
1158 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), 1150 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
1159 owner()->try_index());
1160 statement_exit->Goto(join); 1151 statement_exit->Goto(join);
1161 next_target->Goto(join); 1152 next_target->Goto(join);
1162 exit_instruction = join; 1153 exit_instruction = join;
1163 } else { 1154 } else {
1164 exit_instruction = next_target; 1155 exit_instruction = next_target;
1165 } 1156 }
1166 } 1157 }
1167 } else { 1158 } else {
1168 // A CaseNode without case expressions must contain default. 1159 // A CaseNode without case expressions must contain default.
1169 ASSERT(node->contains_default()); 1160 ASSERT(node->contains_default());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 new CheckStackOverflowInstr(node->token_pos())); 1224 new CheckStackOverflowInstr(node->token_pos()));
1234 node->body()->Visit(&for_body); 1225 node->body()->Visit(&for_body);
1235 1226
1236 TestGraphVisitor for_test(owner(), 1227 TestGraphVisitor for_test(owner(),
1237 temp_index(), 1228 temp_index(),
1238 node->condition()->token_pos()); 1229 node->condition()->token_pos());
1239 node->condition()->Visit(&for_test); 1230 node->condition()->Visit(&for_test);
1240 ASSERT(is_open()); 1231 ASSERT(is_open());
1241 1232
1242 // Tie do-while loop (test is after the body). 1233 // Tie do-while loop (test is after the body).
1243 JoinEntryInstr* body_entry_join = 1234 JoinEntryInstr* body_entry_join = new JoinEntryInstr(owner()->try_index());
1244 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1245 Goto(body_entry_join); 1235 Goto(body_entry_join);
1246 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1236 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1247 1237
1248 JoinEntryInstr* join = node->label()->join_for_continue(); 1238 JoinEntryInstr* join = node->label()->join_for_continue();
1249 if ((body_exit != NULL) || (join != NULL)) { 1239 if ((body_exit != NULL) || (join != NULL)) {
1250 if (join == NULL) { 1240 if (join == NULL) join = new JoinEntryInstr(owner()->try_index());
1251 join =
1252 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1253 }
1254 join->set_next(for_test.entry()); 1241 join->set_next(for_test.entry());
1255 if (body_exit != NULL) { 1242 if (body_exit != NULL) {
1256 body_exit->Goto(join); 1243 body_exit->Goto(join);
1257 } 1244 }
1258 } 1245 }
1259 1246
1260 1247
1261 for_test.IfTrueGoto(body_entry_join); 1248 for_test.IfTrueGoto(body_entry_join);
1262 if (node->label()->join_for_break() == NULL) { 1249 if (node->label()->join_for_break() == NULL) {
1263 exit_ = for_test.CreateFalseSuccessor(); 1250 exit_ = for_test.CreateFalseSuccessor();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 loop_increment_end = for_body.exit(); 1297 loop_increment_end = for_body.exit();
1311 // 'for_body' contains at least the stack check. 1298 // 'for_body' contains at least the stack check.
1312 ASSERT(loop_increment_end != NULL); 1299 ASSERT(loop_increment_end != NULL);
1313 } else { 1300 } else {
1314 loop_increment_end = NULL; 1301 loop_increment_end = NULL;
1315 } 1302 }
1316 1303
1317 // 'loop_increment_end' is NULL only if there is no join for continue and the 1304 // 'loop_increment_end' is NULL only if there is no join for continue and the
1318 // body is not open, i.e., no backward branch exists. 1305 // body is not open, i.e., no backward branch exists.
1319 if (loop_increment_end != NULL) { 1306 if (loop_increment_end != NULL) {
1320 JoinEntryInstr* loop_start = 1307 JoinEntryInstr* loop_start = new JoinEntryInstr(owner()->try_index());
1321 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1322 Goto(loop_start); 1308 Goto(loop_start);
1323 loop_increment_end->Goto(loop_start); 1309 loop_increment_end->Goto(loop_start);
1324 exit_ = loop_start; 1310 exit_ = loop_start;
1325 } 1311 }
1326 1312
1327 if (node->condition() == NULL) { 1313 if (node->condition() == NULL) {
1328 // Endless loop, no test. 1314 // Endless loop, no test.
1329 JoinEntryInstr* body_entry = 1315 JoinEntryInstr* body_entry = new JoinEntryInstr(owner()->try_index());
1330 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1331 AppendFragment(body_entry, for_body); 1316 AppendFragment(body_entry, for_body);
1332 Goto(body_entry); 1317 Goto(body_entry);
1333 if (node->label()->join_for_break() != NULL) { 1318 if (node->label()->join_for_break() != NULL) {
1334 // Control flow of ForLoop continues into join_for_break. 1319 // Control flow of ForLoop continues into join_for_break.
1335 exit_ = node->label()->join_for_break(); 1320 exit_ = node->label()->join_for_break();
1336 } 1321 }
1337 } else { 1322 } else {
1338 TestGraphVisitor for_test(owner(), 1323 TestGraphVisitor for_test(owner(),
1339 temp_index(), 1324 temp_index(),
1340 node->condition()->token_pos()); 1325 node->condition()->token_pos());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 intptr_t current_context_level = owner()->context_level(); 1373 intptr_t current_context_level = owner()->context_level();
1389 ASSERT(current_context_level >= target_context_level); 1374 ASSERT(current_context_level >= target_context_level);
1390 while (current_context_level-- > target_context_level) { 1375 while (current_context_level-- > target_context_level) {
1391 UnchainContext(); 1376 UnchainContext();
1392 } 1377 }
1393 1378
1394 JoinEntryInstr* jump_target = NULL; 1379 JoinEntryInstr* jump_target = NULL;
1395 if (node->kind() == Token::kBREAK) { 1380 if (node->kind() == Token::kBREAK) {
1396 if (node->label()->join_for_break() == NULL) { 1381 if (node->label()->join_for_break() == NULL) {
1397 node->label()->set_join_for_break( 1382 node->label()->set_join_for_break(
1398 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); 1383 new JoinEntryInstr(owner()->try_index()));
1399 } 1384 }
1400 jump_target = node->label()->join_for_break(); 1385 jump_target = node->label()->join_for_break();
1401 } else { 1386 } else {
1402 if (node->label()->join_for_continue() == NULL) { 1387 if (node->label()->join_for_continue() == NULL) {
1403 node->label()->set_join_for_continue( 1388 node->label()->set_join_for_continue(
1404 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); 1389 new JoinEntryInstr(owner()->try_index()));
1405 } 1390 }
1406 jump_target = node->label()->join_for_continue(); 1391 jump_target = node->label()->join_for_continue();
1407 } 1392 }
1408 Goto(jump_target); 1393 Goto(jump_target);
1409 } 1394 }
1410 1395
1411 1396
1412 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1397 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1413 UNREACHABLE(); 1398 UNREACHABLE();
1414 } 1399 }
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 intptr_t try_index = owner()->AllocateTryIndex(); 2466 intptr_t try_index = owner()->AllocateTryIndex();
2482 owner()->set_try_index(try_index); 2467 owner()->set_try_index(try_index);
2483 2468
2484 // Preserve CTX into local variable '%saved_context'. 2469 // Preserve CTX into local variable '%saved_context'.
2485 BuildStoreContext(node->context_var()); 2470 BuildStoreContext(node->context_var());
2486 2471
2487 EffectGraphVisitor for_try_block(owner(), temp_index()); 2472 EffectGraphVisitor for_try_block(owner(), temp_index());
2488 node->try_block()->Visit(&for_try_block); 2473 node->try_block()->Visit(&for_try_block);
2489 2474
2490 if (for_try_block.is_open()) { 2475 if (for_try_block.is_open()) {
2491 JoinEntryInstr* after_try = 2476 JoinEntryInstr* after_try = new JoinEntryInstr(old_try_index);
2492 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index);
2493 for_try_block.Goto(after_try); 2477 for_try_block.Goto(after_try);
2494 for_try_block.exit_ = after_try; 2478 for_try_block.exit_ = after_try;
2495 } 2479 }
2496 2480
2497 JoinEntryInstr* try_entry = 2481 JoinEntryInstr* try_entry = new JoinEntryInstr(try_index);
2498 new JoinEntryInstr(owner()->AllocateBlockId(), try_index);
2499 2482
2500 Goto(try_entry); 2483 Goto(try_entry);
2501 AppendFragment(try_entry, for_try_block); 2484 AppendFragment(try_entry, for_try_block);
2502 exit_ = for_try_block.exit_; 2485 exit_ = for_try_block.exit_;
2503 2486
2504 // We are done generating code for the try block. 2487 // We are done generating code for the try block.
2505 owner()->set_try_index(old_try_index); 2488 owner()->set_try_index(old_try_index);
2506 2489
2507 CatchClauseNode* catch_block = node->catch_block(); 2490 CatchClauseNode* catch_block = node->catch_block();
2508 if (catch_block != NULL) { 2491 if (catch_block != NULL) {
2509 // Set the corresponding try index for this catch block so 2492 // Set the corresponding try index for this catch block so
2510 // that we can set the appropriate handler pc when we generate 2493 // that we can set the appropriate handler pc when we generate
2511 // code for this catch block. 2494 // code for this catch block.
2512 catch_block->set_try_index(try_index); 2495 catch_block->set_try_index(try_index);
2513 EffectGraphVisitor for_catch_block(owner(), temp_index()); 2496 EffectGraphVisitor for_catch_block(owner(), temp_index());
2514 catch_block->Visit(&for_catch_block); 2497 catch_block->Visit(&for_catch_block);
2515 TargetEntryInstr* catch_entry = 2498 TargetEntryInstr* catch_entry = new TargetEntryInstr(old_try_index,
2516 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index); 2499 try_index);
2517 catch_entry->set_catch_try_index(try_index);
2518 owner()->AddCatchEntry(catch_entry); 2500 owner()->AddCatchEntry(catch_entry);
2519 ASSERT(!for_catch_block.is_open()); 2501 ASSERT(!for_catch_block.is_open());
2520 AppendFragment(catch_entry, for_catch_block); 2502 AppendFragment(catch_entry, for_catch_block);
2521 if (node->end_catch_label() != NULL) { 2503 if (node->end_catch_label() != NULL) {
2522 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); 2504 JoinEntryInstr* join = node->end_catch_label()->join_for_continue();
2523 if (join != NULL) { 2505 if (join != NULL) {
2524 if (is_open()) Goto(join); 2506 if (is_open()) Goto(join);
2525 exit_ = join; 2507 exit_ = join;
2526 } 2508 }
2527 } 2509 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); 2559 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)");
2578 const intptr_t try_index = owner()->try_index(); 2560 const intptr_t try_index = owner()->try_index();
2579 if (try_index >= 0) { 2561 if (try_index >= 0) {
2580 // We are about to generate code for an inlined finally block. Exceptions 2562 // We are about to generate code for an inlined finally block. Exceptions
2581 // thrown in this block of code should be treated as though they are 2563 // thrown in this block of code should be treated as though they are
2582 // thrown not from the current try block but the outer try block if any. 2564 // thrown not from the current try block but the outer try block if any.
2583 owner()->set_try_index((try_index - 1)); 2565 owner()->set_try_index((try_index - 1));
2584 } 2566 }
2585 BuildLoadContext(node->context_var()); 2567 BuildLoadContext(node->context_var());
2586 2568
2587 JoinEntryInstr* finally_entry = 2569 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index());
2588 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2589 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2570 EffectGraphVisitor for_finally_block(owner(), temp_index());
2590 node->finally_block()->Visit(&for_finally_block); 2571 node->finally_block()->Visit(&for_finally_block);
2591 2572
2592 if (try_index >= 0) { 2573 if (try_index >= 0) {
2593 owner()->set_try_index(try_index); 2574 owner()->set_try_index(try_index);
2594 } 2575 }
2595 2576
2596 if (for_finally_block.is_open()) { 2577 if (for_finally_block.is_open()) {
2597 JoinEntryInstr* after_finally = 2578 JoinEntryInstr* after_finally = new JoinEntryInstr(owner()->try_index());
2598 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2599 for_finally_block.Goto(after_finally); 2579 for_finally_block.Goto(after_finally);
2600 for_finally_block.exit_ = after_finally; 2580 for_finally_block.exit_ = after_finally;
2601 } 2581 }
2602 2582
2603 Goto(finally_entry); 2583 Goto(finally_entry);
2604 AppendFragment(finally_entry, for_finally_block); 2584 AppendFragment(finally_entry, for_finally_block);
2605 exit_ = for_finally_block.exit_; 2585 exit_ = for_finally_block.exit_;
2606 } 2586 }
2607 2587
2608 2588
2609 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { 2589 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) {
2610 if (FLAG_print_ast) { 2590 if (FLAG_print_ast) {
2611 // Print the function ast before IL generation. 2591 // Print the function ast before IL generation.
2612 AstPrinter::PrintFunctionNodes(parsed_function()); 2592 AstPrinter::PrintFunctionNodes(parsed_function());
2613 } 2593 }
2614 // Set the inlining context. 2594 // Set the inlining context.
2615 ASSERT(inlining_context_ == kNotInlining); 2595 ASSERT(inlining_context_ == kNotInlining);
2616 inlining_context_ = context; 2596 inlining_context_ = context;
2617 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); 2597 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>();
2618 // Compilation can be nested, preserve the computation-id. 2598 // Compilation can be nested, preserve the computation-id.
2619 const Function& function = parsed_function().function(); 2599 const Function& function = parsed_function().function();
2620 TargetEntryInstr* normal_entry = 2600 TargetEntryInstr* normal_entry = new TargetEntryInstr(
2621 new TargetEntryInstr(AllocateBlockId(), 2601 CatchClauseNode::kInvalidTryIndex);
2622 CatchClauseNode::kInvalidTryIndex);
2623 graph_entry_ = new GraphEntryInstr(normal_entry); 2602 graph_entry_ = new GraphEntryInstr(normal_entry);
2624 EffectGraphVisitor for_effect(this, 0); 2603 EffectGraphVisitor for_effect(this, 0);
2625 if (InInliningContext()) { 2604 if (InInliningContext()) {
2626 exits_ = new ZoneGrowableArray<ReturnInstr*>(); 2605 exits_ = new ZoneGrowableArray<ReturnInstr*>();
2627 } 2606 }
2628 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the 2607 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the
2629 // stack check on entry for leaf routines). 2608 // stack check on entry for leaf routines).
2630 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); 2609 Instruction* check = new CheckStackOverflowInstr(function.token_pos());
2631 // If we are inlining don't actually attach the stack check. We must still 2610 // If we are inlining don't actually attach the stack check. We must still
2632 // create the stack check inorder to allocate a deopt id. 2611 // create the stack check inorder to allocate a deopt id.
(...skipping 14 matching lines...) Expand all
2647 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2626 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2648 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2627 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2649 OS::SNPrint(chars, len, kFormat, function_name, reason); 2628 OS::SNPrint(chars, len, kFormat, function_name, reason);
2650 const Error& error = Error::Handle( 2629 const Error& error = Error::Handle(
2651 LanguageError::New(String::Handle(String::New(chars)))); 2630 LanguageError::New(String::Handle(String::New(chars))));
2652 Isolate::Current()->long_jump_base()->Jump(1, error); 2631 Isolate::Current()->long_jump_base()->Jump(1, error);
2653 } 2632 }
2654 2633
2655 2634
2656 } // namespace dart 2635 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698