Chromium Code Reviews| 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/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 Append(for_value); | 800 Append(for_value); |
| 801 values->Add(for_value.value()); | 801 values->Add(for_value.value()); |
| 802 index = for_value.temp_index(); | 802 index = for_value.temp_index(); |
| 803 } | 803 } |
| 804 CreateArrayComp* create = new CreateArrayComp(node, values); | 804 CreateArrayComp* create = new CreateArrayComp(node, values); |
| 805 ReturnComputation(create); | 805 ReturnComputation(create); |
| 806 } | 806 } |
| 807 | 807 |
| 808 | 808 |
| 809 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 809 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 810 Bailout("EffectGraphVisitor::VisitClosureNode"); | 810 const Function& function = node->function(); |
| 811 | |
| 812 int next_index = temp_index(); | |
| 813 if (function.IsNonImplicitClosureFunction()) { | |
|
srdjan
2012/03/12 18:35:23
This condition does not match what is in the (chan
| |
| 814 const int context_level = 0; // Only because we don't handle nesting yet. | |
|
srdjan
2012/03/12 18:35:23
Dont you need to check that state()->context_level
Kevin Millikin (Google)
2012/03/13 08:59:50
Eventually, or handle non-zero. There is no conte
| |
| 815 const ContextScope& context_scope = ContextScope::ZoneHandle( | |
| 816 node->scope()->PreserveOuterScope(context_level)); | |
| 817 ASSERT(!function.HasCode()); | |
| 818 ASSERT(function.context_scope() == ContextScope::null()); | |
| 819 function.set_context_scope(context_scope); | |
| 820 } else if (function.IsImplicitInstanceClosureFunction()) { | |
| 821 ValueGraphVisitor for_receiver(owner(), temp_index()); | |
| 822 node->receiver()->Visit(&for_receiver); | |
| 823 Append(for_receiver); | |
| 824 if (!for_receiver.value()->IsTemp()) { | |
| 825 AddInstruction(new BindInstr(temp_index(), for_receiver.value())); | |
| 826 } | |
| 827 ++next_index; | |
| 828 } | |
| 829 ASSERT(function.context_scope() != ContextScope::null()); | |
| 830 | |
| 831 // The function type of a closure may have type arguments. In that case, pass | |
| 832 // the type arguments of the instantiator. | |
| 833 const Class& cls = Class::Handle(function.signature_class()); | |
| 834 ASSERT(!cls.IsNull()); | |
| 835 const bool requires_type_arguments = cls.HasTypeArguments(); | |
| 836 if (requires_type_arguments) { | |
| 837 Bailout("Closure creation requiring type arguments"); | |
| 838 } | |
| 839 | |
| 840 CreateClosureComp* create = new CreateClosureComp(node); | |
| 841 ReturnComputation(create); | |
| 811 } | 842 } |
| 812 | 843 |
| 813 | 844 |
| 814 void EffectGraphVisitor::TranslateArgumentList( | 845 void EffectGraphVisitor::TranslateArgumentList( |
| 815 const ArgumentListNode& node, | 846 const ArgumentListNode& node, |
| 816 intptr_t next_temp_index, | 847 intptr_t next_temp_index, |
| 817 ZoneGrowableArray<Value*>* values) { | 848 ZoneGrowableArray<Value*>* values) { |
| 818 for (intptr_t i = 0; i < node.length(); ++i) { | 849 for (intptr_t i = 0; i < node.length(); ++i) { |
| 819 ArgumentGraphVisitor for_argument(owner(), next_temp_index); | 850 ArgumentGraphVisitor for_argument(owner(), next_temp_index); |
| 820 node.NodeAt(i)->Visit(&for_argument); | 851 node.NodeAt(i)->Visit(&for_argument); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 StaticCallComp* call = | 883 StaticCallComp* call = |
| 853 new StaticCallComp(node->token_index(), | 884 new StaticCallComp(node->token_index(), |
| 854 node->function(), | 885 node->function(), |
| 855 node->arguments()->names(), | 886 node->arguments()->names(), |
| 856 values); | 887 values); |
| 857 ReturnComputation(call); | 888 ReturnComputation(call); |
| 858 } | 889 } |
| 859 | 890 |
| 860 | 891 |
| 861 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 892 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 862 Bailout("EffectGraphVisitor::VisitClosureCallNode"); | 893 // Context is saved around the call, it's treated as an extra operand |
| 894 // consumed by the call (but not an argument). | |
| 895 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | |
| 896 | |
| 897 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); | |
| 898 node->closure()->Visit(&for_closure); | |
| 899 Append(for_closure); | |
| 900 | |
| 901 ZoneGrowableArray<Value*>* arguments = | |
| 902 new ZoneGrowableArray<Value*>(node->arguments()->length()); | |
| 903 arguments->Add(for_closure.value()); | |
| 904 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); | |
| 905 // First operand is the saved context, consumed by the call. | |
| 906 ClosureCallComp* call = | |
| 907 new ClosureCallComp(node, new TempVal(temp_index()), arguments); | |
| 908 ReturnComputation(call); | |
| 863 } | 909 } |
| 864 | 910 |
| 865 | 911 |
| 866 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 912 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 867 Bailout("EffectGraphVisitor::VisitCloneContextNode"); | 913 Bailout("EffectGraphVisitor::VisitCloneContextNode"); |
| 868 } | 914 } |
| 869 | 915 |
| 870 | 916 |
| 871 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 917 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 872 Bailout("EffectGraphVisitor::VisitConstructorCallNode"); | 918 Bailout("EffectGraphVisitor::VisitConstructorCallNode"); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1228 } | 1274 } |
| 1229 | 1275 |
| 1230 | 1276 |
| 1231 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { | 1277 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 1232 OS::Print("AssertAssignable("); | 1278 OS::Print("AssertAssignable("); |
| 1233 comp->value()->Accept(this); | 1279 comp->value()->Accept(this); |
| 1234 OS::Print(", %s)", comp->type().ToCString()); | 1280 OS::Print(", %s)", comp->type().ToCString()); |
| 1235 } | 1281 } |
| 1236 | 1282 |
| 1237 | 1283 |
| 1284 void FlowGraphPrinter::VisitCurrentContext(CurrentContextComp* comp) { | |
| 1285 OS::Print("CurrentContext"); | |
| 1286 } | |
| 1287 | |
| 1288 | |
| 1289 void FlowGraphPrinter::VisitClosureCall(ClosureCallComp* comp) { | |
| 1290 OS::Print("ClosureCall("); | |
| 1291 comp->context()->Accept(this); | |
| 1292 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { | |
| 1293 OS::Print(", "); | |
| 1294 comp->ArgumentAt(i)->Accept(this); | |
| 1295 } | |
| 1296 OS::Print(")"); | |
| 1297 } | |
| 1298 | |
| 1299 | |
| 1238 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { | 1300 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { |
| 1239 OS::Print("InstanceCall(%s", comp->function_name().ToCString()); | 1301 OS::Print("InstanceCall(%s", comp->function_name().ToCString()); |
| 1240 for (int i = 0; i < comp->ArgumentCount(); ++i) { | 1302 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { |
| 1241 OS::Print(", "); | 1303 OS::Print(", "); |
| 1242 comp->ArgumentAt(i)->Accept(this); | 1304 comp->ArgumentAt(i)->Accept(this); |
| 1243 } | 1305 } |
| 1244 OS::Print(")"); | 1306 OS::Print(")"); |
| 1245 } | 1307 } |
| 1246 | 1308 |
| 1247 | 1309 |
| 1248 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { | 1310 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { |
| 1249 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); | 1311 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); |
| 1250 comp->left()->Accept(this); | 1312 comp->left()->Accept(this); |
| 1251 OS::Print(", "); | 1313 OS::Print(", "); |
| 1252 comp->right()->Accept(this); | 1314 comp->right()->Accept(this); |
| 1253 OS::Print(")"); | 1315 OS::Print(")"); |
| 1254 } | 1316 } |
| 1255 | 1317 |
| 1256 | 1318 |
| 1257 | 1319 |
| 1258 void FlowGraphPrinter::VisitStaticCall(StaticCallComp* comp) { | 1320 void FlowGraphPrinter::VisitStaticCall(StaticCallComp* comp) { |
| 1259 OS::Print("StaticCall(%s", | 1321 OS::Print("StaticCall(%s", |
| 1260 String::Handle(comp->function().name()).ToCString()); | 1322 String::Handle(comp->function().name()).ToCString()); |
| 1261 for (int i = 0; i < comp->ArgumentCount(); ++i) { | 1323 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { |
| 1262 OS::Print(", "); | 1324 OS::Print(", "); |
| 1263 comp->ArgumentAt(i)->Accept(this); | 1325 comp->ArgumentAt(i)->Accept(this); |
| 1264 } | 1326 } |
| 1265 OS::Print(")"); | 1327 OS::Print(")"); |
| 1266 } | 1328 } |
| 1267 | 1329 |
| 1268 | 1330 |
| 1269 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) { | 1331 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) { |
| 1270 OS::Print("LoadLocal(%s)", comp->local().name().ToCString()); | 1332 OS::Print("LoadLocal(%s)", comp->local().name().ToCString()); |
| 1271 } | 1333 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 void FlowGraphPrinter::VisitCreateArray(CreateArrayComp* comp) { | 1425 void FlowGraphPrinter::VisitCreateArray(CreateArrayComp* comp) { |
| 1364 OS::Print("CreateArray("); | 1426 OS::Print("CreateArray("); |
| 1365 for (int i = 0; i < comp->ElementCount(); ++i) { | 1427 for (int i = 0; i < comp->ElementCount(); ++i) { |
| 1366 if (i != 0) OS::Print(", "); | 1428 if (i != 0) OS::Print(", "); |
| 1367 comp->ElementAt(i)->Accept(this); | 1429 comp->ElementAt(i)->Accept(this); |
| 1368 } | 1430 } |
| 1369 OS::Print(")"); | 1431 OS::Print(")"); |
| 1370 } | 1432 } |
| 1371 | 1433 |
| 1372 | 1434 |
| 1435 void FlowGraphPrinter::VisitCreateClosure(CreateClosureComp* comp) { | |
| 1436 OS::Print("CreateClosure(%s)", comp->function().ToCString()); | |
| 1437 } | |
| 1438 | |
| 1439 | |
| 1373 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { | 1440 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { |
| 1374 OS::Print("%2d: [join]", instr->block_number()); | 1441 OS::Print("%2d: [join]", instr->block_number()); |
| 1375 } | 1442 } |
| 1376 | 1443 |
| 1377 | 1444 |
| 1378 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { | 1445 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { |
| 1379 OS::Print("%2d: [target]", instr->block_number()); | 1446 OS::Print("%2d: [target]", instr->block_number()); |
| 1380 } | 1447 } |
| 1381 | 1448 |
| 1382 | 1449 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1412 OS::Print(" if "); | 1479 OS::Print(" if "); |
| 1413 instr->value()->Accept(this); | 1480 instr->value()->Accept(this); |
| 1414 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), | 1481 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), |
| 1415 instr->false_successor()->block_number()); | 1482 instr->false_successor()->block_number()); |
| 1416 } | 1483 } |
| 1417 | 1484 |
| 1418 | 1485 |
| 1419 void FlowGraphBuilder::BuildGraph() { | 1486 void FlowGraphBuilder::BuildGraph() { |
| 1420 if (FLAG_print_ast) { | 1487 if (FLAG_print_ast) { |
| 1421 // Print the function ast before IL generation. | 1488 // Print the function ast before IL generation. |
| 1422 AstPrinter::PrintFunctionNodes(parsed_function_); | 1489 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 1490 } | |
| 1491 // Allocate variables before constructing the graph. | |
|
Kevin Millikin (Google)
2012/03/12 14:06:36
This comment is out of date, I'm deleting it.
| |
| 1492 const Function& function = parsed_function().function(); | |
| 1493 if ((function.num_optional_parameters() != 0)) { | |
| 1494 Bailout("function has optional parameters"); | |
| 1423 } | 1495 } |
|
srdjan
2012/03/12 19:56:17
Why do we bailout here and not in the FlowGraphCom
Kevin Millikin (Google)
2012/03/13 08:59:50
I moved the bailout because I initially moved the
| |
| 1424 EffectGraphVisitor for_effect(this, 0); | 1496 EffectGraphVisitor for_effect(this, 0); |
| 1425 for_effect.AddInstruction(new TargetEntryInstr()); | 1497 for_effect.AddInstruction(new TargetEntryInstr()); |
| 1426 parsed_function().node_sequence()->Visit(&for_effect); | 1498 parsed_function().node_sequence()->Visit(&for_effect); |
| 1427 // Check that the graph is properly terminated. | 1499 // Check that the graph is properly terminated. |
| 1428 ASSERT(!for_effect.is_open()); | 1500 ASSERT(!for_effect.is_open()); |
| 1429 if (for_effect.entry() != NULL) { | 1501 if (for_effect.entry() != NULL) { |
| 1430 // Accumulate basic block entries via postorder traversal. | 1502 // Accumulate basic block entries via postorder traversal. |
| 1431 for_effect.entry()->Postorder(&postorder_block_entries_); | 1503 for_effect.entry()->Postorder(&postorder_block_entries_); |
| 1432 // Number the blocks in reverse postorder starting with 0. | 1504 // Number the blocks in reverse postorder starting with 0. |
| 1433 intptr_t last_index = postorder_block_entries_.length() - 1; | 1505 intptr_t last_index = postorder_block_entries_.length() - 1; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1449 char* chars = reinterpret_cast<char*>( | 1521 char* chars = reinterpret_cast<char*>( |
| 1450 Isolate::Current()->current_zone()->Allocate(len)); | 1522 Isolate::Current()->current_zone()->Allocate(len)); |
| 1451 OS::SNPrint(chars, len, kFormat, function_name, reason); | 1523 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 1452 const Error& error = Error::Handle( | 1524 const Error& error = Error::Handle( |
| 1453 LanguageError::New(String::Handle(String::New(chars)))); | 1525 LanguageError::New(String::Handle(String::New(chars)))); |
| 1454 Isolate::Current()->long_jump_base()->Jump(1, error); | 1526 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1455 } | 1527 } |
| 1456 | 1528 |
| 1457 | 1529 |
| 1458 } // namespace dart | 1530 } // namespace dart |
| OLD | NEW |