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

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

Issue 2137673002: Sped up hashCode by removing megamorphic call to _identityHashCode. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Improved the speed of instance-of for unoptimized code. 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 unknown at compile time.
1548 if (!type.IsInstantiated()) return false;
1549
1550 // Bail if the type is a function.
1551 if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
1552
1553 const Class& type_class = Class::Handle(type.type_class());
1554 // Bail if the type is any type parameters.
1555 if (type_class.IsGeneric()) return false;
1556
1557 // Finally a simple class for instance of checking.
1558 return true;
1559 }
1560
1546 1561
1547 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 1562 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
1548 ASSERT(Token::IsTypeTestOperator(node->kind())); 1563 ASSERT(Token::IsTypeTestOperator(node->kind()));
1549 const AbstractType& type = node->right()->AsTypeNode()->type(); 1564 const AbstractType& type = node->right()->AsTypeNode()->type();
1550 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1565 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1551 const bool negate_result = (node->kind() == Token::kISNOT); 1566 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. 1567 // 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()); 1568 const Type& object_type = Type::Handle(Z, Type::ObjectType());
1554 if (type.IsInstantiated() && 1569 if (type.IsInstantiated() &&
1555 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { 1570 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), 1607 Library::PrivateCoreLibName(method_name),
1593 node->kind(), 1608 node->kind(),
1594 arguments, 1609 arguments,
1595 Object::null_array(), // No argument names. 1610 Object::null_array(), // No argument names.
1596 kNumArgsChecked, 1611 kNumArgsChecked,
1597 owner()->ic_data_array()); 1612 owner()->ic_data_array());
1598 ReturnDefinition(call); 1613 ReturnDefinition(call);
1599 return; 1614 return;
1600 } 1615 }
1601 1616
1617 // We now know type is a real class (!num, !int, !smi, !string)
1618 // and the type check could NOT be removed at compile time.
1602 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1619 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1603 PushArgumentInstr* push_type_args = NULL; 1620 if (simpleInstanceOfType(type) && (node->kind() == Token::kIS)) {
1604 if (type.IsInstantiated()) { 1621 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1605 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1622 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1623 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1624 arguments->Add(push_left);
1625 Value* type_const = Bind(new(Z) ConstantInstr(type));
1626 arguments->Add(PushArgument(type_const));
1627 const intptr_t kNumArgsChecked = 2;
1628 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1629 node->token_pos(),
1630 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()),
1631 node->kind(),
1632 arguments,
1633 Object::null_array(), // No argument names.
1634 kNumArgsChecked,
1635 owner()->ic_data_array());
1636 ReturnDefinition(call);
1606 } else { 1637 } else {
1607 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); 1638 PushArgumentInstr* push_type_args = NULL;
1639 if (type.IsInstantiated()) {
1640 push_type_args = PushArgument(BuildNullValue(node->token_pos()));
1641 } else {
1642 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1643 }
1644 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1645 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1646 arguments->Add(push_left);
1647 arguments->Add(push_type_args);
1648 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1649 Value* type_const = Bind(new(Z) ConstantInstr(type));
1650 arguments->Add(PushArgument(type_const));
1651 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1652 Value* negate_arg = Bind(new(Z) ConstantInstr(negate));
1653 arguments->Add(PushArgument(negate_arg));
1654 const intptr_t kNumArgsChecked = 1;
1655 InstanceCallInstr* call = new(Z) InstanceCallInstr(
1656 node->token_pos(),
1657 Library::PrivateCoreLibName(Symbols::_instanceOf()),
1658 node->kind(),
1659 arguments,
1660 Object::null_array(), // No argument names.
1661 kNumArgsChecked,
1662 owner()->ic_data_array());
1663 ReturnDefinition(call);
1608 } 1664 }
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 } 1665 }
1630 1666
1631 1667
1632 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1668 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1633 ASSERT(Token::IsTypeCastOperator(node->kind())); 1669 ASSERT(Token::IsTypeCastOperator(node->kind()));
1634 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1670 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1635 const AbstractType& type = node->right()->AsTypeNode()->type(); 1671 const AbstractType& type = node->right()->AsTypeNode()->type();
1636 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1672 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1637 ValueGraphVisitor for_value(owner()); 1673 ValueGraphVisitor for_value(owner());
1638 node->left()->Visit(&for_value); 1674 node->left()->Visit(&for_value);
(...skipping 2942 matching lines...) Expand 10 before | Expand all | Expand 10 after
4581 block_marks); 4617 block_marks);
4582 ASSERT(found); 4618 ASSERT(found);
4583 } 4619 }
4584 4620
4585 4621
4586 void FlowGraphBuilder::Bailout(const char* reason) const { 4622 void FlowGraphBuilder::Bailout(const char* reason) const {
4587 parsed_function_.Bailout("FlowGraphBuilder", reason); 4623 parsed_function_.Bailout("FlowGraphBuilder", reason);
4588 } 4624 }
4589 4625
4590 } // namespace dart 4626 } // 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