| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "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 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 // e) true-target-0 -> case-statements-join | 1085 // e) true-target-0 -> case-statements-join |
| 1086 // f) true-target-1 -> case-statements-join | 1086 // f) true-target-1 -> case-statements-join |
| 1087 // g) case-statements-join | 1087 // g) case-statements-join |
| 1088 // h) [ case-statements ] -> exit-join | 1088 // h) [ case-statements ] -> exit-join |
| 1089 // i) exit-target -> exit-join | 1089 // i) exit-target -> exit-join |
| 1090 // j) exit-join | 1090 // j) exit-join |
| 1091 // | 1091 // |
| 1092 // Note: The specification of switch/case is under discussion and may change | 1092 // Note: The specification of switch/case is under discussion and may change |
| 1093 // drastically. | 1093 // drastically. |
| 1094 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1094 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1095 InlineBailout("EffectGraphVisitor::VisitCaseNode (control)"); | |
| 1096 const intptr_t len = node->case_expressions()->length(); | 1095 const intptr_t len = node->case_expressions()->length(); |
| 1097 // Create case statements instructions. | 1096 // Create case statements instructions. |
| 1098 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 1097 EffectGraphVisitor for_case_statements(owner(), temp_index()); |
| 1099 // Compute start of statements fragment. | 1098 // Compute start of statements fragment. |
| 1100 JoinEntryInstr* statement_start = NULL; | 1099 JoinEntryInstr* statement_start = NULL; |
| 1101 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1100 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1102 // Since a labeled jump continue statement occur in a different case node, | 1101 // Since a labeled jump continue statement occur in a different case node, |
| 1103 // allocate JoinNode here and use it as statement start. | 1102 // allocate JoinNode here and use it as statement start. |
| 1104 statement_start = node->label()->join_for_continue(); | 1103 statement_start = node->label()->join_for_continue(); |
| 1105 if (statement_start == NULL) { | 1104 if (statement_start == NULL) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 // body: <Sequence> } | 1180 // body: <Sequence> } |
| 1182 // The fragment is composed as follows: | 1181 // The fragment is composed as follows: |
| 1183 // a) loop-join | 1182 // a) loop-join |
| 1184 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1183 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1185 // c) body-entry-target | 1184 // c) body-entry-target |
| 1186 // d) [ body ] -> (continue-join) | 1185 // d) [ body ] -> (continue-join) |
| 1187 // e) continue-join -> (loop-join) | 1186 // e) continue-join -> (loop-join) |
| 1188 // f) loop-exit-target | 1187 // f) loop-exit-target |
| 1189 // g) break-join (optional) | 1188 // g) break-join (optional) |
| 1190 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1189 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1191 InlineBailout("EffectGraphVisitor::VisitWhileNode (control)"); | |
| 1192 TestGraphVisitor for_test(owner(), | 1190 TestGraphVisitor for_test(owner(), |
| 1193 temp_index(), | 1191 temp_index(), |
| 1194 node->condition()->token_pos()); | 1192 node->condition()->token_pos()); |
| 1195 node->condition()->Visit(&for_test); | 1193 node->condition()->Visit(&for_test); |
| 1196 ASSERT(!for_test.is_empty()); // Language spec. | 1194 ASSERT(!for_test.is_empty()); // Language spec. |
| 1197 | 1195 |
| 1198 EffectGraphVisitor for_body(owner(), temp_index()); | 1196 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1199 for_body.AddInstruction( | 1197 for_body.AddInstruction( |
| 1200 new CheckStackOverflowInstr(node->token_pos())); | 1198 new CheckStackOverflowInstr(node->token_pos())); |
| 1201 node->body()->Visit(&for_body); | 1199 node->body()->Visit(&for_body); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1219 | 1217 |
| 1220 // The fragment is composed as follows: | 1218 // The fragment is composed as follows: |
| 1221 // a) body-entry-join | 1219 // a) body-entry-join |
| 1222 // b) [ body ] | 1220 // b) [ body ] |
| 1223 // c) test-entry (continue-join or body-exit-target) | 1221 // c) test-entry (continue-join or body-exit-target) |
| 1224 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1222 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1225 // e) back-target -> (body-entry-join) | 1223 // e) back-target -> (body-entry-join) |
| 1226 // f) loop-exit-target | 1224 // f) loop-exit-target |
| 1227 // g) break-join | 1225 // g) break-join |
| 1228 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1226 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1229 InlineBailout("EffectGraphVisitor::VisitDoWhileNode (control)"); | |
| 1230 // Traverse body first in order to generate continue and break labels. | 1227 // Traverse body first in order to generate continue and break labels. |
| 1231 EffectGraphVisitor for_body(owner(), temp_index()); | 1228 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1232 for_body.AddInstruction( | 1229 for_body.AddInstruction( |
| 1233 new CheckStackOverflowInstr(node->token_pos())); | 1230 new CheckStackOverflowInstr(node->token_pos())); |
| 1234 node->body()->Visit(&for_body); | 1231 node->body()->Visit(&for_body); |
| 1235 | 1232 |
| 1236 TestGraphVisitor for_test(owner(), | 1233 TestGraphVisitor for_test(owner(), |
| 1237 temp_index(), | 1234 temp_index(), |
| 1238 node->condition()->token_pos()); | 1235 node->condition()->token_pos()); |
| 1239 node->condition()->Visit(&for_test); | 1236 node->condition()->Visit(&for_test); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 // a) [ initializer ] | 1271 // a) [ initializer ] |
| 1275 // b) loop-join | 1272 // b) loop-join |
| 1276 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1273 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1277 // d) body-entry-target | 1274 // d) body-entry-target |
| 1278 // e) [ body ] | 1275 // e) [ body ] |
| 1279 // f) continue-join (optional) | 1276 // f) continue-join (optional) |
| 1280 // g) [ increment ] -> (loop-join) | 1277 // g) [ increment ] -> (loop-join) |
| 1281 // h) loop-exit-target | 1278 // h) loop-exit-target |
| 1282 // i) break-join | 1279 // i) break-join |
| 1283 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1280 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1284 InlineBailout("EffectGraphVisitor::VisitForNode (control)"); | |
| 1285 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1281 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1286 node->initializer()->Visit(&for_initializer); | 1282 node->initializer()->Visit(&for_initializer); |
| 1287 Append(for_initializer); | 1283 Append(for_initializer); |
| 1288 ASSERT(is_open()); | 1284 ASSERT(is_open()); |
| 1289 | 1285 |
| 1290 // Compose body to set any jump labels. | 1286 // Compose body to set any jump labels. |
| 1291 EffectGraphVisitor for_body(owner(), temp_index()); | 1287 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1292 for_body.AddInstruction( | 1288 for_body.AddInstruction( |
| 1293 new CheckStackOverflowInstr(node->token_pos())); | 1289 new CheckStackOverflowInstr(node->token_pos())); |
| 1294 node->body()->Visit(&for_body); | 1290 node->body()->Visit(&for_body); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 exit_ = for_test.CreateFalseSuccessor(); | 1344 exit_ = for_test.CreateFalseSuccessor(); |
| 1349 } else { | 1345 } else { |
| 1350 for_test.IfFalseGoto(node->label()->join_for_break()); | 1346 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1351 exit_ = node->label()->join_for_break(); | 1347 exit_ = node->label()->join_for_break(); |
| 1352 } | 1348 } |
| 1353 } | 1349 } |
| 1354 } | 1350 } |
| 1355 | 1351 |
| 1356 | 1352 |
| 1357 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1353 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1358 InlineBailout("EffectGraphVisitor::VisitJumpNode (control)"); | |
| 1359 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1354 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1360 EffectGraphVisitor for_effect(owner(), temp_index()); | 1355 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1361 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1356 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1362 Append(for_effect); | 1357 Append(for_effect); |
| 1363 if (!is_open()) return; | 1358 if (!is_open()) return; |
| 1364 } | 1359 } |
| 1365 | 1360 |
| 1366 // Unchain the context(s) up to the outer context level of the scope which | 1361 // Unchain the context(s) up to the outer context level of the scope which |
| 1367 // contains the destination label. | 1362 // contains the destination label. |
| 1368 SourceLabel* label = node->label(); | 1363 SourceLabel* label = node->label(); |
| (...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2623 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2629 // stack check on entry for leaf routines). | 2624 // stack check on entry for leaf routines). |
| 2630 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); | 2625 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); |
| 2631 // If we are inlining don't actually attach the stack check. We must still | 2626 // 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. | 2627 // create the stack check inorder to allocate a deopt id. |
| 2633 if (!InInliningContext()) for_effect.AddInstruction(check); | 2628 if (!InInliningContext()) for_effect.AddInstruction(check); |
| 2634 parsed_function().node_sequence()->Visit(&for_effect); | 2629 parsed_function().node_sequence()->Visit(&for_effect); |
| 2635 AppendFragment(normal_entry, for_effect); | 2630 AppendFragment(normal_entry, for_effect); |
| 2636 // Check that the graph is properly terminated. | 2631 // Check that the graph is properly terminated. |
| 2637 ASSERT(!for_effect.is_open()); | 2632 ASSERT(!for_effect.is_open()); |
| 2638 FlowGraph* graph = new FlowGraph(*this, graph_entry_); | 2633 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); |
| 2639 if (InInliningContext()) graph->set_exits(exits_); | 2634 if (InInliningContext()) graph->set_exits(exits_); |
| 2640 return graph; | 2635 return graph; |
| 2641 } | 2636 } |
| 2642 | 2637 |
| 2643 | 2638 |
| 2644 void FlowGraphBuilder::Bailout(const char* reason) { | 2639 void FlowGraphBuilder::Bailout(const char* reason) { |
| 2645 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 2640 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 2646 const char* function_name = parsed_function_.function().ToCString(); | 2641 const char* function_name = parsed_function_.function().ToCString(); |
| 2647 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2642 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2648 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2643 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2649 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2644 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2650 const Error& error = Error::Handle( | 2645 const Error& error = Error::Handle( |
| 2651 LanguageError::New(String::Handle(String::New(chars)))); | 2646 LanguageError::New(String::Handle(String::New(chars)))); |
| 2652 Isolate::Current()->long_jump_base()->Jump(1, error); | 2647 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2653 } | 2648 } |
| 2654 | 2649 |
| 2655 | 2650 |
| 2656 } // namespace dart | 2651 } // namespace dart |
| OLD | NEW |