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

Side by Side Diff: src/crankshaft/hydrogen.cc

Issue 2424433002: [ic] Delete old KeyedLoadIC code (Closed)
Patch Set: fix failing test Created 4 years, 2 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 | « src/crankshaft/hydrogen.h ('k') | src/deoptimize-reason.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/crankshaft/hydrogen.h" 5 #include "src/crankshaft/hydrogen.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 1640
1641 cow_checker.Else(); 1641 cow_checker.Else();
1642 1642
1643 environment()->Push(elements); 1643 environment()->Push(elements);
1644 1644
1645 cow_checker.End(); 1645 cow_checker.End();
1646 1646
1647 return environment()->Pop(); 1647 return environment()->Pop();
1648 } 1648 }
1649 1649
1650
1651 void HGraphBuilder::BuildJSObjectCheck(HValue* receiver,
1652 int bit_field_mask) {
1653 // Check that the object isn't a smi.
1654 Add<HCheckHeapObject>(receiver);
1655
1656 // Get the map of the receiver.
1657 HValue* map =
1658 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
1659
1660 // Check the instance type and if an access check is needed, this can be
1661 // done with a single load, since both bytes are adjacent in the map.
1662 HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField());
1663 HValue* instance_type_and_bit_field =
1664 Add<HLoadNamedField>(map, nullptr, access);
1665
1666 HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8));
1667 HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND,
1668 instance_type_and_bit_field,
1669 mask);
1670 HValue* sub_result = AddUncasted<HSub>(and_result,
1671 Add<HConstant>(JS_OBJECT_TYPE));
1672 Add<HBoundsCheck>(sub_result,
1673 Add<HConstant>(LAST_JS_OBJECT_TYPE + 1 - JS_OBJECT_TYPE));
1674 }
1675
1676
1677 void HGraphBuilder::BuildKeyedIndexCheck(HValue* key,
1678 HIfContinuation* join_continuation) {
1679 // The sometimes unintuitively backward ordering of the ifs below is
1680 // convoluted, but necessary. All of the paths must guarantee that the
1681 // if-true of the continuation returns a smi element index and the if-false of
1682 // the continuation returns either a symbol or a unique string key. All other
1683 // object types cause a deopt to fall back to the runtime.
1684
1685 IfBuilder key_smi_if(this);
1686 key_smi_if.If<HIsSmiAndBranch>(key);
1687 key_smi_if.Then();
1688 {
1689 Push(key); // Nothing to do, just continue to true of continuation.
1690 }
1691 key_smi_if.Else();
1692 {
1693 HValue* map = Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForMap());
1694 HValue* instance_type =
1695 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
1696
1697 // Non-unique string, check for a string with a hash code that is actually
1698 // an index.
1699 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
1700 IfBuilder not_string_or_name_if(this);
1701 not_string_or_name_if.If<HCompareNumericAndBranch>(
1702 instance_type,
1703 Add<HConstant>(LAST_UNIQUE_NAME_TYPE),
1704 Token::GT);
1705
1706 not_string_or_name_if.Then();
1707 {
1708 // Non-smi, non-Name, non-String: Try to convert to smi in case of
1709 // HeapNumber.
1710 // TODO(danno): This could call some variant of ToString
1711 Push(AddUncasted<HForceRepresentation>(key, Representation::Smi()));
1712 }
1713 not_string_or_name_if.Else();
1714 {
1715 // String or Name: check explicitly for Name, they can short-circuit
1716 // directly to unique non-index key path.
1717 IfBuilder not_symbol_if(this);
1718 not_symbol_if.If<HCompareNumericAndBranch>(
1719 instance_type,
1720 Add<HConstant>(SYMBOL_TYPE),
1721 Token::NE);
1722
1723 not_symbol_if.Then();
1724 {
1725 // String: check whether the String is a String of an index. If it is,
1726 // extract the index value from the hash.
1727 HValue* hash = Add<HLoadNamedField>(key, nullptr,
1728 HObjectAccess::ForNameHashField());
1729 HValue* not_index_mask = Add<HConstant>(static_cast<int>(
1730 String::kContainsCachedArrayIndexMask));
1731
1732 HValue* not_index_test = AddUncasted<HBitwise>(
1733 Token::BIT_AND, hash, not_index_mask);
1734
1735 IfBuilder string_index_if(this);
1736 string_index_if.If<HCompareNumericAndBranch>(not_index_test,
1737 graph()->GetConstant0(),
1738 Token::EQ);
1739 string_index_if.Then();
1740 {
1741 // String with index in hash: extract string and merge to index path.
1742 Push(BuildDecodeField<String::ArrayIndexValueBits>(hash));
1743 }
1744 string_index_if.Else();
1745 {
1746 // Key is a non-index String, check for uniqueness/internalization.
1747 // If it's not internalized yet, internalize it now.
1748 HValue* not_internalized_bit = AddUncasted<HBitwise>(
1749 Token::BIT_AND,
1750 instance_type,
1751 Add<HConstant>(static_cast<int>(kIsNotInternalizedMask)));
1752
1753 IfBuilder internalized(this);
1754 internalized.If<HCompareNumericAndBranch>(not_internalized_bit,
1755 graph()->GetConstant0(),
1756 Token::EQ);
1757 internalized.Then();
1758 Push(key);
1759
1760 internalized.Else();
1761 Add<HPushArguments>(key);
1762 HValue* intern_key = Add<HCallRuntime>(
1763 Runtime::FunctionForId(Runtime::kInternalizeString), 1);
1764 Push(intern_key);
1765
1766 internalized.End();
1767 // Key guaranteed to be a unique string
1768 }
1769 string_index_if.JoinContinuation(join_continuation);
1770 }
1771 not_symbol_if.Else();
1772 {
1773 Push(key); // Key is symbol
1774 }
1775 not_symbol_if.JoinContinuation(join_continuation);
1776 }
1777 not_string_or_name_if.JoinContinuation(join_continuation);
1778 }
1779 key_smi_if.JoinContinuation(join_continuation);
1780 }
1781
1782
1783 void HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) {
1784 // Get the the instance type of the receiver, and make sure that it is
1785 // not one of the global object types.
1786 HValue* map =
1787 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
1788 HValue* instance_type =
1789 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
1790 HValue* global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE);
1791
1792 IfBuilder if_global_object(this);
1793 if_global_object.If<HCompareNumericAndBranch>(instance_type, global_type,
1794 Token::EQ);
1795 if_global_object.ThenDeopt(DeoptimizeReason::kReceiverWasAGlobalObject);
1796 if_global_object.End();
1797 }
1798
1799
1800 void HGraphBuilder::BuildTestForDictionaryProperties(
1801 HValue* object,
1802 HIfContinuation* continuation) {
1803 HValue* properties = Add<HLoadNamedField>(
1804 object, nullptr, HObjectAccess::ForPropertiesPointer());
1805 HValue* properties_map =
1806 Add<HLoadNamedField>(properties, nullptr, HObjectAccess::ForMap());
1807 HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex);
1808 IfBuilder builder(this);
1809 builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map);
1810 builder.CaptureContinuation(continuation);
1811 }
1812
1813
1814 HValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object,
1815 HValue* key) {
1816 // Load the map of the receiver, compute the keyed lookup cache hash
1817 // based on 32 bits of the map pointer and the string hash.
1818 HValue* object_map =
1819 Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMapAsInteger32());
1820 HValue* shifted_map = AddUncasted<HShr>(
1821 object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift));
1822 HValue* string_hash =
1823 Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForStringHashField());
1824 HValue* shifted_hash = AddUncasted<HShr>(
1825 string_hash, Add<HConstant>(String::kHashShift));
1826 HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map,
1827 shifted_hash);
1828 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
1829 return AddUncasted<HBitwise>(Token::BIT_AND, xor_result,
1830 Add<HConstant>(mask));
1831 }
1832
1833
1834 HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { 1650 HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) {
1835 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); 1651 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed());
1836 HValue* seed = Add<HConstant>(seed_value); 1652 HValue* seed = Add<HConstant>(seed_value);
1837 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed); 1653 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed);
1838 1654
1839 // hash = ~hash + (hash << 15); 1655 // hash = ~hash + (hash << 15);
1840 HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15)); 1656 HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15));
1841 HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, 1657 HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash,
1842 graph()->GetConstantMinus1()); 1658 graph()->GetConstantMinus1());
1843 hash = AddUncasted<HAdd>(shifted_hash, not_hash); 1659 hash = AddUncasted<HAdd>(shifted_hash, not_hash);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 Push(entry); 1806 Push(entry);
1991 Push(count); 1807 Push(count);
1992 1808
1993 probe_loop.EndBody(); 1809 probe_loop.EndBody();
1994 1810
1995 return_or_loop.End(); 1811 return_or_loop.End();
1996 1812
1997 return Pop(); 1813 return Pop();
1998 } 1814 }
1999 1815
2000
2001 HValue* HGraphBuilder::BuildCreateIterResultObject(HValue* value, 1816 HValue* HGraphBuilder::BuildCreateIterResultObject(HValue* value,
2002 HValue* done) { 1817 HValue* done) {
2003 NoObservableSideEffectsScope scope(this); 1818 NoObservableSideEffectsScope scope(this);
2004 1819
2005 // Allocate the JSIteratorResult object. 1820 // Allocate the JSIteratorResult object.
2006 HValue* result = 1821 HValue* result =
2007 Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(), 1822 Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(),
2008 NOT_TENURED, JS_OBJECT_TYPE, graph()->GetConstant0()); 1823 NOT_TENURED, JS_OBJECT_TYPE, graph()->GetConstant0());
2009 1824
2010 // Initialize the JSIteratorResult object. 1825 // Initialize the JSIteratorResult object.
(...skipping 11276 matching lines...) Expand 10 before | Expand all | Expand 10 after
13287 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 13102 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
13288 } 13103 }
13289 13104
13290 #ifdef DEBUG 13105 #ifdef DEBUG
13291 graph_->Verify(false); // No full verify. 13106 graph_->Verify(false); // No full verify.
13292 #endif 13107 #endif
13293 } 13108 }
13294 13109
13295 } // namespace internal 13110 } // namespace internal
13296 } // namespace v8 13111 } // namespace v8
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.h ('k') | src/deoptimize-reason.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698