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

Side by Side Diff: src/hydrogen.cc

Issue 122463004: Revert "Fix compilation with C++11." and "Allocation site support for monomorphic StringAdds in Bin… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.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 // 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 1675 matching lines...) Expand 10 before | Expand all | Expand 10 after
1686 isolate()->factory()->empty_string(), 1686 isolate()->factory()->empty_string(),
1687 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 1687 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1688 1)); 1688 1));
1689 } 1689 }
1690 if_found.End(); 1690 if_found.End();
1691 1691
1692 return Pop(); 1692 return Pop();
1693 } 1693 }
1694 1694
1695 1695
1696 HAllocate* HGraphBuilder::BuildAllocate( 1696 HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
1697 HValue* object_size, 1697 String::Encoding encoding) {
1698 HType type, 1698 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
1699 InstanceType instance_type, 1699 HValue* size = length;
1700 HAllocationMode allocation_mode) { 1700 if (encoding == String::TWO_BYTE_ENCODING) {
1701 // Compute the effective allocation size. 1701 size = AddUncasted<HShl>(length, graph()->GetConstant1());
1702 HValue* size = object_size;
1703 if (allocation_mode.CreateAllocationMementos()) {
1704 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize));
1705 size->ClearFlag(HValue::kCanOverflow); 1702 size->ClearFlag(HValue::kCanOverflow);
1703 size->SetFlag(HValue::kUint32);
1706 } 1704 }
1707 1705 size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
1708 // Perform the actual allocation. 1706 SeqString::kHeaderSize + kObjectAlignmentMask)));
1709 HAllocate* object = Add<HAllocate>( 1707 size->ClearFlag(HValue::kCanOverflow);
1710 size, type, allocation_mode.GetPretenureMode(), 1708 size = AddUncasted<HBitwise>(
1711 instance_type, allocation_mode.feedback_site()); 1709 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
1712 1710 ~kObjectAlignmentMask)));
1713 // Setup the allocation memento. 1711 return size;
1714 if (allocation_mode.CreateAllocationMementos()) {
1715 BuildCreateAllocationMemento(
1716 object, object_size, allocation_mode.current_site());
1717 }
1718
1719 return object;
1720 } 1712 }
1721 1713
1722 1714
1723 HValue* HGraphBuilder::BuildAddStringLengths(HValue* left_length,
1724 HValue* right_length) {
1725 // Compute the combined string length. If the result is larger than the max
1726 // supported string length, we bailout to the runtime. This is done implicitly
1727 // when converting the result back to a smi in case the max string length
1728 // equals the max smi value. Otherwise, for platforms with 32-bit smis, we do
1729 HValue* length = AddUncasted<HAdd>(left_length, right_length);
1730 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
1731 if (String::kMaxLength != Smi::kMaxValue) {
1732 IfBuilder if_nooverflow(this);
1733 if_nooverflow.If<HCompareNumericAndBranch>(
1734 length, Add<HConstant>(String::kMaxLength), Token::LTE);
1735 if_nooverflow.Then();
1736 if_nooverflow.ElseDeopt("String length exceeds limit");
1737 }
1738 return length;
1739 }
1740
1741
1742 HValue* HGraphBuilder::BuildCreateConsString(
1743 HValue* length,
1744 HValue* left,
1745 HValue* right,
1746 HAllocationMode allocation_mode) {
1747 // Determine the string instance types.
1748 HInstruction* left_instance_type = AddLoadStringInstanceType(left);
1749 HInstruction* right_instance_type = AddLoadStringInstanceType(right);
1750
1751 // Allocate the cons string object. HAllocate does not care whether we
1752 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1753 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1754 // one-byte or two-byte and set the appropriate map.
1755 ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
1756 CONS_ASCII_STRING_TYPE));
1757 HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize),
1758 HType::String(), CONS_STRING_TYPE,
1759 allocation_mode);
1760
1761 // Compute intersection and difference of instance types.
1762 HValue* anded_instance_types = AddUncasted<HBitwise>(
1763 Token::BIT_AND, left_instance_type, right_instance_type);
1764 HValue* xored_instance_types = AddUncasted<HBitwise>(
1765 Token::BIT_XOR, left_instance_type, right_instance_type);
1766
1767 // We create a one-byte cons string if
1768 // 1. both strings are one-byte, or
1769 // 2. at least one of the strings is two-byte, but happens to contain only
1770 // one-byte characters.
1771 // To do this, we check
1772 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1773 // both strings, or
1774 // 2. if one of the strings has the one-byte data hint set and the other
1775 // string is one-byte.
1776 IfBuilder if_onebyte(this);
1777 STATIC_ASSERT(kOneByteStringTag != 0);
1778 STATIC_ASSERT(kOneByteDataHintMask != 0);
1779 if_onebyte.If<HCompareNumericAndBranch>(
1780 AddUncasted<HBitwise>(
1781 Token::BIT_AND, anded_instance_types,
1782 Add<HConstant>(static_cast<int32_t>(
1783 kStringEncodingMask | kOneByteDataHintMask))),
1784 graph()->GetConstant0(), Token::NE);
1785 if_onebyte.Or();
1786 STATIC_ASSERT(kOneByteStringTag != 0 &&
1787 kOneByteDataHintTag != 0 &&
1788 kOneByteDataHintTag != kOneByteStringTag);
1789 if_onebyte.If<HCompareNumericAndBranch>(
1790 AddUncasted<HBitwise>(
1791 Token::BIT_AND, xored_instance_types,
1792 Add<HConstant>(static_cast<int32_t>(
1793 kOneByteStringTag | kOneByteDataHintTag))),
1794 Add<HConstant>(static_cast<int32_t>(
1795 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1796 if_onebyte.Then();
1797 {
1798 // We can safely skip the write barrier for storing the map here.
1799 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1800 AddStoreMapConstantNoWriteBarrier(result, map);
1801 }
1802 if_onebyte.Else();
1803 {
1804 // We can safely skip the write barrier for storing the map here.
1805 Handle<Map> map = isolate()->factory()->cons_string_map();
1806 AddStoreMapConstantNoWriteBarrier(result, map);
1807 }
1808 if_onebyte.End();
1809
1810 // Initialize the cons string fields.
1811 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
1812 Add<HConstant>(String::kEmptyHashField));
1813 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
1814 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left);
1815 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right);
1816
1817 // Count the native string addition.
1818 AddIncrementCounter(isolate()->counters()->string_add_native());
1819
1820 return result;
1821 }
1822
1823
1824 void HGraphBuilder::BuildCopySeqStringChars(HValue* src, 1715 void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
1825 HValue* src_offset, 1716 HValue* src_offset,
1826 String::Encoding src_encoding, 1717 String::Encoding src_encoding,
1827 HValue* dst, 1718 HValue* dst,
1828 HValue* dst_offset, 1719 HValue* dst_offset,
1829 String::Encoding dst_encoding, 1720 String::Encoding dst_encoding,
1830 HValue* length) { 1721 HValue* length) {
1831 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING || 1722 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
1832 src_encoding == String::ONE_BYTE_ENCODING); 1723 src_encoding == String::ONE_BYTE_ENCODING);
1833 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 1724 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
1834 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 1725 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
1835 { 1726 {
1836 HValue* src_index = AddUncasted<HAdd>(src_offset, index); 1727 HValue* src_index = AddUncasted<HAdd>(src_offset, index);
1837 HValue* value = 1728 HValue* value =
1838 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); 1729 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index);
1839 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 1730 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index);
1840 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 1731 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
1841 } 1732 }
1842 loop.EndBody(); 1733 loop.EndBody();
1843 } 1734 }
1844 1735
1845 1736
1846 HValue* HGraphBuilder::BuildUncheckedStringAdd( 1737 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
1847 HValue* left, 1738 HValue* right,
1848 HValue* right, 1739 PretenureFlag pretenure_flag) {
1849 HAllocationMode allocation_mode) {
1850 // Determine the string lengths. 1740 // Determine the string lengths.
1851 HValue* left_length = AddLoadStringLength(left); 1741 HValue* left_length = Add<HLoadNamedField>(
1852 HValue* right_length = AddLoadStringLength(right); 1742 left, HObjectAccess::ForStringLength());
1743 HValue* right_length = Add<HLoadNamedField>(
1744 right, HObjectAccess::ForStringLength());
1853 1745
1854 // Compute the combined string length. 1746 // Compute the combined string length. If the result is larger than the max
1855 HValue* length = BuildAddStringLengths(left_length, right_length); 1747 // supported string length, we bailout to the runtime. This is done implicitly
1748 // when converting the result back to a smi in case the max string length
1749 // equals the max smi valie. Otherwise, for platforms with 32-bit smis, we do
1750 HValue* length = AddUncasted<HAdd>(left_length, right_length);
1751 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
1752 if (String::kMaxLength != Smi::kMaxValue) {
1753 IfBuilder if_nooverflow(this);
1754 if_nooverflow.If<HCompareNumericAndBranch>(
1755 length, Add<HConstant>(String::kMaxLength), Token::LTE);
1756 if_nooverflow.Then();
1757 if_nooverflow.ElseDeopt("String length exceeds limit");
1758 }
1856 1759
1857 // Do some manual constant folding here. 1760 // Determine the string instance types.
1858 if (left_length->IsConstant()) { 1761 HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
1859 HConstant* c_left_length = HConstant::cast(left_length); 1762 Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
1860 ASSERT_NE(0, c_left_length->Integer32Value()); 1763 HObjectAccess::ForMapInstanceType());
1861 if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) { 1764 HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
1862 // The right string contains at least one character. 1765 Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
1863 return BuildCreateConsString(length, left, right, allocation_mode); 1766 HObjectAccess::ForMapInstanceType());
1864 } 1767
1865 } else if (right_length->IsConstant()) { 1768 // Compute difference of instance types.
1866 HConstant* c_right_length = HConstant::cast(right_length); 1769 HValue* xored_instance_types = AddUncasted<HBitwise>(
1867 ASSERT_NE(0, c_right_length->Integer32Value()); 1770 Token::BIT_XOR, left_instance_type, right_instance_type);
1868 if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) {
1869 // The left string contains at least one character.
1870 return BuildCreateConsString(length, left, right, allocation_mode);
1871 }
1872 }
1873 1771
1874 // Check if we should create a cons string. 1772 // Check if we should create a cons string.
1875 IfBuilder if_createcons(this); 1773 IfBuilder if_createcons(this);
1876 if_createcons.If<HCompareNumericAndBranch>( 1774 if_createcons.If<HCompareNumericAndBranch>(
1877 length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 1775 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
1878 if_createcons.Then(); 1776 if_createcons.Then();
1879 { 1777 {
1880 // Create a cons string. 1778 // Allocate the cons string object. HAllocate does not care whether we
1881 Push(BuildCreateConsString(length, left, right, allocation_mode)); 1779 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1780 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1781 // one-byte or two-byte and set the appropriate map.
1782 ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
1783 CONS_ASCII_STRING_TYPE));
1784 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
1785 HType::String(), pretenure_flag,
1786 CONS_STRING_TYPE);
1787
1788 // Compute the intersection of instance types.
1789 HValue* anded_instance_types = AddUncasted<HBitwise>(
1790 Token::BIT_AND, left_instance_type, right_instance_type);
1791
1792 // We create a one-byte cons string if
1793 // 1. both strings are one-byte, or
1794 // 2. at least one of the strings is two-byte, but happens to contain only
1795 // one-byte characters.
1796 // To do this, we check
1797 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1798 // both strings, or
1799 // 2. if one of the strings has the one-byte data hint set and the other
1800 // string is one-byte.
1801 IfBuilder if_onebyte(this);
1802 STATIC_ASSERT(kOneByteStringTag != 0);
1803 STATIC_ASSERT(kOneByteDataHintMask != 0);
1804 if_onebyte.If<HCompareNumericAndBranch>(
1805 AddUncasted<HBitwise>(
1806 Token::BIT_AND, anded_instance_types,
1807 Add<HConstant>(static_cast<int32_t>(
1808 kStringEncodingMask | kOneByteDataHintMask))),
1809 graph()->GetConstant0(), Token::NE);
1810 if_onebyte.Or();
1811 STATIC_ASSERT(kOneByteStringTag != 0 &&
1812 kOneByteDataHintTag != 0 &&
1813 kOneByteDataHintTag != kOneByteStringTag);
1814 if_onebyte.If<HCompareNumericAndBranch>(
1815 AddUncasted<HBitwise>(
1816 Token::BIT_AND, xored_instance_types,
1817 Add<HConstant>(static_cast<int32_t>(
1818 kOneByteStringTag | kOneByteDataHintTag))),
1819 Add<HConstant>(static_cast<int32_t>(
1820 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1821 if_onebyte.Then();
1822 {
1823 // We can safely skip the write barrier for storing the map here.
1824 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1825 AddStoreMapConstantNoWriteBarrier(string, map);
1826 }
1827 if_onebyte.Else();
1828 {
1829 // We can safely skip the write barrier for storing the map here.
1830 Handle<Map> map = isolate()->factory()->cons_string_map();
1831 AddStoreMapConstantNoWriteBarrier(string, map);
1832 }
1833 if_onebyte.End();
1834
1835 // Initialize the cons string fields.
1836 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1837 Add<HConstant>(String::kEmptyHashField));
1838 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
1839 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
1840 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
1841 right);
1842
1843 // Count the native string addition.
1844 AddIncrementCounter(isolate()->counters()->string_add_native());
1845
1846 // Cons string is result.
1847 Push(string);
1882 } 1848 }
1883 if_createcons.Else(); 1849 if_createcons.Else();
1884 { 1850 {
1885 // Determine the string instance types. 1851 // Compute union of instance types.
1886 HValue* left_instance_type = AddLoadStringInstanceType(left);
1887 HValue* right_instance_type = AddLoadStringInstanceType(right);
1888
1889 // Compute union and difference of instance types.
1890 HValue* ored_instance_types = AddUncasted<HBitwise>( 1852 HValue* ored_instance_types = AddUncasted<HBitwise>(
1891 Token::BIT_OR, left_instance_type, right_instance_type); 1853 Token::BIT_OR, left_instance_type, right_instance_type);
1892 HValue* xored_instance_types = AddUncasted<HBitwise>(
1893 Token::BIT_XOR, left_instance_type, right_instance_type);
1894 1854
1895 // Check if both strings have the same encoding and both are 1855 // Check if both strings have the same encoding and both are
1896 // sequential. 1856 // sequential.
1897 IfBuilder if_sameencodingandsequential(this); 1857 IfBuilder if_sameencodingandsequential(this);
1898 if_sameencodingandsequential.If<HCompareNumericAndBranch>( 1858 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1899 AddUncasted<HBitwise>( 1859 AddUncasted<HBitwise>(
1900 Token::BIT_AND, xored_instance_types, 1860 Token::BIT_AND, xored_instance_types,
1901 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 1861 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1902 graph()->GetConstant0(), Token::EQ); 1862 graph()->GetConstant0(), Token::EQ);
1903 if_sameencodingandsequential.And(); 1863 if_sameencodingandsequential.And();
1904 STATIC_ASSERT(kSeqStringTag == 0); 1864 STATIC_ASSERT(kSeqStringTag == 0);
1905 if_sameencodingandsequential.If<HCompareNumericAndBranch>( 1865 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1906 AddUncasted<HBitwise>( 1866 AddUncasted<HBitwise>(
1907 Token::BIT_AND, ored_instance_types, 1867 Token::BIT_AND, ored_instance_types,
1908 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), 1868 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1909 graph()->GetConstant0(), Token::EQ); 1869 graph()->GetConstant0(), Token::EQ);
1910 if_sameencodingandsequential.Then(); 1870 if_sameencodingandsequential.Then();
1911 { 1871 {
1912 HConstant* string_map = 1872 // Check if the result is a one-byte string.
1913 Add<HConstant>(isolate()->factory()->string_map());
1914 HConstant* ascii_string_map =
1915 Add<HConstant>(isolate()->factory()->ascii_string_map());
1916
1917 // Determine map and size depending on whether result is one-byte string.
1918 IfBuilder if_onebyte(this); 1873 IfBuilder if_onebyte(this);
1919 STATIC_ASSERT(kOneByteStringTag != 0); 1874 STATIC_ASSERT(kOneByteStringTag != 0);
1920 if_onebyte.If<HCompareNumericAndBranch>( 1875 if_onebyte.If<HCompareNumericAndBranch>(
1921 AddUncasted<HBitwise>( 1876 AddUncasted<HBitwise>(
1922 Token::BIT_AND, ored_instance_types, 1877 Token::BIT_AND, ored_instance_types,
1923 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 1878 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1924 graph()->GetConstant0(), Token::NE); 1879 graph()->GetConstant0(), Token::NE);
1925 if_onebyte.Then(); 1880 if_onebyte.Then();
1926 { 1881 {
1927 // Allocate sequential one-byte string object. 1882 // Calculate the number of bytes needed for the characters in the
1928 Push(length); 1883 // string while observing object alignment.
1929 Push(ascii_string_map); 1884 HValue* size = BuildSeqStringSizeFor(
1885 length, String::ONE_BYTE_ENCODING);
1886
1887 // Allocate the ASCII string object.
1888 Handle<Map> map = isolate()->factory()->ascii_string_map();
1889 HAllocate* string = Add<HAllocate>(size, HType::String(),
1890 pretenure_flag, ASCII_STRING_TYPE);
1891 string->set_known_initial_map(map);
1892
1893 // We can safely skip the write barrier for storing map here.
1894 AddStoreMapConstantNoWriteBarrier(string, map);
1895
1896 // Length must be stored into the string before we copy characters to
1897 // make debug verification code happy.
1898 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1899 length);
1900
1901 // Copy bytes from the left string.
1902 BuildCopySeqStringChars(
1903 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1904 string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1905 left_length);
1906
1907 // Copy bytes from the right string.
1908 BuildCopySeqStringChars(
1909 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1910 string, left_length, String::ONE_BYTE_ENCODING,
1911 right_length);
1912
1913 // Count the native string addition.
1914 AddIncrementCounter(isolate()->counters()->string_add_native());
1915
1916 // Return the string.
1917 Push(string);
1930 } 1918 }
1931 if_onebyte.Else(); 1919 if_onebyte.Else();
1932 { 1920 {
1933 // Allocate sequential two-byte string object. 1921 // Calculate the number of bytes needed for the characters in the
1934 HValue* size = AddUncasted<HShl>(length, graph()->GetConstant1()); 1922 // string while observing object alignment.
1935 size->ClearFlag(HValue::kCanOverflow); 1923 HValue* size = BuildSeqStringSizeFor(
1936 size->SetFlag(HValue::kUint32); 1924 length, String::TWO_BYTE_ENCODING);
1937 Push(size); 1925
1938 Push(string_map); 1926 // Allocate the two-byte string object.
1927 Handle<Map> map = isolate()->factory()->string_map();
1928 HAllocate* string = Add<HAllocate>(size, HType::String(),
1929 pretenure_flag, STRING_TYPE);
1930 string->set_known_initial_map(map);
1931
1932 // We can safely skip the write barrier for storing map here.
1933 AddStoreMapConstantNoWriteBarrier(string, map);
1934
1935 // Length must be stored into the string before we copy characters to
1936 // make debug verification code happy.
1937 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1938 length);
1939
1940 // Copy bytes from the left string.
1941 BuildCopySeqStringChars(
1942 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1943 string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1944 left_length);
1945
1946 // Copy bytes from the right string.
1947 BuildCopySeqStringChars(
1948 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1949 string, left_length, String::TWO_BYTE_ENCODING,
1950 right_length);
1951
1952 // Return the string.
1953 Push(string);
1939 } 1954 }
1940 if_onebyte.End(); 1955 if_onebyte.End();
1941 HValue* map = Pop();
1942 1956
1943 // Calculate the number of bytes needed for the characters in the 1957 // Initialize the (common) string fields.
1944 // string while observing object alignment. 1958 HValue* string = Pop();
1945 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); 1959 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1946 HValue* size = Pop();
1947 size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
1948 SeqString::kHeaderSize + kObjectAlignmentMask)));
1949 size->ClearFlag(HValue::kCanOverflow);
1950 size = AddUncasted<HBitwise>(
1951 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
1952 ~kObjectAlignmentMask)));
1953
1954 // Allocate the string object. HAllocate does not care whether we pass
1955 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here.
1956 HAllocate* result = BuildAllocate(
1957 size, HType::String(), STRING_TYPE, allocation_mode);
1958
1959 // We can safely skip the write barrier for storing map here.
1960 AddStoreMapNoWriteBarrier(result, map);
1961
1962 // Initialize the string fields.
1963 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(),
1964 Add<HConstant>(String::kEmptyHashField)); 1960 Add<HConstant>(String::kEmptyHashField));
1965 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length);
1966
1967 // Copy characters to the result string.
1968 IfBuilder if_twobyte(this);
1969 if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map);
1970 if_twobyte.Then();
1971 {
1972 // Copy characters from the left string.
1973 BuildCopySeqStringChars(
1974 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1975 result, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1976 left_length);
1977
1978 // Copy characters from the right string.
1979 BuildCopySeqStringChars(
1980 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1981 result, left_length, String::TWO_BYTE_ENCODING,
1982 right_length);
1983 }
1984 if_twobyte.Else();
1985 {
1986 // Copy characters from the left string.
1987 BuildCopySeqStringChars(
1988 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1989 result, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1990 left_length);
1991
1992 // Copy characters from the right string.
1993 BuildCopySeqStringChars(
1994 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1995 result, left_length, String::ONE_BYTE_ENCODING,
1996 right_length);
1997 }
1998 if_twobyte.End();
1999 1961
2000 // Count the native string addition. 1962 // Count the native string addition.
2001 AddIncrementCounter(isolate()->counters()->string_add_native()); 1963 AddIncrementCounter(isolate()->counters()->string_add_native());
2002 1964
2003 // Return the sequential string. 1965 Push(string);
2004 Push(result);
2005 } 1966 }
2006 if_sameencodingandsequential.Else(); 1967 if_sameencodingandsequential.Else();
2007 { 1968 {
2008 // Fallback to the runtime to add the two strings. 1969 // Fallback to the runtime to add the two strings.
2009 Add<HPushArgument>(left); 1970 Add<HPushArgument>(left);
2010 Add<HPushArgument>(right); 1971 Add<HPushArgument>(right);
2011 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), 1972 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
2012 Runtime::FunctionForId(Runtime::kStringAdd), 1973 Runtime::FunctionForId(Runtime::kStringAdd),
2013 2)); 1974 2));
2014 } 1975 }
2015 if_sameencodingandsequential.End(); 1976 if_sameencodingandsequential.End();
2016 } 1977 }
2017 if_createcons.End(); 1978 if_createcons.End();
2018 1979
2019 return Pop(); 1980 return Pop();
2020 } 1981 }
2021 1982
2022 1983
2023 HValue* HGraphBuilder::BuildStringAdd( 1984 HValue* HGraphBuilder::BuildStringAdd(HValue* left,
2024 HValue* left, 1985 HValue* right,
2025 HValue* right, 1986 PretenureFlag pretenure_flag) {
2026 HAllocationMode allocation_mode) { 1987 // Determine the string lengths.
2027 NoObservableSideEffectsScope no_effects(this); 1988 HValue* left_length = Add<HLoadNamedField>(
2028 1989 left, HObjectAccess::ForStringLength());
2029 // Determine string lengths. 1990 HValue* right_length = Add<HLoadNamedField>(
2030 HValue* left_length = AddLoadStringLength(left); 1991 right, HObjectAccess::ForStringLength());
2031 HValue* right_length = AddLoadStringLength(right);
2032 1992
2033 // Check if left string is empty. 1993 // Check if left string is empty.
2034 IfBuilder if_leftempty(this); 1994 IfBuilder if_leftisempty(this);
2035 if_leftempty.If<HCompareNumericAndBranch>( 1995 if_leftisempty.If<HCompareNumericAndBranch>(
2036 left_length, graph()->GetConstant0(), Token::EQ); 1996 left_length, graph()->GetConstant0(), Token::EQ);
2037 if_leftempty.Then(); 1997 if_leftisempty.Then();
2038 { 1998 {
2039 // Count the native string addition. 1999 // Count the native string addition.
2040 AddIncrementCounter(isolate()->counters()->string_add_native()); 2000 AddIncrementCounter(isolate()->counters()->string_add_native());
2041 2001
2042 // Just return the right string. 2002 // Just return the right string.
2043 Push(right); 2003 Push(right);
2044 } 2004 }
2045 if_leftempty.Else(); 2005 if_leftisempty.Else();
2046 { 2006 {
2047 // Check if right string is empty. 2007 // Check if right string is empty.
2048 IfBuilder if_rightempty(this); 2008 IfBuilder if_rightisempty(this);
2049 if_rightempty.If<HCompareNumericAndBranch>( 2009 if_rightisempty.If<HCompareNumericAndBranch>(
2050 right_length, graph()->GetConstant0(), Token::EQ); 2010 right_length, graph()->GetConstant0(), Token::EQ);
2051 if_rightempty.Then(); 2011 if_rightisempty.Then();
2052 { 2012 {
2053 // Count the native string addition. 2013 // Count the native string addition.
2054 AddIncrementCounter(isolate()->counters()->string_add_native()); 2014 AddIncrementCounter(isolate()->counters()->string_add_native());
2055 2015
2056 // Just return the left string. 2016 // Just return the left string.
2057 Push(left); 2017 Push(left);
2058 } 2018 }
2059 if_rightempty.Else(); 2019 if_rightisempty.Else();
2060 { 2020 {
2061 // Add the two non-empty strings. 2021 // Concatenate the two non-empty strings.
2062 Push(BuildUncheckedStringAdd(left, right, allocation_mode)); 2022 Push(BuildUncheckedStringAdd(left, right, pretenure_flag));
2063 } 2023 }
2064 if_rightempty.End(); 2024 if_rightisempty.End();
2065 } 2025 }
2066 if_leftempty.End(); 2026 if_leftisempty.End();
2067 2027
2068 return Pop(); 2028 return Pop();
2069 } 2029 }
2070 2030
2071 2031
2072 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2032 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
2073 HValue* checked_object, 2033 HValue* checked_object,
2074 HValue* key, 2034 HValue* key,
2075 HValue* val, 2035 HValue* val,
2076 bool is_js_array, 2036 bool is_js_array,
(...skipping 4056 matching lines...) Expand 10 before | Expand all | Expand 10 after
6133 return New<HLoadNamedField>(object, access); 6093 return New<HLoadNamedField>(object, access);
6134 } 6094 }
6135 6095
6136 6096
6137 HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object, 6097 HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object,
6138 HObjectAccess access) { 6098 HObjectAccess access) {
6139 return AddInstruction(BuildLoadNamedField(object, access)); 6099 return AddInstruction(BuildLoadNamedField(object, access));
6140 } 6100 }
6141 6101
6142 6102
6143 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { 6103 HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
6144 if (string->IsConstant()) { 6104 HValue* checked_string) {
6145 HConstant* c_string = HConstant::cast(string); 6105 if (FLAG_fold_constants && object->IsConstant()) {
6146 if (c_string->HasStringValue()) { 6106 HConstant* constant = HConstant::cast(object);
6147 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); 6107 if (constant->HasStringValue()) {
6108 return New<HConstant>(constant->StringValue()->length());
6148 } 6109 }
6149 } 6110 }
6150 return AddLoadNamedField( 6111 return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength());
6151 AddLoadNamedField(string, HObjectAccess::ForMap()),
6152 HObjectAccess::ForMapInstanceType());
6153 } 6112 }
6154 6113
6155 6114
6156 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) {
6157 if (string->IsConstant()) {
6158 HConstant* c_string = HConstant::cast(string);
6159 if (c_string->HasStringValue()) {
6160 return Add<HConstant>(c_string->StringValue()->length());
6161 }
6162 }
6163 return AddLoadNamedField(string, HObjectAccess::ForStringLength());
6164 }
6165
6166
6167 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6115 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
6168 HValue* object, 6116 HValue* object,
6169 Handle<String> name, 6117 Handle<String> name,
6170 Property* expr) { 6118 Property* expr) {
6171 if (expr->IsUninitialized()) { 6119 if (expr->IsUninitialized()) {
6172 Add<HDeoptimize>("Insufficient type feedback for generic named load", 6120 Add<HDeoptimize>("Insufficient type feedback for generic named load",
6173 Deoptimizer::SOFT); 6121 Deoptimizer::SOFT);
6174 } 6122 }
6175 return New<HLoadNamedGeneric>(object, name); 6123 return New<HLoadNamedGeneric>(object, name);
6176 } 6124 }
(...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after
8601 HConstant* c_index = HConstant::cast(index); 8549 HConstant* c_index = HConstant::cast(index);
8602 if (c_string->HasStringValue() && c_index->HasNumberValue()) { 8550 if (c_string->HasStringValue() && c_index->HasNumberValue()) {
8603 int32_t i = c_index->NumberValueAsInteger32(); 8551 int32_t i = c_index->NumberValueAsInteger32();
8604 Handle<String> s = c_string->StringValue(); 8552 Handle<String> s = c_string->StringValue();
8605 if (i < 0 || i >= s->length()) { 8553 if (i < 0 || i >= s->length()) {
8606 return New<HConstant>(OS::nan_value()); 8554 return New<HConstant>(OS::nan_value());
8607 } 8555 }
8608 return New<HConstant>(s->Get(i)); 8556 return New<HConstant>(s->Get(i));
8609 } 8557 }
8610 } 8558 }
8611 string = BuildCheckString(string); 8559 BuildCheckHeapObject(string);
8612 index = Add<HBoundsCheck>(index, AddLoadStringLength(string)); 8560 HValue* checkstring =
8613 return New<HStringCharCodeAt>(string, index); 8561 Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
8562 HInstruction* length = BuildLoadStringLength(string, checkstring);
8563 AddInstruction(length);
8564 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
8565 return New<HStringCharCodeAt>(string, checked_index);
8614 } 8566 }
8615 8567
8616 8568
8617 // Checks if the given shift amounts have following forms: 8569 // Checks if the given shift amounts have following forms:
8618 // (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa). 8570 // (N1) and (N2) with N1 + N2 = 32; (sa) and (32 - sa).
8619 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8571 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
8620 HValue* const32_minus_sa) { 8572 HValue* const32_minus_sa) {
8621 if (sa->IsConstant() && const32_minus_sa->IsConstant()) { 8573 if (sa->IsConstant() && const32_minus_sa->IsConstant()) {
8622 const HConstant* c1 = HConstant::cast(sa); 8574 const HConstant* c1 = HConstant::cast(sa);
8623 const HConstant* c2 = HConstant::cast(const32_minus_sa); 8575 const HConstant* c2 = HConstant::cast(const32_minus_sa);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
8734 8686
8735 8687
8736 HValue* HOptimizedGraphBuilder::BuildBinaryOperation( 8688 HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
8737 BinaryOperation* expr, 8689 BinaryOperation* expr,
8738 HValue* left, 8690 HValue* left,
8739 HValue* right) { 8691 HValue* right) {
8740 Handle<Type> left_type = expr->left()->bounds().lower; 8692 Handle<Type> left_type = expr->left()->bounds().lower;
8741 Handle<Type> right_type = expr->right()->bounds().lower; 8693 Handle<Type> right_type = expr->right()->bounds().lower;
8742 Handle<Type> result_type = expr->bounds().lower; 8694 Handle<Type> result_type = expr->bounds().lower;
8743 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 8695 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
8744 Handle<AllocationSite> allocation_site = expr->allocation_site();
8745
8746 HAllocationMode allocation_mode =
8747 FLAG_allocation_site_pretenuring
8748 ? (allocation_site.is_null()
8749 ? HAllocationMode(NOT_TENURED)
8750 : HAllocationMode(allocation_site))
8751 : HAllocationMode(isolate()->heap()->GetPretenureMode());
8752 8696
8753 HValue* result = HGraphBuilder::BuildBinaryOperation( 8697 HValue* result = HGraphBuilder::BuildBinaryOperation(
8754 expr->op(), left, right, left_type, right_type, result_type, 8698 expr->op(), left, right, left_type, right_type,
8755 fixed_right_arg, allocation_mode); 8699 result_type, fixed_right_arg);
8756 // Add a simulate after instructions with observable side effects, and 8700 // Add a simulate after instructions with observable side effects, and
8757 // after phis, which are the result of BuildBinaryOperation when we 8701 // after phis, which are the result of BuildBinaryOperation when we
8758 // inlined some complex subgraph. 8702 // inlined some complex subgraph.
8759 if (result->HasObservableSideEffects() || result->IsPhi()) { 8703 if (result->HasObservableSideEffects() || result->IsPhi()) {
8760 Push(result); 8704 Push(result);
8761 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 8705 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
8762 Drop(1); 8706 Drop(1);
8763 } 8707 }
8764 return result; 8708 return result;
8765 } 8709 }
8766 8710
8767 8711
8768 HValue* HGraphBuilder::BuildBinaryOperation( 8712 HValue* HGraphBuilder::BuildBinaryOperation(
8769 Token::Value op, 8713 Token::Value op,
8770 HValue* left, 8714 HValue* left,
8771 HValue* right, 8715 HValue* right,
8772 Handle<Type> left_type, 8716 Handle<Type> left_type,
8773 Handle<Type> right_type, 8717 Handle<Type> right_type,
8774 Handle<Type> result_type, 8718 Handle<Type> result_type,
8775 Maybe<int> fixed_right_arg, 8719 Maybe<int> fixed_right_arg) {
8776 HAllocationMode allocation_mode) {
8777 8720
8778 Representation left_rep = Representation::FromType(left_type); 8721 Representation left_rep = Representation::FromType(left_type);
8779 Representation right_rep = Representation::FromType(right_type); 8722 Representation right_rep = Representation::FromType(right_type);
8780 8723
8781 bool maybe_string_add = op == Token::ADD && 8724 bool maybe_string_add = op == Token::ADD &&
8782 (left_type->Maybe(Type::String()) || 8725 (left_type->Maybe(Type::String()) ||
8783 right_type->Maybe(Type::String())); 8726 right_type->Maybe(Type::String()));
8784 8727
8785 if (left_type->Is(Type::None())) { 8728 if (left_type->Is(Type::None())) {
8786 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 8729 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8832 ASSERT(left_type->Is(Type::String())); 8775 ASSERT(left_type->Is(Type::String()));
8833 right = BuildNumberToString(right, right_type); 8776 right = BuildNumberToString(right, right_type);
8834 } else if (!right_type->Is(Type::String())) { 8777 } else if (!right_type->Is(Type::String())) {
8835 ASSERT(left_type->Is(Type::String())); 8778 ASSERT(left_type->Is(Type::String()));
8836 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 8779 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
8837 Add<HPushArgument>(left); 8780 Add<HPushArgument>(left);
8838 Add<HPushArgument>(right); 8781 Add<HPushArgument>(right);
8839 return AddUncasted<HInvokeFunction>(function, 2); 8782 return AddUncasted<HInvokeFunction>(function, 2);
8840 } 8783 }
8841 8784
8842 // Inline the string addition into the stub when creating allocation 8785 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE);
8843 // mementos to gather allocation site feedback.
8844 if (graph()->info()->IsStub() &&
8845 allocation_mode.CreateAllocationMementos()) {
8846 return BuildStringAdd(left, right, allocation_mode);
8847 }
8848
8849 // Register the dependent code with the allocation site.
8850 if (!allocation_mode.feedback_site().is_null()) {
8851 ASSERT(!graph()->info()->IsStub());
8852 allocation_mode.feedback_site()->AddDependentCompilationInfo(
8853 AllocationSite::TENURING, top_info());
8854 }
8855
8856 // Inline string addition if we know that we'll create a cons string.
8857 if (left->IsConstant()) {
8858 HConstant* c_left = HConstant::cast(left);
8859 if (c_left->HasStringValue()) {
8860 int c_left_length = c_left->StringValue()->length();
8861 if (c_left_length == 0) {
8862 return right;
8863 } else if (c_left_length + 1 >= ConsString::kMinLength) {
8864 return BuildStringAdd(left, right, allocation_mode);
8865 }
8866 }
8867 }
8868 if (right->IsConstant()) {
8869 HConstant* c_right = HConstant::cast(right);
8870 if (c_right->HasStringValue()) {
8871 int c_right_length = c_right->StringValue()->length();
8872 if (c_right_length == 0) {
8873 return left;
8874 } else if (c_right_length + 1 >= ConsString::kMinLength) {
8875 return BuildStringAdd(left, right, allocation_mode);
8876 }
8877 }
8878 }
8879
8880 // Fallback to using the string add stub.
8881 return AddUncasted<HStringAdd>(
8882 left, right, allocation_mode.GetPretenureMode(),
8883 STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
8884 } 8786 }
8885 8787
8886 if (graph()->info()->IsStub()) { 8788 if (graph()->info()->IsStub()) {
8887 left = EnforceNumberType(left, left_type); 8789 left = EnforceNumberType(left, left_type);
8888 right = EnforceNumberType(right, right_type); 8790 right = EnforceNumberType(right, right_type);
8889 } 8791 }
8890 8792
8891 Representation result_rep = Representation::FromType(result_type); 8793 Representation result_rep = Representation::FromType(result_type);
8892 8794
8893 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 8795 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) ||
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after
10102 } 10004 }
10103 10005
10104 10006
10105 // Fast support for StringAdd. 10007 // Fast support for StringAdd.
10106 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 10008 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
10107 ASSERT_EQ(2, call->arguments()->length()); 10009 ASSERT_EQ(2, call->arguments()->length());
10108 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10010 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10109 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10011 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10110 HValue* right = Pop(); 10012 HValue* right = Pop();
10111 HValue* left = Pop(); 10013 HValue* left = Pop();
10112 HInstruction* result = NewUncasted<HStringAdd>(left, right); 10014 HInstruction* result =
10015 NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH);
10113 return ast_context()->ReturnInstruction(result, call->id()); 10016 return ast_context()->ReturnInstruction(result, call->id());
10114 } 10017 }
10115 10018
10116 10019
10117 // Fast support for SubString. 10020 // Fast support for SubString.
10118 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 10021 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
10119 ASSERT_EQ(3, call->arguments()->length()); 10022 ASSERT_EQ(3, call->arguments()->length());
10120 CHECK_ALIVE(VisitArgumentList(call->arguments())); 10023 CHECK_ALIVE(VisitArgumentList(call->arguments()));
10121 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 10024 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
10122 Drop(3); 10025 Drop(3);
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
10891 if (ShouldProduceTraceOutput()) { 10794 if (ShouldProduceTraceOutput()) {
10892 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10795 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10893 } 10796 }
10894 10797
10895 #ifdef DEBUG 10798 #ifdef DEBUG
10896 graph_->Verify(false); // No full verify. 10799 graph_->Verify(false); // No full verify.
10897 #endif 10800 #endif
10898 } 10801 }
10899 10802
10900 } } // namespace v8::internal 10803 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698