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

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

Issue 9664062: Support allocating and calling closures in the new non-optimizing compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 8 years, 9 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_compiler_x64.h » ('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/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
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()) {
814 const int context_level = 0; // Only because we don't handle nesting yet.
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
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 if (node->constructor().IsFactory()) { 918 if (node->constructor().IsFactory()) {
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 } 1289 }
1244 1290
1245 1291
1246 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { 1292 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) {
1247 OS::Print("AssertAssignable("); 1293 OS::Print("AssertAssignable(");
1248 comp->value()->Accept(this); 1294 comp->value()->Accept(this);
1249 OS::Print(", %s)", comp->type().ToCString()); 1295 OS::Print(", %s)", comp->type().ToCString());
1250 } 1296 }
1251 1297
1252 1298
1299 void FlowGraphPrinter::VisitCurrentContext(CurrentContextComp* comp) {
1300 OS::Print("CurrentContext");
1301 }
1302
1303
1304 void FlowGraphPrinter::VisitClosureCall(ClosureCallComp* comp) {
1305 OS::Print("ClosureCall(");
1306 comp->context()->Accept(this);
1307 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) {
1308 OS::Print(", ");
1309 comp->ArgumentAt(i)->Accept(this);
1310 }
1311 OS::Print(")");
1312 }
1313
1314
1253 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) { 1315 void FlowGraphPrinter::VisitInstanceCall(InstanceCallComp* comp) {
1254 OS::Print("InstanceCall(%s", comp->function_name().ToCString()); 1316 OS::Print("InstanceCall(%s", comp->function_name().ToCString());
1255 for (int i = 0; i < comp->ArgumentCount(); ++i) { 1317 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) {
1256 OS::Print(", "); 1318 OS::Print(", ");
1257 comp->ArgumentAt(i)->Accept(this); 1319 comp->ArgumentAt(i)->Accept(this);
1258 } 1320 }
1259 OS::Print(")"); 1321 OS::Print(")");
1260 } 1322 }
1261 1323
1262 1324
1263 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) { 1325 void FlowGraphPrinter::VisitStrictCompare(StrictCompareComp* comp) {
1264 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind())); 1326 OS::Print("StrictCompare(%s, ", Token::Str(comp->kind()));
1265 comp->left()->Accept(this); 1327 comp->left()->Accept(this);
1266 OS::Print(", "); 1328 OS::Print(", ");
1267 comp->right()->Accept(this); 1329 comp->right()->Accept(this);
1268 OS::Print(")"); 1330 OS::Print(")");
1269 } 1331 }
1270 1332
1271 1333
1272 1334
1273 void FlowGraphPrinter::VisitStaticCall(StaticCallComp* comp) { 1335 void FlowGraphPrinter::VisitStaticCall(StaticCallComp* comp) {
1274 OS::Print("StaticCall(%s", 1336 OS::Print("StaticCall(%s",
1275 String::Handle(comp->function().name()).ToCString()); 1337 String::Handle(comp->function().name()).ToCString());
1276 for (int i = 0; i < comp->ArgumentCount(); ++i) { 1338 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) {
1277 OS::Print(", "); 1339 OS::Print(", ");
1278 comp->ArgumentAt(i)->Accept(this); 1340 comp->ArgumentAt(i)->Accept(this);
1279 } 1341 }
1280 OS::Print(")"); 1342 OS::Print(")");
1281 } 1343 }
1282 1344
1283 1345
1284 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) { 1346 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) {
1285 OS::Print("LoadLocal(%s)", comp->local().name().ToCString()); 1347 OS::Print("LoadLocal(%s)", comp->local().name().ToCString());
1286 } 1348 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 void FlowGraphPrinter::VisitCreateArray(CreateArrayComp* comp) { 1440 void FlowGraphPrinter::VisitCreateArray(CreateArrayComp* comp) {
1379 OS::Print("CreateArray("); 1441 OS::Print("CreateArray(");
1380 for (int i = 0; i < comp->ElementCount(); ++i) { 1442 for (int i = 0; i < comp->ElementCount(); ++i) {
1381 if (i != 0) OS::Print(", "); 1443 if (i != 0) OS::Print(", ");
1382 comp->ElementAt(i)->Accept(this); 1444 comp->ElementAt(i)->Accept(this);
1383 } 1445 }
1384 OS::Print(")"); 1446 OS::Print(")");
1385 } 1447 }
1386 1448
1387 1449
1450 void FlowGraphPrinter::VisitCreateClosure(CreateClosureComp* comp) {
1451 OS::Print("CreateClosure(%s)", comp->function().ToCString());
1452 }
1453
1454
1388 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { 1455 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) {
1389 OS::Print("%2d: [join]", instr->block_number()); 1456 OS::Print("%2d: [join]", instr->block_number());
1390 } 1457 }
1391 1458
1392 1459
1393 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { 1460 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) {
1394 OS::Print("%2d: [target]", instr->block_number()); 1461 OS::Print("%2d: [target]", instr->block_number());
1395 } 1462 }
1396 1463
1397 1464
(...skipping 29 matching lines...) Expand all
1427 OS::Print(" if "); 1494 OS::Print(" if ");
1428 instr->value()->Accept(this); 1495 instr->value()->Accept(this);
1429 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), 1496 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(),
1430 instr->false_successor()->block_number()); 1497 instr->false_successor()->block_number());
1431 } 1498 }
1432 1499
1433 1500
1434 void FlowGraphBuilder::BuildGraph() { 1501 void FlowGraphBuilder::BuildGraph() {
1435 if (FLAG_print_ast) { 1502 if (FLAG_print_ast) {
1436 // Print the function ast before IL generation. 1503 // Print the function ast before IL generation.
1437 AstPrinter::PrintFunctionNodes(parsed_function_); 1504 AstPrinter::PrintFunctionNodes(parsed_function());
1505 }
1506 const Function& function = parsed_function().function();
1507 if ((function.num_optional_parameters() != 0)) {
1508 Bailout("function has optional parameters");
1438 } 1509 }
1439 EffectGraphVisitor for_effect(this, 0); 1510 EffectGraphVisitor for_effect(this, 0);
1440 for_effect.AddInstruction(new TargetEntryInstr()); 1511 for_effect.AddInstruction(new TargetEntryInstr());
1441 parsed_function().node_sequence()->Visit(&for_effect); 1512 parsed_function().node_sequence()->Visit(&for_effect);
1442 // Check that the graph is properly terminated. 1513 // Check that the graph is properly terminated.
1443 ASSERT(!for_effect.is_open()); 1514 ASSERT(!for_effect.is_open());
1444 if (for_effect.entry() != NULL) { 1515 if (for_effect.entry() != NULL) {
1445 // Accumulate basic block entries via postorder traversal. 1516 // Accumulate basic block entries via postorder traversal.
1446 for_effect.entry()->Postorder(&postorder_block_entries_); 1517 for_effect.entry()->Postorder(&postorder_block_entries_);
1447 // Number the blocks in reverse postorder starting with 0. 1518 // Number the blocks in reverse postorder starting with 0.
1448 intptr_t last_index = postorder_block_entries_.length() - 1; 1519 intptr_t last_index = postorder_block_entries_.length() - 1;
1449 for (intptr_t i = last_index; i >= 0; --i) { 1520 for (intptr_t i = last_index; i >= 0; --i) {
1450 postorder_block_entries_[i]->set_block_number(last_index - i); 1521 postorder_block_entries_[i]->set_block_number(last_index - i);
1451 } 1522 }
1452 } 1523 }
1453 if (FLAG_print_flow_graph) { 1524 if (FLAG_print_flow_graph) {
1454 FlowGraphPrinter printer(parsed_function().function()); 1525 FlowGraphPrinter printer(function);
1455 printer.VisitBlocks(postorder_block_entries_); 1526 printer.VisitBlocks(postorder_block_entries_);
1456 } 1527 }
1457 } 1528 }
1458 1529
1459 1530
1460 void FlowGraphBuilder::Bailout(const char* reason) { 1531 void FlowGraphBuilder::Bailout(const char* reason) {
1461 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 1532 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
1462 const char* function_name = parsed_function_.function().ToCString(); 1533 const char* function_name = parsed_function_.function().ToCString();
1463 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 1534 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
1464 char* chars = reinterpret_cast<char*>( 1535 char* chars = reinterpret_cast<char*>(
1465 Isolate::Current()->current_zone()->Allocate(len)); 1536 Isolate::Current()->current_zone()->Allocate(len));
1466 OS::SNPrint(chars, len, kFormat, function_name, reason); 1537 OS::SNPrint(chars, len, kFormat, function_name, reason);
1467 const Error& error = Error::Handle( 1538 const Error& error = Error::Handle(
1468 LanguageError::New(String::Handle(String::New(chars)))); 1539 LanguageError::New(String::Handle(String::New(chars))));
1469 Isolate::Current()->long_jump_base()->Jump(1, error); 1540 Isolate::Current()->long_jump_base()->Jump(1, error);
1470 } 1541 }
1471 1542
1472 1543
1473 } // namespace dart 1544 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698