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

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

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

Powered by Google App Engine
This is Rietveld 408576698