OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 } | 1663 } |
1664 | 1664 |
1665 | 1665 |
1666 void HLoadNamedField::PrintDataTo(StringStream* stream) { | 1666 void HLoadNamedField::PrintDataTo(StringStream* stream) { |
1667 object()->PrintNameTo(stream); | 1667 object()->PrintNameTo(stream); |
1668 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); | 1668 stream->Add(" @%d%s", offset(), is_in_object() ? "[in-object]" : ""); |
1669 } | 1669 } |
1670 | 1670 |
1671 | 1671 |
1672 // Returns true if an instance of this map can never find a property with this | 1672 // Returns true if an instance of this map can never find a property with this |
1673 // name in its prototype chain. This means all prototypes up to the top are | 1673 // name in its prototype chain. This means all prototypes up to the top are fast |
1674 // fast and don't have the name in them. It would be good if we could optimize | 1674 // and don't have the name in them. It would be good if we could optimize |
1675 // polymorphic loads where the property is sometimes found in the prototype | 1675 // polymorphic loads where the property is sometimes found in the prototype |
1676 // chain. | 1676 // chain. |
1677 static bool PrototypeChainCanNeverResolve( | 1677 static bool PrototypeChainCanNeverResolve( |
1678 Handle<Map> map, Handle<String> name) { | 1678 Handle<Map> map, Handle<String> name) { |
1679 Isolate* isolate = map->GetIsolate(); | 1679 Isolate* isolate = map->GetIsolate(); |
1680 Object* current = map->prototype(); | 1680 Object* current = map->prototype(); |
1681 while (current != isolate->heap()->null_value()) { | 1681 while (current != isolate->heap()->null_value()) { |
1682 if (current->IsJSGlobalProxy() || | 1682 if (current->IsJSGlobalProxy() || |
1683 current->IsGlobalObject() || | 1683 current->IsGlobalObject() || |
1684 !current->IsJSObject() || | 1684 !current->IsJSObject() || |
1685 JSObject::cast(current)->IsAccessCheckNeeded() || | 1685 JSObject::cast(current)->IsAccessCheckNeeded() || |
1686 !JSObject::cast(current)->HasFastProperties()) { | 1686 !JSObject::cast(current)->HasFastProperties()) { |
1687 return false; | 1687 return false; |
1688 } | 1688 } |
1689 | 1689 |
1690 LookupResult lookup(isolate); | 1690 LookupResult lookup(isolate); |
1691 Map* map = JSObject::cast(current)->map(); | 1691 Map* map = JSObject::cast(current)->map(); |
1692 map->LookupTransitionOrDescriptor(NULL, *name, &lookup); | 1692 map->LookupDescriptor(NULL, *name, &lookup); |
1693 if (lookup.IsFound()) { | 1693 if (lookup.IsFound()) return false; |
1694 if (!lookup.IsTransition()) return false; | 1694 if (!lookup.IsCacheable()) return false; |
1695 } else if (!lookup.IsCacheable()) { | |
1696 return false; | |
1697 } | |
1698 | |
1699 current = JSObject::cast(current)->GetPrototype(); | 1695 current = JSObject::cast(current)->GetPrototype(); |
1700 } | 1696 } |
1701 return true; | 1697 return true; |
1702 } | 1698 } |
1703 | 1699 |
1704 | 1700 |
1705 HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, | 1701 HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, |
1706 HValue* object, | 1702 HValue* object, |
1707 SmallMapList* types, | 1703 SmallMapList* types, |
1708 Handle<String> name, | 1704 Handle<String> name, |
1709 Zone* zone) | 1705 Zone* zone) |
1710 : types_(Min(types->length(), kMaxLoadPolymorphism), zone), | 1706 : types_(Min(types->length(), kMaxLoadPolymorphism), zone), |
1711 name_(name), | 1707 name_(name), |
1712 need_generic_(false) { | 1708 need_generic_(false) { |
1713 SetOperandAt(0, context); | 1709 SetOperandAt(0, context); |
1714 SetOperandAt(1, object); | 1710 SetOperandAt(1, object); |
1715 set_representation(Representation::Tagged()); | 1711 set_representation(Representation::Tagged()); |
1716 SetGVNFlag(kDependsOnMaps); | 1712 SetGVNFlag(kDependsOnMaps); |
1717 SmallMapList negative_lookups; | 1713 SmallMapList negative_lookups; |
1718 for (int i = 0; | 1714 for (int i = 0; |
1719 i < types->length() && types_.length() < kMaxLoadPolymorphism; | 1715 i < types->length() && types_.length() < kMaxLoadPolymorphism; |
1720 ++i) { | 1716 ++i) { |
1721 Handle<Map> map = types->at(i); | 1717 Handle<Map> map = types->at(i); |
1722 LookupResult lookup(map->GetIsolate()); | 1718 LookupResult lookup(map->GetIsolate()); |
1723 map->LookupTransitionOrDescriptor(NULL, *name, &lookup); | 1719 map->LookupDescriptor(NULL, *name, &lookup); |
1724 if (lookup.IsFound()) { | 1720 if (lookup.IsFound()) { |
1725 switch (lookup.type()) { | 1721 switch (lookup.type()) { |
1726 case FIELD: { | 1722 case FIELD: { |
1727 int index = lookup.GetLocalFieldIndexFromMap(*map); | 1723 int index = lookup.GetLocalFieldIndexFromMap(*map); |
1728 if (index < 0) { | 1724 if (index < 0) { |
1729 SetGVNFlag(kDependsOnInobjectFields); | 1725 SetGVNFlag(kDependsOnInobjectFields); |
1730 } else { | 1726 } else { |
1731 SetGVNFlag(kDependsOnBackingStoreFields); | 1727 SetGVNFlag(kDependsOnBackingStoreFields); |
1732 } | 1728 } |
1733 types_.Add(types->at(i), zone); | 1729 types_.Add(types->at(i), zone); |
1734 break; | 1730 break; |
1735 } | 1731 } |
1736 case CONSTANT_FUNCTION: | 1732 case CONSTANT_FUNCTION: |
1737 types_.Add(types->at(i), zone); | 1733 types_.Add(types->at(i), zone); |
1738 break; | 1734 break; |
1739 case CALLBACKS: | 1735 case CALLBACKS: |
1740 break; | 1736 break; |
1741 case TRANSITION: | 1737 case TRANSITION: |
1742 if (PrototypeChainCanNeverResolve(map, name)) { | |
1743 negative_lookups.Add(types->at(i), zone); | |
1744 } | |
1745 break; | |
1746 case INTERCEPTOR: | 1738 case INTERCEPTOR: |
1747 case NONEXISTENT: | 1739 case NONEXISTENT: |
1748 case NORMAL: | 1740 case NORMAL: |
1749 case HANDLER: | 1741 case HANDLER: |
1750 UNREACHABLE(); | 1742 UNREACHABLE(); |
1751 break; | 1743 break; |
1752 } | 1744 } |
1753 } else if (lookup.IsCacheable()) { | 1745 } else if (lookup.IsCacheable() && |
1754 if (PrototypeChainCanNeverResolve(map, name)) { | 1746 PrototypeChainCanNeverResolve(map, name)) { |
1755 negative_lookups.Add(types->at(i), zone); | 1747 negative_lookups.Add(types->at(i), zone); |
1756 } | |
1757 } | 1748 } |
1758 } | 1749 } |
1759 | 1750 |
1760 bool need_generic = | 1751 bool need_generic = |
1761 (types->length() != negative_lookups.length() + types_.length()); | 1752 (types->length() != negative_lookups.length() + types_.length()); |
1762 if (!need_generic && FLAG_deoptimize_uncommon_cases) { | 1753 if (!need_generic && FLAG_deoptimize_uncommon_cases) { |
1763 SetFlag(kUseGVN); | 1754 SetFlag(kUseGVN); |
1764 for (int i = 0; i < negative_lookups.length(); i++) { | 1755 for (int i = 0; i < negative_lookups.length(); i++) { |
1765 types_.Add(negative_lookups.at(i), zone); | 1756 types_.Add(negative_lookups.at(i), zone); |
1766 } | 1757 } |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 | 2580 |
2590 | 2581 |
2591 void HCheckPrototypeMaps::Verify() { | 2582 void HCheckPrototypeMaps::Verify() { |
2592 HInstruction::Verify(); | 2583 HInstruction::Verify(); |
2593 ASSERT(HasNoUses()); | 2584 ASSERT(HasNoUses()); |
2594 } | 2585 } |
2595 | 2586 |
2596 #endif | 2587 #endif |
2597 | 2588 |
2598 } } // namespace v8::internal | 2589 } } // namespace v8::internal |
OLD | NEW |