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

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

Issue 2147123002: Made simple instance-of checks fast for unoptimized code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Removed compile_time_constants_ from object_store. Created 4 years, 5 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/code_generator.cc ('k') | runtime/vm/jit_optimizer.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 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, 1536 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos,
1537 Value* value, 1537 Value* value,
1538 const AbstractType& dst_type, 1538 const AbstractType& dst_type,
1539 const String& dst_name) { 1539 const String& dst_name) {
1540 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 1540 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
1541 return value; 1541 return value;
1542 } 1542 }
1543 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); 1543 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
1544 } 1544 }
1545 1545
1546 static bool simpleInstanceOfType(const AbstractType& type) {
1547 // Bail if the type is still uninstantiated at compile time.
1548 if (!type.IsInstantiated()) return false;
1549
1550 // Bail if the type is a function or a Dart Function type.
1551 if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
1552
1553 ASSERT(type.HasResolvedTypeClass());
1554 const Class& type_class = Class::Handle(type.type_class());
1555 // Bail if the type has any type parameters.
1556 if (type_class.IsGeneric()) return false;
1557
1558 // Finally a simple class for instance of checking.
1559 return true;
1560 }
1561
1546 1562
1547 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 1563 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
1548 ASSERT(Token::IsTypeTestOperator(node->kind())); 1564 ASSERT(Token::IsTypeTestOperator(node->kind()));
1549 const AbstractType& type = node->right()->AsTypeNode()->type(); 1565 const AbstractType& type = node->right()->AsTypeNode()->type();
1550 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1566 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1551 const bool negate_result = (node->kind() == Token::kISNOT); 1567 const bool negate_result = (node->kind() == Token::kISNOT);
1552 // All objects are instances of type T if Object type is a subtype of type T. 1568 // All objects are instances of type T if Object type is a subtype of type T.
1553 const Type& object_type = Type::Handle(Z, Type::ObjectType()); 1569 const Type& object_type = Type::Handle(Z, Type::ObjectType());
1554 if (type.IsInstantiated() && 1570 if (type.IsInstantiated() &&
1555 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { 1571 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 Library::PrivateCoreLibName(method_name), 1608 Library::PrivateCoreLibName(method_name),
1593 node->kind(), 1609 node->kind(),
1594 arguments, 1610 arguments,
1595 Object::null_array(), // No argument names. 1611 Object::null_array(), // No argument names.
1596 kNumArgsChecked, 1612 kNumArgsChecked,
1597 owner()->ic_data_array()); 1613 owner()->ic_data_array());
1598 ReturnDefinition(call); 1614 ReturnDefinition(call);
1599 return; 1615 return;
1600 } 1616 }
1601 1617
1618 // We now know type is a real class (!num, !int, !smi, !string)
1619 // and the type check could NOT be removed at compile time.
1602 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1620 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1603 PushArgumentInstr* push_type_args = NULL; 1621 if (simpleInstanceOfType(type) && (node->kind() == Token::kIS)) {
1604 if (type.IsInstantiated()) { 1622 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1605 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1623 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1624 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1625 arguments->Add(push_left);
1626 Value* type_const = Bind(new(Z) ConstantInstr(type));
1627 arguments->Add(PushArgument(type_const));
1628 const intptr_t kNumArgsChecked = 2;
1629 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1630 node->token_pos(),
1631 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()),
1632 node->kind(),
1633 arguments,
1634 Object::null_array(), // No argument names.
1635 kNumArgsChecked,
1636 owner()->ic_data_array());
1637 ReturnDefinition(call);
1606 } else { 1638 } else {
1607 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); 1639 PushArgumentInstr* push_type_args = NULL;
1640 if (type.IsInstantiated()) {
1641 push_type_args = PushArgument(BuildNullValue(node->token_pos()));
1642 } else {
1643 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1644 }
1645 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1646 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1647 arguments->Add(push_left);
1648 arguments->Add(push_type_args);
1649 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1650 Value* type_const = Bind(new(Z) ConstantInstr(type));
1651 arguments->Add(PushArgument(type_const));
1652 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1653 Value* negate_arg = Bind(new(Z) ConstantInstr(negate));
1654 arguments->Add(PushArgument(negate_arg));
1655 const intptr_t kNumArgsChecked = 1;
1656 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1657 node->token_pos(),
1658 Library::PrivateCoreLibName(Symbols::_instanceOf()),
1659 node->kind(),
1660 arguments,
1661 Object::null_array(), // No argument names.
1662 kNumArgsChecked,
1663 owner()->ic_data_array());
1664 ReturnDefinition(call);
1608 } 1665 }
1609 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1610 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1611 arguments->Add(push_left);
1612 arguments->Add(push_type_args);
1613 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1614 Value* type_const = Bind(new(Z) ConstantInstr(type));
1615 arguments->Add(PushArgument(type_const));
1616 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1617 Value* negate_arg = Bind(new(Z) ConstantInstr(negate));
1618 arguments->Add(PushArgument(negate_arg));
1619 const intptr_t kNumArgsChecked = 1;
1620 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1621 node->token_pos(),
1622 Library::PrivateCoreLibName(Symbols::_instanceOf()),
1623 node->kind(),
1624 arguments,
1625 Object::null_array(), // No argument names.
1626 kNumArgsChecked,
1627 owner()->ic_data_array());
1628 ReturnDefinition(call);
1629 } 1666 }
1630 1667
1631 1668
1632 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1669 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1633 ASSERT(Token::IsTypeCastOperator(node->kind())); 1670 ASSERT(Token::IsTypeCastOperator(node->kind()));
1634 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1671 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1635 const AbstractType& type = node->right()->AsTypeNode()->type(); 1672 const AbstractType& type = node->right()->AsTypeNode()->type();
1636 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1673 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1637 ValueGraphVisitor for_value(owner()); 1674 ValueGraphVisitor for_value(owner());
1638 node->left()->Visit(&for_value); 1675 node->left()->Visit(&for_value);
(...skipping 2942 matching lines...) Expand 10 before | Expand all | Expand 10 after
4581 block_marks); 4618 block_marks);
4582 ASSERT(found); 4619 ASSERT(found);
4583 } 4620 }
4584 4621
4585 4622
4586 void FlowGraphBuilder::Bailout(const char* reason) const { 4623 void FlowGraphBuilder::Bailout(const char* reason) const {
4587 parsed_function_.Bailout("FlowGraphBuilder", reason); 4624 parsed_function_.Bailout("FlowGraphBuilder", reason);
4588 } 4625 }
4589 4626
4590 } // namespace dart 4627 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/jit_optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698