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

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: 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
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()) {
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698