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

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

Issue 2761933002: Add Genericity enum in VM to distinguish how a type is uninstantiated. (Closed)
Patch Set: sync Created 3 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 return; 1211 return;
1212 } 1212 }
1213 1213
1214 1214
1215 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1215 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1216 const AbstractType& type = node->type(); 1216 const AbstractType& type = node->type();
1217 // Type may be malbounded, but not malformed. 1217 // Type may be malbounded, but not malformed.
1218 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1218 ASSERT(type.IsFinalized() && !type.IsMalformed());
1219 if (type.IsInstantiated()) { 1219 if (type.IsInstantiated()) {
1220 ReturnDefinition(new (Z) ConstantInstr(type)); 1220 ReturnDefinition(new (Z) ConstantInstr(type));
1221 return;
1222 }
1223 const TokenPosition token_pos = node->token_pos();
1224 Value* instantiator_type_arguments = NULL;
1225 if (type.IsInstantiated(kClass)) {
1226 instantiator_type_arguments = BuildNullValue(token_pos);
1221 } else { 1227 } else {
1222 const Class& instantiator_class = 1228 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos);
1223 Class::ZoneHandle(Z, owner()->function().Owner());
1224 Value* instantiator_value = BuildInstantiatorTypeArguments(
1225 node->token_pos(), instantiator_class, NULL);
1226 ReturnDefinition(new (Z) InstantiateTypeInstr(
1227 node->token_pos(), type, instantiator_class, instantiator_value));
1228 } 1229 }
1230 Value* function_type_arguments = NULL;
1231 if (type.IsInstantiated(kCurrentFunction)) {
1232 // TODO(regis): function_type_arguments = BuildNullValue((token_pos);
1233 } else {
1234 function_type_arguments = BuildFunctionTypeArguments(token_pos);
1235 }
1236 ReturnDefinition(new (Z) InstantiateTypeInstr(
1237 token_pos, type, instantiator_type_arguments, function_type_arguments));
1229 } 1238 }
1230 1239
1231 1240
1232 // Returns true if the type check can be skipped, for example, if the 1241 // Returns true if the type check can be skipped, for example, if the
1233 // destination type is dynamic or if the compile type of the value is a subtype 1242 // destination type is dynamic or if the compile type of the value is a subtype
1234 // of the destination type. 1243 // of the destination type.
1235 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, 1244 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos,
1236 Value* value, 1245 Value* value,
1237 const AbstractType& dst_type, 1246 const AbstractType& dst_type,
1238 const String& dst_name) { 1247 const String& dst_name) {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 Join(for_test, for_true, for_right); 1406 Join(for_test, for_true, for_right);
1398 } 1407 }
1399 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 1408 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
1400 return; 1409 return;
1401 } 1410 }
1402 1411
1403 EffectGraphVisitor::VisitBinaryOpNode(node); 1412 EffectGraphVisitor::VisitBinaryOpNode(node);
1404 } 1413 }
1405 1414
1406 1415
1407 void EffectGraphVisitor::BuildTypecheckPushArguments( 1416 PushArgumentInstr* EffectGraphVisitor::PushInstantiatorTypeArguments(
1408 TokenPosition token_pos, 1417 const AbstractType& type,
1409 PushArgumentInstr** push_instantiator_type_arguments_result) { 1418 TokenPosition token_pos) {
1410 const Class& instantiator_class = 1419 if (type.IsInstantiated(kClass)) {
1411 Class::Handle(Z, owner()->function().Owner()); 1420 return PushArgument(BuildNullValue(token_pos));
1412 // Since called only when type tested against is not instantiated.
1413 ASSERT(instantiator_class.IsGeneric());
1414 Value* instantiator_type_arguments = NULL;
1415 Value* instantiator = BuildInstantiator(token_pos);
1416 if (instantiator == NULL) {
1417 // No instantiator when inside factory.
1418 instantiator_type_arguments =
1419 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1420 } else { 1421 } else {
1421 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1422 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos);
1422 token_pos, instantiator_class, instantiator); 1423 return PushArgument(instantiator_type_args);
1423 } 1424 }
1424 *push_instantiator_type_arguments_result =
1425 PushArgument(instantiator_type_arguments);
1426 } 1425 }
1427 1426
1428 1427
1429 void EffectGraphVisitor::BuildTypecheckArguments( 1428 PushArgumentInstr* EffectGraphVisitor::PushFunctionTypeArguments(
1430 TokenPosition token_pos, 1429 const AbstractType& type,
1431 Value** instantiator_type_arguments_result) { 1430 TokenPosition token_pos) {
1432 Value* instantiator = NULL; 1431 if (type.IsInstantiated(kCurrentFunction)) {
1433 Value* instantiator_type_arguments = NULL; 1432 return PushArgument(BuildNullValue(token_pos));
1434 const Class& instantiator_class =
1435 Class::Handle(Z, owner()->function().Owner());
1436 // Since called only when type tested against is not instantiated.
1437 ASSERT(instantiator_class.IsGeneric());
1438 instantiator = BuildInstantiator(token_pos);
1439 if (instantiator == NULL) {
1440 // No instantiator when inside factory.
1441 instantiator_type_arguments =
1442 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1443 } else { 1433 } else {
1444 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1434 Value* function_type_args = BuildFunctionTypeArguments(token_pos);
1445 token_pos, instantiator_class, instantiator); 1435 return PushArgument(function_type_args);
1446 } 1436 }
1447 *instantiator_type_arguments_result = instantiator_type_arguments;
1448 } 1437 }
1449 1438
1450 1439
1451 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) { 1440 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) {
1452 return Bind( 1441 return Bind(
1453 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos)); 1442 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos));
1454 } 1443 }
1455 1444
1456 1445
1457 // Used for testing incoming arguments. 1446 // Used for testing incoming arguments.
1458 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( 1447 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
1459 TokenPosition token_pos, 1448 TokenPosition token_pos,
1460 Value* value, 1449 Value* value,
1461 const AbstractType& dst_type, 1450 const AbstractType& dst_type,
1462 const String& dst_name) { 1451 const String& dst_name) {
1463 // Build the type check computation. 1452 // Build the type check computation.
1464 Value* instantiator_type_arguments = NULL; 1453 Value* instantiator_type_arguments = NULL;
1465 if (dst_type.IsInstantiated()) { 1454 Value* function_type_arguments = NULL;
1455 if (dst_type.IsInstantiated(kClass)) {
1466 instantiator_type_arguments = BuildNullValue(token_pos); 1456 instantiator_type_arguments = BuildNullValue(token_pos);
1467 } else { 1457 } else {
1468 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); 1458 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos);
1459 }
1460 if (dst_type.IsInstantiated(kCurrentFunction)) {
1461 // TODO(regis): function_type_arguments = BuildNullValue(token_pos);
1462 } else {
1463 function_type_arguments = BuildFunctionTypeArguments(token_pos);
1469 } 1464 }
1470 1465
1471 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); 1466 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId();
1472 return new (Z) 1467 return new (Z) AssertAssignableInstr(
1473 AssertAssignableInstr(token_pos, value, instantiator_type_arguments, 1468 token_pos, value, instantiator_type_arguments, function_type_arguments,
1474 dst_type, dst_name, deopt_id); 1469 dst_type, dst_name, deopt_id);
1475 } 1470 }
1476 1471
1477 1472
1478 // Used for type casts and to test assignments. 1473 // Used for type casts and to test assignments.
1479 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, 1474 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos,
1480 Value* value, 1475 Value* value,
1481 const AbstractType& dst_type, 1476 const AbstractType& dst_type,
1482 const String& dst_name) { 1477 const String& dst_name) {
1483 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 1478 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
1484 return value; 1479 return value;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 return; 1516 return;
1522 } 1517 }
1523 ValueGraphVisitor for_left_value(owner()); 1518 ValueGraphVisitor for_left_value(owner());
1524 node->left()->Visit(&for_left_value); 1519 node->left()->Visit(&for_left_value);
1525 Append(for_left_value); 1520 Append(for_left_value);
1526 1521
1527 // We now know type is a real class (!num, !int, !smi, !string) 1522 // We now know type is a real class (!num, !int, !smi, !string)
1528 // and the type check could NOT be removed at compile time. 1523 // and the type check could NOT be removed at compile time.
1529 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1524 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1530 if (simpleInstanceOfType(type)) { 1525 if (simpleInstanceOfType(type)) {
1531 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1532 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1526 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1533 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1527 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1534 arguments->Add(push_left); 1528 arguments->Add(push_left);
1535 Value* type_const = Bind(new (Z) ConstantInstr(type)); 1529 Value* type_const = Bind(new (Z) ConstantInstr(type));
1536 arguments->Add(PushArgument(type_const)); 1530 arguments->Add(PushArgument(type_const));
1537 const intptr_t kNumArgsChecked = 2; 1531 const intptr_t kNumArgsChecked = 2;
1538 Definition* result = new (Z) InstanceCallInstr( 1532 Definition* result = new (Z) InstanceCallInstr(
1539 node->token_pos(), 1533 node->token_pos(),
1540 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(), 1534 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(),
1541 arguments, 1535 arguments,
1542 Object::null_array(), // No argument names. 1536 Object::null_array(), // No argument names.
1543 kNumArgsChecked, owner()->ic_data_array()); 1537 kNumArgsChecked, owner()->ic_data_array());
1544 if (negate_result) { 1538 if (negate_result) {
1545 result = new (Z) BooleanNegateInstr(Bind(result)); 1539 result = new (Z) BooleanNegateInstr(Bind(result));
1546 } 1540 }
1547 ReturnDefinition(result); 1541 ReturnDefinition(result);
1548 return; 1542 return;
1549 } 1543 }
1550 1544
1551 PushArgumentInstr* push_type_args = NULL; 1545 PushArgumentInstr* push_instantiator_type_args =
1552 if (type.IsInstantiated()) { 1546 PushInstantiatorTypeArguments(type, node->token_pos());
1553 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1547 // TODO(regis): PushArgumentInstr* push_function_type_args =
1554 } else { 1548 // PushFunctionTypeArguments(type, node->token_pos());
1555 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1556 }
1557 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1549 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1558 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); 1550 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
1559 arguments->Add(push_left); 1551 arguments->Add(push_left);
1560 arguments->Add(push_type_args); 1552 arguments->Add(push_instantiator_type_args);
1561 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1553 // TODO(regis): arguments->Add(push_function_type_args);
1562 Value* type_const = Bind(new (Z) ConstantInstr(type)); 1554 Value* type_const = Bind(new (Z) ConstantInstr(type));
1563 arguments->Add(PushArgument(type_const)); 1555 arguments->Add(PushArgument(type_const));
1564 const intptr_t kNumArgsChecked = 1; 1556 const intptr_t kNumArgsChecked = 1;
1565 Definition* result = new (Z) InstanceCallInstr( 1557 Definition* result = new (Z) InstanceCallInstr(
1566 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()), 1558 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()),
1567 node->kind(), arguments, 1559 node->kind(), arguments,
1568 Object::null_array(), // No argument names. 1560 Object::null_array(), // No argument names.
1569 kNumArgsChecked, owner()->ic_data_array()); 1561 kNumArgsChecked, owner()->ic_data_array());
1570 if (negate_result) { 1562 if (negate_result) {
1571 result = new (Z) BooleanNegateInstr(Bind(result)); 1563 result = new (Z) BooleanNegateInstr(Bind(result));
1572 } 1564 }
1573 ReturnDefinition(result); 1565 ReturnDefinition(result);
1574 } 1566 }
1575 1567
1576 1568
1577 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1569 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1578 ASSERT(Token::IsTypeCastOperator(node->kind())); 1570 ASSERT(Token::IsTypeCastOperator(node->kind()));
1579 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1571 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1580 const AbstractType& type = node->right()->AsTypeNode()->type(); 1572 const AbstractType& type = node->right()->AsTypeNode()->type();
1581 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1573 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1582 ValueGraphVisitor for_value(owner()); 1574 ValueGraphVisitor for_value(owner());
1583 node->left()->Visit(&for_value); 1575 node->left()->Visit(&for_value);
1584 Append(for_value); 1576 Append(for_value);
1585 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, 1577 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type,
1586 Symbols::InTypeCast())) { 1578 Symbols::InTypeCast())) {
1587 ReturnValue(for_value.value()); 1579 ReturnValue(for_value.value());
1588 return; 1580 return;
1589 } 1581 }
1590 PushArgumentInstr* push_left = PushArgument(for_value.value()); 1582 PushArgumentInstr* push_left = PushArgument(for_value.value());
1591 PushArgumentInstr* push_type_args = NULL; 1583 PushArgumentInstr* push_instantiator_type_args =
1592 if (type.IsInstantiated()) { 1584 PushInstantiatorTypeArguments(type, node->token_pos());
1593 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1585 // TODO(regis): PushArgumentInstr* push_function_type_args =
1594 } else { 1586 // PushFunctionTypeArguments(type, node->token_pos());
1595 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1596 }
1597 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1587 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1598 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); 1588 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
1599 arguments->Add(push_left); 1589 arguments->Add(push_left);
1600 arguments->Add(push_type_args); 1590 arguments->Add(push_instantiator_type_args);
1591 // TODO(regis): arguments->Add(push_function_type_args);
1601 Value* type_arg = Bind(new (Z) ConstantInstr(type)); 1592 Value* type_arg = Bind(new (Z) ConstantInstr(type));
1602 arguments->Add(PushArgument(type_arg)); 1593 arguments->Add(PushArgument(type_arg));
1603 const intptr_t kNumArgsChecked = 1; 1594 const intptr_t kNumArgsChecked = 1;
1604 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1595 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1605 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()), 1596 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()),
1606 node->kind(), arguments, 1597 node->kind(), arguments,
1607 Object::null_array(), // No argument names. 1598 Object::null_array(), // No argument names.
1608 kNumArgsChecked, owner()->ic_data_array()); 1599 kNumArgsChecked, owner()->ic_data_array());
1609 ReturnDefinition(call); 1600 ReturnDefinition(call);
1610 } 1601 }
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 Value* closure_val = Bind(alloc); 2356 Value* closure_val = Bind(alloc);
2366 { 2357 {
2367 LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); 2358 LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
2368 // Store instantiator type arguments if scope class is generic. 2359 // Store instantiator type arguments if scope class is generic.
2369 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); 2360 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType());
2370 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); 2361 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class());
2371 if (scope_cls.IsGeneric()) { 2362 if (scope_cls.IsGeneric()) {
2372 ASSERT(function.Owner() == scope_cls.raw()); 2363 ASSERT(function.Owner() == scope_cls.raw());
2373 Value* closure_tmp_val = 2364 Value* closure_tmp_val =
2374 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2365 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2375 const Class& instantiator_class = 2366 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos());
2376 Class::Handle(Z, owner()->function().Owner());
2377 Value* type_arguments = BuildInstantiatorTypeArguments(
2378 node->token_pos(), instantiator_class, NULL);
2379 Do(new (Z) StoreInstanceFieldInstr(Closure::instantiator_offset(), 2367 Do(new (Z) StoreInstanceFieldInstr(Closure::instantiator_offset(),
2380 closure_tmp_val, type_arguments, 2368 closure_tmp_val, type_arguments,
2381 kEmitStoreBarrier, node->token_pos())); 2369 kEmitStoreBarrier, node->token_pos()));
2382 } 2370 }
2383 2371
2384 // Store function. 2372 // Store function.
2385 Value* closure_tmp_val = 2373 Value* closure_tmp_val =
2386 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2374 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2387 Value* func_val = 2375 Value* func_val =
2388 Bind(new (Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); 2376 Bind(new (Z) ConstantInstr(Function::ZoneHandle(Z, function.raw())));
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 return NULL; 2679 return NULL;
2692 } 2680 }
2693 2681
2694 LocalVariable* instantiator = owner()->parsed_function().instantiator(); 2682 LocalVariable* instantiator = owner()->parsed_function().instantiator();
2695 ASSERT(instantiator != NULL); 2683 ASSERT(instantiator != NULL);
2696 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); 2684 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos));
2697 return result; 2685 return result;
2698 } 2686 }
2699 2687
2700 2688
2701 // 'expression_temp_var' may not be used inside this method if 'instantiator'
2702 // is not NULL.
2703 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2689 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2704 TokenPosition token_pos, 2690 TokenPosition token_pos) {
2705 const Class& instantiator_class, 2691 const Class& instantiator_class =
2706 Value* instantiator) { 2692 Class::Handle(Z, owner()->function().Owner());
2707 if (!instantiator_class.IsGeneric()) { 2693 if (!instantiator_class.IsGeneric()) {
2708 // The type arguments are compile time constants. 2694 // The type arguments are compile time constants.
2709 TypeArguments& type_arguments = 2695 TypeArguments& type_arguments =
2710 TypeArguments::ZoneHandle(Z, TypeArguments::null()); 2696 TypeArguments::ZoneHandle(Z, TypeArguments::null());
2711 // Type is temporary. Only its type arguments are preserved. 2697 // Type is temporary. Only its type arguments are preserved.
2712 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments, 2698 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments,
2713 token_pos, Heap::kNew)); 2699 token_pos, Heap::kNew));
2714 type ^= ClassFinalizer::FinalizeType(instantiator_class, type, 2700 type ^= ClassFinalizer::FinalizeType(instantiator_class, type,
2715 ClassFinalizer::kFinalize); 2701 ClassFinalizer::kFinalize);
2716 ASSERT(!type.IsMalformedOrMalbounded()); 2702 ASSERT(!type.IsMalformedOrMalbounded());
2717 type_arguments = type.arguments(); 2703 type_arguments = type.arguments();
2718 type_arguments = type_arguments.Canonicalize(); 2704 type_arguments = type_arguments.Canonicalize();
2719 return Bind(new (Z) ConstantInstr(type_arguments)); 2705 return Bind(new (Z) ConstantInstr(type_arguments));
2720 } 2706 }
2721 Function& outer_function = Function::Handle(Z, owner()->function().raw()); 2707 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2722 while (outer_function.IsLocalFunction()) { 2708 while (outer_function.IsLocalFunction()) {
2723 outer_function = outer_function.parent_function(); 2709 outer_function = outer_function.parent_function();
2724 } 2710 }
2725 if (outer_function.IsFactory()) { 2711 if (outer_function.IsFactory()) {
2726 // No instantiator for factories. 2712 // Note that in the factory case, the instantiator is the first parameter
2727 ASSERT(instantiator == NULL); 2713 // of the factory, i.e. already a TypeArguments object.
2728 LocalVariable* instantiator_var = owner()->parsed_function().instantiator(); 2714 LocalVariable* instantiator_var = owner()->parsed_function().instantiator();
2729 ASSERT(instantiator_var != NULL); 2715 ASSERT(instantiator_var != NULL);
2730 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); 2716 return Bind(BuildLoadLocal(*instantiator_var, token_pos));
2731 } 2717 }
2732 if (instantiator == NULL) {
2733 instantiator = BuildInstantiator(token_pos);
2734 }
2735 // The instantiator is the receiver of the caller, which is not a factory. 2718 // The instantiator is the receiver of the caller, which is not a factory.
2736 // The receiver cannot be null; extract its TypeArguments object. 2719 // The receiver cannot be null; extract its TypeArguments object.
2737 // Note that in the factory case, the instantiator is the first parameter 2720 Value* instantiator = BuildInstantiator(token_pos);
2738 // of the factory, i.e. already a TypeArguments object.
2739 intptr_t type_arguments_field_offset = 2721 intptr_t type_arguments_field_offset =
2740 instantiator_class.type_arguments_field_offset(); 2722 instantiator_class.type_arguments_field_offset();
2741 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2723 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2742 2724
2743 return Bind(new (Z) LoadFieldInstr( 2725 return Bind(new (Z) LoadFieldInstr(
2744 instantiator, type_arguments_field_offset, 2726 instantiator, type_arguments_field_offset,
2745 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. 2727 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type.
2746 token_pos)); 2728 token_pos));
2747 } 2729 }
2748 2730
2749 2731
2732 Value* EffectGraphVisitor::BuildFunctionTypeArguments(TokenPosition token_pos) {
2733 UNIMPLEMENTED();
2734 return NULL;
2735 }
2736
2737
2750 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2738 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2751 TokenPosition token_pos, 2739 TokenPosition token_pos,
2752 const TypeArguments& type_arguments) { 2740 const TypeArguments& type_arguments) {
2753 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2741 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2754 return Bind(new (Z) ConstantInstr(type_arguments)); 2742 return Bind(new (Z) ConstantInstr(type_arguments));
2755 } 2743 }
2756 // The type arguments are uninstantiated. 2744 // The type arguments are uninstantiated.
2757 const Class& instantiator_class = 2745 const Class& instantiator_class =
2758 Class::ZoneHandle(Z, owner()->function().Owner()); 2746 Class::ZoneHandle(Z, owner()->function().Owner());
2759 Value* instantiator_value = 2747 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos);
2760 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2761 const bool use_instantiator_type_args = 2748 const bool use_instantiator_type_args =
2762 type_arguments.IsUninstantiatedIdentity() || 2749 type_arguments.IsUninstantiatedIdentity() ||
2763 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); 2750 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
2764 if (use_instantiator_type_args) { 2751 if (use_instantiator_type_args) {
2765 return instantiator_value; 2752 return instantiator_type_args;
2753 }
2754 Value* function_type_args = NULL;
2755 if (type_arguments.IsInstantiated(kCurrentFunction)) {
2756 // TODO(regis): function_type_args = BuildNullValue(token_pos);
2766 } else { 2757 } else {
2767 return Bind(new (Z) InstantiateTypeArgumentsInstr( 2758 function_type_args = BuildFunctionTypeArguments(token_pos);
2768 token_pos, type_arguments, instantiator_class, instantiator_value));
2769 } 2759 }
2760 return Bind(new (Z) InstantiateTypeArgumentsInstr(
2761 token_pos, type_arguments, instantiator_class, instantiator_type_args,
2762 function_type_args));
2770 } 2763 }
2771 2764
2772 2765
2773 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2766 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2774 if (node->constructor().IsFactory()) { 2767 if (node->constructor().IsFactory()) {
2775 EffectGraphVisitor::VisitConstructorCallNode(node); 2768 EffectGraphVisitor::VisitConstructorCallNode(node);
2776 return; 2769 return;
2777 } 2770 }
2778 2771
2779 // t_n contains the allocated and initialized object. 2772 // t_n contains the allocated and initialized object.
(...skipping 1577 matching lines...) Expand 10 before | Expand all | Expand 10 after
4357 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks); 4350 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks);
4358 ASSERT(found); 4351 ASSERT(found);
4359 } 4352 }
4360 4353
4361 4354
4362 void FlowGraphBuilder::Bailout(const char* reason) const { 4355 void FlowGraphBuilder::Bailout(const char* reason) const {
4363 parsed_function_.Bailout("FlowGraphBuilder", reason); 4356 parsed_function_.Bailout("FlowGraphBuilder", reason);
4364 } 4357 }
4365 4358
4366 } // namespace dart 4359 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698