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

Side by Side Diff: src/hydrogen.cc

Issue 148593004: A64: Synchronize with r18084. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "hydrogen-minus-zero.h" 51 #include "hydrogen-minus-zero.h"
52 #include "hydrogen-osr.h" 52 #include "hydrogen-osr.h"
53 #include "hydrogen-range-analysis.h" 53 #include "hydrogen-range-analysis.h"
54 #include "hydrogen-redundant-phi.h" 54 #include "hydrogen-redundant-phi.h"
55 #include "hydrogen-removable-simulates.h" 55 #include "hydrogen-removable-simulates.h"
56 #include "hydrogen-representation-changes.h" 56 #include "hydrogen-representation-changes.h"
57 #include "hydrogen-sce.h" 57 #include "hydrogen-sce.h"
58 #include "hydrogen-uint32-analysis.h" 58 #include "hydrogen-uint32-analysis.h"
59 #include "lithium-allocator.h" 59 #include "lithium-allocator.h"
60 #include "parser.h" 60 #include "parser.h"
61 #include "runtime.h"
61 #include "scopeinfo.h" 62 #include "scopeinfo.h"
62 #include "scopes.h" 63 #include "scopes.h"
63 #include "stub-cache.h" 64 #include "stub-cache.h"
64 #include "typing.h" 65 #include "typing.h"
65 66
66 #if V8_TARGET_ARCH_IA32 67 #if V8_TARGET_ARCH_IA32
67 #include "ia32/lithium-codegen-ia32.h" 68 #include "ia32/lithium-codegen-ia32.h"
68 #elif V8_TARGET_ARCH_X64 69 #elif V8_TARGET_ARCH_X64
69 #include "x64/lithium-codegen-x64.h" 70 #include "x64/lithium-codegen-x64.h"
70 #elif V8_TARGET_ARCH_A64 71 #elif V8_TARGET_ARCH_A64
(...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 set_current_block(NULL); 1191 set_current_block(NULL);
1191 } 1192 }
1192 } 1193 }
1193 1194
1194 1195
1195 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1196 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1196 if (FLAG_native_code_counters && counter->Enabled()) { 1197 if (FLAG_native_code_counters && counter->Enabled()) {
1197 HValue* reference = Add<HConstant>(ExternalReference(counter)); 1198 HValue* reference = Add<HConstant>(ExternalReference(counter));
1198 HValue* old_value = Add<HLoadNamedField>(reference, 1199 HValue* old_value = Add<HLoadNamedField>(reference,
1199 HObjectAccess::ForCounter()); 1200 HObjectAccess::ForCounter());
1200 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); 1201 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
1201 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1202 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
1202 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1203 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1203 new_value); 1204 new_value);
1204 } 1205 }
1205 } 1206 }
1206 1207
1207 1208
1208 void HGraphBuilder::AddSimulate(BailoutId id, 1209 void HGraphBuilder::AddSimulate(BailoutId id,
1209 RemovableSimulate removable) { 1210 RemovableSimulate removable) {
1210 ASSERT(current_block() != NULL); 1211 ASSERT(current_block() != NULL);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 ASSERT(continuation->predecessors()->length() == 0); 1269 ASSERT(continuation->predecessors()->length() == 0);
1269 } 1270 }
1270 } 1271 }
1271 1272
1272 1273
1273 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) { 1274 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
1274 return Add<HCheckMaps>(obj, map, top_info()); 1275 return Add<HCheckMaps>(obj, map, top_info());
1275 } 1276 }
1276 1277
1277 1278
1278 HValue* HGraphBuilder::BuildCheckString( 1279 HValue* HGraphBuilder::BuildCheckString(HValue* string) {
1279 HValue* object, const char* failure_reason) { 1280 if (!string->type().IsString()) {
1280 if (!object->type().IsString()) { 1281 ASSERT(!string->IsConstant() ||
1281 ASSERT(!object->IsConstant() || 1282 !HConstant::cast(string)->HasStringValue());
1282 !HConstant::cast(object)->HasStringValue()); 1283 BuildCheckHeapObject(string);
1283 IfBuilder if_isstring(this); 1284 return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
1284 if_isstring.If<HIsStringAndBranch>(object);
1285 if_isstring.Then();
1286 if_isstring.ElseDeopt(failure_reason);
1287 } 1285 }
1288 return object; 1286 return string;
1289 } 1287 }
1290 1288
1291 1289
1292 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1290 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1293 if (object->type().IsJSObject()) return object; 1291 if (object->type().IsJSObject()) return object;
1294 return Add<HWrapReceiver>(object, function); 1292 return Add<HWrapReceiver>(object, function);
1295 } 1293 }
1296 1294
1297 1295
1298 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1296 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 HValue* elements = AddLoadElements(receiver); 1535 HValue* elements = AddLoadElements(receiver);
1538 1536
1539 HValue* hash = BuildElementIndexHash(key); 1537 HValue* hash = BuildElementIndexHash(key);
1540 1538
1541 HValue* capacity = Add<HLoadKeyed>( 1539 HValue* capacity = Add<HLoadKeyed>(
1542 elements, 1540 elements,
1543 Add<HConstant>(NameDictionary::kCapacityIndex), 1541 Add<HConstant>(NameDictionary::kCapacityIndex),
1544 static_cast<HValue*>(NULL), 1542 static_cast<HValue*>(NULL),
1545 FAST_SMI_ELEMENTS); 1543 FAST_SMI_ELEMENTS);
1546 1544
1547 HValue* mask = Add<HSub>(capacity, graph()->GetConstant1()); 1545 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
1548 mask->ChangeRepresentation(Representation::Integer32()); 1546 mask->ChangeRepresentation(Representation::Integer32());
1549 mask->ClearFlag(HValue::kCanOverflow); 1547 mask->ClearFlag(HValue::kCanOverflow);
1550 1548
1551 return BuildUncheckedDictionaryElementLoadHelper(elements, key, 1549 return BuildUncheckedDictionaryElementLoadHelper(elements, key,
1552 hash, mask, 0); 1550 hash, mask, 0);
1553 } 1551 }
1554 1552
1555 1553
1556 HValue* HGraphBuilder::BuildNumberToString(HValue* object, 1554 HValue* HGraphBuilder::BuildNumberToString(HValue* object,
1557 Handle<Type> type) { 1555 Handle<Type> type) {
(...skipping 11 matching lines...) Expand all
1569 graph()->CreateBasicBlock()); 1567 graph()->CreateBasicBlock());
1570 1568
1571 // Load the number string cache. 1569 // Load the number string cache.
1572 HValue* number_string_cache = 1570 HValue* number_string_cache =
1573 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex); 1571 Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
1574 1572
1575 // Make the hash mask from the length of the number string cache. It 1573 // Make the hash mask from the length of the number string cache. It
1576 // contains two elements (number and string) for each cache entry. 1574 // contains two elements (number and string) for each cache entry.
1577 HValue* mask = AddLoadFixedArrayLength(number_string_cache); 1575 HValue* mask = AddLoadFixedArrayLength(number_string_cache);
1578 mask->set_type(HType::Smi()); 1576 mask->set_type(HType::Smi());
1579 mask = Add<HSar>(mask, graph()->GetConstant1()); 1577 mask = AddUncasted<HSar>(mask, graph()->GetConstant1());
1580 mask = Add<HSub>(mask, graph()->GetConstant1()); 1578 mask = AddUncasted<HSub>(mask, graph()->GetConstant1());
1581 1579
1582 // Check whether object is a smi. 1580 // Check whether object is a smi.
1583 IfBuilder if_objectissmi(this); 1581 IfBuilder if_objectissmi(this);
1584 if_objectissmi.If<HIsSmiAndBranch>(object); 1582 if_objectissmi.If<HIsSmiAndBranch>(object);
1585 if_objectissmi.Then(); 1583 if_objectissmi.Then();
1586 { 1584 {
1587 // Compute hash for smi similar to smi_get_hash(). 1585 // Compute hash for smi similar to smi_get_hash().
1588 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); 1586 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask);
1589 1587
1590 // Load the key. 1588 // Load the key.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 HValue* dst, 1712 HValue* dst,
1715 HValue* dst_offset, 1713 HValue* dst_offset,
1716 String::Encoding dst_encoding, 1714 String::Encoding dst_encoding,
1717 HValue* length) { 1715 HValue* length) {
1718 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING || 1716 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
1719 src_encoding == String::ONE_BYTE_ENCODING); 1717 src_encoding == String::ONE_BYTE_ENCODING);
1720 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 1718 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
1721 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 1719 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
1722 { 1720 {
1723 HValue* src_index = AddUncasted<HAdd>(src_offset, index); 1721 HValue* src_index = AddUncasted<HAdd>(src_offset, index);
1724 HValue* value = Add<HSeqStringGetChar>(src_encoding, src, src_index); 1722 HValue* value =
1723 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index);
1725 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 1724 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index);
1726 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 1725 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
1727 } 1726 }
1728 loop.EndBody(); 1727 loop.EndBody();
1729 } 1728 }
1730 1729
1731 1730
1732 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left, 1731 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
1733 HValue* right, 1732 HValue* right,
1734 PretenureFlag pretenure_flag) { 1733 PretenureFlag pretenure_flag) {
1735 // Determine the string lengths. 1734 // Determine the string lengths.
1736 HValue* left_length = Add<HLoadNamedField>( 1735 HValue* left_length = Add<HLoadNamedField>(
1737 left, HObjectAccess::ForStringLength()); 1736 left, HObjectAccess::ForStringLength());
1738 HValue* right_length = Add<HLoadNamedField>( 1737 HValue* right_length = Add<HLoadNamedField>(
1739 right, HObjectAccess::ForStringLength()); 1738 right, HObjectAccess::ForStringLength());
1740 1739
1741 // Check if we concatenated the strings here, or if we have to resort to the 1740 // Compute the combined string length. If the result is larger than the max
1742 // runtime function. 1741 // supported string length, we bailout to the runtime. This is done implicitly
1743 HIfContinuation handled(graph()->CreateBasicBlock(), 1742 // when converting the result back to a smi in case the max string length
1744 graph()->CreateBasicBlock()); 1743 // equals the max smi valie. Otherwise, for platforms with 32-bit smis, we do
1745 1744 HValue* length = AddUncasted<HAdd>(left_length, right_length);
1746 // Check if both parameters do not exceed half the max string length, because 1745 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
1747 // exceptionally long strings should be handled in the runtime. Unfortunately 1746 if (String::kMaxLength != Smi::kMaxValue) {
1748 // we cannot actually check whether the combined length of both strings 1747 IfBuilder if_nooverflow(this);
1749 // exceeds String::kMaxLength (because of unclear results from the 1748 if_nooverflow.If<HCompareNumericAndBranch>(
1750 // representation inference phase), so we use a pessimistic approach here 1749 length, Add<HConstant>(String::kMaxLength), Token::LTE);
1751 // instead, checking that the length of either substring does not exceed half 1750 if_nooverflow.Then();
1752 // of String::kMaxLength. 1751 if_nooverflow.ElseDeopt("String length exceeds limit");
1753 HConstant* max_length = Add<HConstant>(String::kMaxLength / 2); 1752 }
1754 IfBuilder if_nooverflow(this); 1753
1755 if_nooverflow.If<HCompareNumericAndBranch>( 1754 // Determine the string instance types.
1756 left_length, max_length, Token::LTE); 1755 HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
1757 if_nooverflow.AndIf<HCompareNumericAndBranch>( 1756 Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
1758 right_length, max_length, Token::LTE); 1757 HObjectAccess::ForMapInstanceType());
1759 if_nooverflow.Then(); 1758 HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
1759 Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
1760 HObjectAccess::ForMapInstanceType());
1761
1762 // Compute difference of instance types.
1763 HValue* xored_instance_types = AddUncasted<HBitwise>(
1764 Token::BIT_XOR, left_instance_type, right_instance_type);
1765
1766 // Check if we should create a cons string.
1767 IfBuilder if_createcons(this);
1768 if_createcons.If<HCompareNumericAndBranch>(
1769 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
1770 if_createcons.Then();
1760 { 1771 {
1761 // Determine the string instance types. 1772 // Allocate the cons string object. HAllocate does not care whether we
1762 HLoadNamedField* left_instance_type = Add<HLoadNamedField>( 1773 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1763 Add<HLoadNamedField>(left, HObjectAccess::ForMap()), 1774 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1764 HObjectAccess::ForMapInstanceType()); 1775 // one-byte or two-byte and set the appropriate map.
1765 HLoadNamedField* right_instance_type = Add<HLoadNamedField>( 1776 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
1766 Add<HLoadNamedField>(right, HObjectAccess::ForMap()), 1777 HType::String(), pretenure_flag,
1767 HObjectAccess::ForMapInstanceType()); 1778 CONS_STRING_TYPE);
1768 1779
1769 // Compute difference of instance types. 1780 // Compute the intersection of instance types.
1770 HValue* xored_instance_types = AddUncasted<HBitwise>( 1781 HValue* anded_instance_types = AddUncasted<HBitwise>(
1771 Token::BIT_XOR, left_instance_type, right_instance_type); 1782 Token::BIT_AND, left_instance_type, right_instance_type);
1772 1783
1773 // Compute the length of the resulting string. 1784 // We create a one-byte cons string if
1774 HValue* length = AddUncasted<HAdd>(left_length, right_length); 1785 // 1. both strings are one-byte, or
1775 1786 // 2. at least one of the strings is two-byte, but happens to contain only
1776 // Check if we should create a cons string. 1787 // one-byte characters.
1777 IfBuilder if_createcons(this); 1788 // To do this, we check
1778 if_createcons.If<HCompareNumericAndBranch>( 1789 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1779 length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 1790 // both strings, or
1780 if_createcons.Then(); 1791 // 2. if one of the strings has the one-byte data hint set and the other
1781 { 1792 // string is one-byte.
1782 // Allocate the cons string object. HAllocate does not care whether we 1793 IfBuilder if_onebyte(this);
1783 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use 1794 STATIC_ASSERT(kOneByteStringTag != 0);
1784 // CONS_STRING_TYPE here. Below we decide whether the cons string is 1795 STATIC_ASSERT(kOneByteDataHintMask != 0);
1785 // one-byte or two-byte and set the appropriate map. 1796 if_onebyte.If<HCompareNumericAndBranch>(
1786 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize), 1797 AddUncasted<HBitwise>(
1787 HType::String(), pretenure_flag, 1798 Token::BIT_AND, anded_instance_types,
1788 CONS_STRING_TYPE); 1799 Add<HConstant>(static_cast<int32_t>(
1789 1800 kStringEncodingMask | kOneByteDataHintMask))),
1790 // Compute the intersection of instance types. 1801 graph()->GetConstant0(), Token::NE);
1791 HValue* anded_instance_types = AddUncasted<HBitwise>( 1802 if_onebyte.Or();
1792 Token::BIT_AND, left_instance_type, right_instance_type); 1803 STATIC_ASSERT(kOneByteStringTag != 0 &&
1793 1804 kOneByteDataHintTag != 0 &&
1794 // We create a one-byte cons string if 1805 kOneByteDataHintTag != kOneByteStringTag);
1795 // 1. both strings are one-byte, or 1806 if_onebyte.If<HCompareNumericAndBranch>(
1796 // 2. at least one of the strings is two-byte, but happens to contain only 1807 AddUncasted<HBitwise>(
1797 // one-byte characters. 1808 Token::BIT_AND, xored_instance_types,
1798 // To do this, we check 1809 Add<HConstant>(static_cast<int32_t>(
1799 // 1. if both strings are one-byte, or if the one-byte data hint is set in 1810 kOneByteStringTag | kOneByteDataHintTag))),
1800 // both strings, or 1811 Add<HConstant>(static_cast<int32_t>(
1801 // 2. if one of the strings has the one-byte data hint set and the other 1812 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1802 // string is one-byte. 1813 if_onebyte.Then();
1814 {
1815 // We can safely skip the write barrier for storing the map here.
1816 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1817 AddStoreMapConstantNoWriteBarrier(string, map);
1818 }
1819 if_onebyte.Else();
1820 {
1821 // We can safely skip the write barrier for storing the map here.
1822 Handle<Map> map = isolate()->factory()->cons_string_map();
1823 AddStoreMapConstantNoWriteBarrier(string, map);
1824 }
1825 if_onebyte.End();
1826
1827 // Initialize the cons string fields.
1828 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1829 Add<HConstant>(String::kEmptyHashField));
1830 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
1831 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
1832 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
1833 right);
1834
1835 // Count the native string addition.
1836 AddIncrementCounter(isolate()->counters()->string_add_native());
1837
1838 // Cons string is result.
1839 Push(string);
1840 }
1841 if_createcons.Else();
1842 {
1843 // Compute union of instance types.
1844 HValue* ored_instance_types = AddUncasted<HBitwise>(
1845 Token::BIT_OR, left_instance_type, right_instance_type);
1846
1847 // Check if both strings have the same encoding and both are
1848 // sequential.
1849 IfBuilder if_sameencodingandsequential(this);
1850 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1851 AddUncasted<HBitwise>(
1852 Token::BIT_AND, xored_instance_types,
1853 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1854 graph()->GetConstant0(), Token::EQ);
1855 if_sameencodingandsequential.And();
1856 STATIC_ASSERT(kSeqStringTag == 0);
1857 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1858 AddUncasted<HBitwise>(
1859 Token::BIT_AND, ored_instance_types,
1860 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1861 graph()->GetConstant0(), Token::EQ);
1862 if_sameencodingandsequential.Then();
1863 {
1864 // Check if the result is a one-byte string.
1803 IfBuilder if_onebyte(this); 1865 IfBuilder if_onebyte(this);
1804 STATIC_ASSERT(kOneByteStringTag != 0); 1866 STATIC_ASSERT(kOneByteStringTag != 0);
1805 STATIC_ASSERT(kOneByteDataHintMask != 0);
1806 if_onebyte.If<HCompareNumericAndBranch>( 1867 if_onebyte.If<HCompareNumericAndBranch>(
1807 AddUncasted<HBitwise>( 1868 AddUncasted<HBitwise>(
1808 Token::BIT_AND, anded_instance_types, 1869 Token::BIT_AND, ored_instance_types,
1809 Add<HConstant>(static_cast<int32_t>( 1870 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1810 kStringEncodingMask | kOneByteDataHintMask))),
1811 graph()->GetConstant0(), Token::NE); 1871 graph()->GetConstant0(), Token::NE);
1812 if_onebyte.Or();
1813 STATIC_ASSERT(kOneByteStringTag != 0 &&
1814 kOneByteDataHintTag != 0 &&
1815 kOneByteDataHintTag != kOneByteStringTag);
1816 if_onebyte.If<HCompareNumericAndBranch>(
1817 AddUncasted<HBitwise>(
1818 Token::BIT_AND, xored_instance_types,
1819 Add<HConstant>(static_cast<int32_t>(
1820 kOneByteStringTag | kOneByteDataHintTag))),
1821 Add<HConstant>(static_cast<int32_t>(
1822 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1823 if_onebyte.Then(); 1872 if_onebyte.Then();
1824 { 1873 {
1825 // We can safely skip the write barrier for storing the map here. 1874 // Calculate the number of bytes needed for the characters in the
1826 Handle<Map> map = isolate()->factory()->cons_ascii_string_map(); 1875 // string while observing object alignment.
1876 HValue* size = BuildSeqStringSizeFor(
1877 length, String::ONE_BYTE_ENCODING);
1878
1879 // Allocate the ASCII string object.
1880 Handle<Map> map = isolate()->factory()->ascii_string_map();
1881 HAllocate* string = Add<HAllocate>(size, HType::String(),
1882 pretenure_flag, ASCII_STRING_TYPE);
1883 string->set_known_initial_map(map);
1884
1885 // We can safely skip the write barrier for storing map here.
1827 AddStoreMapConstantNoWriteBarrier(string, map); 1886 AddStoreMapConstantNoWriteBarrier(string, map);
1887
1888 // Length must be stored into the string before we copy characters to
1889 // make debug verification code happy.
1890 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1891 length);
1892
1893 // Copy bytes from the left string.
1894 BuildCopySeqStringChars(
1895 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1896 string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1897 left_length);
1898
1899 // Copy bytes from the right string.
1900 BuildCopySeqStringChars(
1901 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1902 string, left_length, String::ONE_BYTE_ENCODING,
1903 right_length);
1904
1905 // Count the native string addition.
1906 AddIncrementCounter(isolate()->counters()->string_add_native());
1907
1908 // Return the string.
1909 Push(string);
1828 } 1910 }
1829 if_onebyte.Else(); 1911 if_onebyte.Else();
1830 { 1912 {
1831 // We can safely skip the write barrier for storing the map here. 1913 // Calculate the number of bytes needed for the characters in the
1832 Handle<Map> map = isolate()->factory()->cons_string_map(); 1914 // string while observing object alignment.
1915 HValue* size = BuildSeqStringSizeFor(
1916 length, String::TWO_BYTE_ENCODING);
1917
1918 // Allocate the two-byte string object.
1919 Handle<Map> map = isolate()->factory()->string_map();
1920 HAllocate* string = Add<HAllocate>(size, HType::String(),
1921 pretenure_flag, STRING_TYPE);
1922 string->set_known_initial_map(map);
1923
1924 // We can safely skip the write barrier for storing map here.
1833 AddStoreMapConstantNoWriteBarrier(string, map); 1925 AddStoreMapConstantNoWriteBarrier(string, map);
1926
1927 // Length must be stored into the string before we copy characters to
1928 // make debug verification code happy.
1929 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1930 length);
1931
1932 // Copy bytes from the left string.
1933 BuildCopySeqStringChars(
1934 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1935 string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1936 left_length);
1937
1938 // Copy bytes from the right string.
1939 BuildCopySeqStringChars(
1940 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1941 string, left_length, String::TWO_BYTE_ENCODING,
1942 right_length);
1943
1944 // Return the string.
1945 Push(string);
1834 } 1946 }
1835 if_onebyte.End(); 1947 if_onebyte.End();
1836 1948
1837 // Initialize the cons string fields. 1949 // Initialize the (common) string fields.
1950 HValue* string = Pop();
1838 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(), 1951 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1839 Add<HConstant>(String::kEmptyHashField)); 1952 Add<HConstant>(String::kEmptyHashField));
1840 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length); 1953
1841 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left); 1954 // Count the native string addition.
1842 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(), 1955 AddIncrementCounter(isolate()->counters()->string_add_native());
1843 right); 1956
1844
1845 // Cons string is result.
1846 Push(string); 1957 Push(string);
1847 } 1958 }
1848 if_createcons.Else(); 1959 if_sameencodingandsequential.Else();
1849 { 1960 {
1850 // Compute union of instance types. 1961 // Fallback to the runtime to add the two strings.
1851 HValue* ored_instance_types = AddUncasted<HBitwise>( 1962 Add<HPushArgument>(left);
1852 Token::BIT_OR, left_instance_type, right_instance_type); 1963 Add<HPushArgument>(right);
1853 1964 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
1854 // Check if both strings have the same encoding and both are 1965 Runtime::FunctionForId(Runtime::kStringAdd),
1855 // sequential. 1966 2));
1856 IfBuilder if_sameencodingandsequential(this); 1967 }
1857 if_sameencodingandsequential.If<HCompareNumericAndBranch>( 1968 if_sameencodingandsequential.End();
1858 AddUncasted<HBitwise>(
1859 Token::BIT_AND, xored_instance_types,
1860 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1861 graph()->GetConstant0(), Token::EQ);
1862 if_sameencodingandsequential.And();
1863 STATIC_ASSERT(kSeqStringTag == 0);
1864 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1865 AddUncasted<HBitwise>(
1866 Token::BIT_AND, ored_instance_types,
1867 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1868 graph()->GetConstant0(), Token::EQ);
1869 if_sameencodingandsequential.Then();
1870 {
1871 // Check if the result is a one-byte string.
1872 IfBuilder if_onebyte(this);
1873 STATIC_ASSERT(kOneByteStringTag != 0);
1874 if_onebyte.If<HCompareNumericAndBranch>(
1875 AddUncasted<HBitwise>(
1876 Token::BIT_AND, ored_instance_types,
1877 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1878 graph()->GetConstant0(), Token::NE);
1879 if_onebyte.Then();
1880 {
1881 // Calculate the number of bytes needed for the characters in the
1882 // string while observing object alignment.
1883 HValue* size = BuildSeqStringSizeFor(
1884 length, String::ONE_BYTE_ENCODING);
1885
1886 // Allocate the ASCII string object.
1887 Handle<Map> map = isolate()->factory()->ascii_string_map();
1888 HAllocate* string = Add<HAllocate>(size, HType::String(),
1889 pretenure_flag, ASCII_STRING_TYPE);
1890 string->set_known_initial_map(map);
1891
1892 // We can safely skip the write barrier for storing map here.
1893 AddStoreMapConstantNoWriteBarrier(string, map);
1894
1895 // Length must be stored into the string before we copy characters to
1896 // make debug verification code happy.
1897 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1898 length);
1899
1900 // Copy bytes from the left string.
1901 BuildCopySeqStringChars(
1902 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1903 string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1904 left_length);
1905
1906 // Copy bytes from the right string.
1907 BuildCopySeqStringChars(
1908 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1909 string, left_length, String::ONE_BYTE_ENCODING,
1910 right_length);
1911
1912 // Return the string.
1913 Push(string);
1914 }
1915 if_onebyte.Else();
1916 {
1917 // Calculate the number of bytes needed for the characters in the
1918 // string while observing object alignment.
1919 HValue* size = BuildSeqStringSizeFor(
1920 length, String::TWO_BYTE_ENCODING);
1921
1922 // Allocate the two-byte string object.
1923 Handle<Map> map = isolate()->factory()->string_map();
1924 HAllocate* string = Add<HAllocate>(size, HType::String(),
1925 pretenure_flag, STRING_TYPE);
1926 string->set_known_initial_map(map);
1927
1928 // We can safely skip the write barrier for storing map here.
1929 AddStoreMapConstantNoWriteBarrier(string, map);
1930
1931 // Length must be stored into the string before we copy characters to
1932 // make debug verification code happy.
1933 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1934 length);
1935
1936 // Copy bytes from the left string.
1937 BuildCopySeqStringChars(
1938 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1939 string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1940 left_length);
1941
1942 // Copy bytes from the right string.
1943 BuildCopySeqStringChars(
1944 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1945 string, left_length, String::TWO_BYTE_ENCODING,
1946 right_length);
1947
1948 // Return the string.
1949 Push(string);
1950 }
1951 if_onebyte.End();
1952
1953 // Initialize the (common) string fields.
1954 HValue* string = Pop();
1955 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1956 Add<HConstant>(String::kEmptyHashField));
1957 Push(string);
1958 }
1959 if_sameencodingandsequential.JoinContinuation(&handled);
1960 }
1961 if_createcons.JoinContinuation(&handled);
1962 } 1969 }
1963 if_nooverflow.JoinContinuation(&handled); 1970 if_createcons.End();
1964
1965 // Check if the strings were concatenated successfully, otherwise fallback to
1966 // add the strings in the runtime.
1967 IfBuilder if_handled(this, &handled);
1968 if_handled.Then();
1969 {
1970 // Count the native string addition.
1971 AddIncrementCounter(isolate()->counters()->string_add_native());
1972 }
1973 if_handled.Else();
1974 {
1975 // Fallback to the runtime to add the two strings.
1976 Add<HPushArgument>(left);
1977 Add<HPushArgument>(right);
1978 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
1979 Runtime::FunctionForId(Runtime::kStringAdd),
1980 2));
1981 }
1982 if_handled.End();
1983 1971
1984 return Pop(); 1972 return Pop();
1985 } 1973 }
1986 1974
1987 1975
1988 HValue* HGraphBuilder::BuildStringAdd(HValue* left, 1976 HValue* HGraphBuilder::BuildStringAdd(HValue* left,
1989 HValue* right, 1977 HValue* right,
1990 PretenureFlag pretenure_flag) { 1978 PretenureFlag pretenure_flag) {
1991 // Determine the string lengths. 1979 // Determine the string lengths.
1992 HValue* left_length = Add<HLoadNamedField>( 1980 HValue* left_length = Add<HLoadNamedField>(
(...skipping 3122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5115 AllocationSiteUsageContext usage_context(isolate(), site, false); 5103 AllocationSiteUsageContext usage_context(isolate(), site, false);
5116 usage_context.EnterNewScope(); 5104 usage_context.EnterNewScope();
5117 literal = BuildFastLiteral(boilerplate_object, &usage_context); 5105 literal = BuildFastLiteral(boilerplate_object, &usage_context);
5118 usage_context.ExitScope(site, boilerplate_object); 5106 usage_context.ExitScope(site, boilerplate_object);
5119 } else { 5107 } else {
5120 NoObservableSideEffectsScope no_effects(this); 5108 NoObservableSideEffectsScope no_effects(this);
5121 // Boilerplate already exists and constant elements are never accessed, 5109 // Boilerplate already exists and constant elements are never accessed,
5122 // pass an empty fixed array to the runtime function instead. 5110 // pass an empty fixed array to the runtime function instead.
5123 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 5111 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
5124 int literal_index = expr->literal_index(); 5112 int literal_index = expr->literal_index();
5113 int flags = expr->depth() == 1
5114 ? ArrayLiteral::kShallowElements
5115 : ArrayLiteral::kNoFlags;
5116 flags |= ArrayLiteral::kDisableMementos;
5125 5117
5126 Add<HPushArgument>(Add<HConstant>(literals)); 5118 Add<HPushArgument>(Add<HConstant>(literals));
5127 Add<HPushArgument>(Add<HConstant>(literal_index)); 5119 Add<HPushArgument>(Add<HConstant>(literal_index));
5128 Add<HPushArgument>(Add<HConstant>(constants)); 5120 Add<HPushArgument>(Add<HConstant>(constants));
5121 Add<HPushArgument>(Add<HConstant>(flags));
5129 5122
5130 // TODO(mvstanton): Consider a flag to turn off creation of any 5123 // TODO(mvstanton): Consider a flag to turn off creation of any
5131 // AllocationMementos for this call: we are in crankshaft and should have 5124 // AllocationMementos for this call: we are in crankshaft and should have
5132 // learned enough about transition behavior to stop emitting mementos. 5125 // learned enough about transition behavior to stop emitting mementos.
5133 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; 5126 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
5134 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5127 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5135 Runtime::FunctionForId(function_id), 5128 Runtime::FunctionForId(function_id),
5136 3); 5129 4);
5137 5130
5138 // De-opt if elements kind changed from boilerplate_elements_kind. 5131 // De-opt if elements kind changed from boilerplate_elements_kind.
5139 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 5132 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
5140 literal = Add<HCheckMaps>(literal, map, top_info()); 5133 literal = Add<HCheckMaps>(literal, map, top_info());
5141 } 5134 }
5142 5135
5143 // The array is expected in the bailout environment during computation 5136 // The array is expected in the bailout environment during computation
5144 // of the property values and is the value of the entire expression. 5137 // of the property values and is the value of the entire expression.
5145 Push(literal); 5138 Push(literal);
5146 // The literal index is on the stack, too. 5139 // The literal index is on the stack, too.
(...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after
7501 } 7494 }
7502 } 7495 }
7503 7496
7504 if (result == NULL) { 7497 if (result == NULL) {
7505 result = NewUncasted<HPower>(left, right); 7498 result = NewUncasted<HPower>(left, right);
7506 } 7499 }
7507 ast_context()->ReturnInstruction(result, expr->id()); 7500 ast_context()->ReturnInstruction(result, expr->id());
7508 return true; 7501 return true;
7509 } 7502 }
7510 break; 7503 break;
7511 case kMathRandom:
7512 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) {
7513 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7514 Drop(1); // Receiver.
7515 HGlobalObject* global_object = Add<HGlobalObject>();
7516 HRandom* result = New<HRandom>(global_object);
7517 ast_context()->ReturnInstruction(result, expr->id());
7518 return true;
7519 }
7520 break;
7521 case kMathMax: 7504 case kMathMax:
7522 case kMathMin: 7505 case kMathMin:
7523 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { 7506 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) {
7524 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7507 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
7525 HValue* right = Pop(); 7508 HValue* right = Pop();
7526 HValue* left = Pop(); 7509 HValue* left = Pop();
7527 Drop(1); // Receiver. 7510 Drop(1); // Receiver.
7528 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin 7511 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin
7529 : HMathMinMax::kMathMax; 7512 : HMathMinMax::kMathMax;
7530 HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); 7513 HInstruction* result = NewUncasted<HMathMinMax>(left, right, op);
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
8090 &HOptimizedGraphBuilder::Generate##Name, 8073 &HOptimizedGraphBuilder::Generate##Name,
8091 8074
8092 const HOptimizedGraphBuilder::InlineFunctionGenerator 8075 const HOptimizedGraphBuilder::InlineFunctionGenerator
8093 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { 8076 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = {
8094 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 8077 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
8095 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 8078 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
8096 }; 8079 };
8097 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 8080 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
8098 8081
8099 8082
8083 template <class ViewClass>
8084 void HGraphBuilder::BuildArrayBufferViewInitialization(
8085 HValue* obj,
8086 HValue* buffer,
8087 HValue* byte_offset,
8088 HValue* byte_length) {
8089
8090 for (int offset = ViewClass::kSize;
8091 offset < ViewClass::kSizeWithInternalFields;
8092 offset += kPointerSize) {
8093 Add<HStoreNamedField>(obj,
8094 HObjectAccess::ForJSObjectOffset(offset),
8095 Add<HConstant>(static_cast<int32_t>(0)));
8096 }
8097
8098 Add<HStoreNamedField>(
8099 obj,
8100 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
8101 Add<HStoreNamedField>(
8102 obj,
8103 HObjectAccess::ForJSArrayBufferViewByteOffset(),
8104 byte_offset);
8105 Add<HStoreNamedField>(
8106 obj,
8107 HObjectAccess::ForJSArrayBufferViewByteLength(),
8108 byte_length);
8109
8110 HObjectAccess weak_first_view_access =
8111 HObjectAccess::ForJSArrayBufferWeakFirstView();
8112 Add<HStoreNamedField>(obj,
8113 HObjectAccess::ForJSArrayBufferViewWeakNext(),
8114 Add<HLoadNamedField>(buffer, weak_first_view_access));
8115 Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
8116 }
8117
8118
8100 void HOptimizedGraphBuilder::VisitDataViewInitialize( 8119 void HOptimizedGraphBuilder::VisitDataViewInitialize(
8101 CallRuntime* expr) { 8120 CallRuntime* expr) {
8102 ZoneList<Expression*>* arguments = expr->arguments(); 8121 ZoneList<Expression*>* arguments = expr->arguments();
8103 8122
8104 NoObservableSideEffectsScope scope(this); 8123 NoObservableSideEffectsScope scope(this);
8105 ASSERT(arguments->length()== 4); 8124 ASSERT(arguments->length()== 4);
8106 CHECK_ALIVE(VisitForValue(arguments->at(0))); 8125 CHECK_ALIVE(VisitForValue(arguments->at(0)));
8107 HValue* obj = Pop(); 8126 HValue* obj = Pop();
8108 8127
8109 CHECK_ALIVE(VisitForValue(arguments->at(1))); 8128 CHECK_ALIVE(VisitForValue(arguments->at(1)));
8110 HValue* buffer = Pop(); 8129 HValue* buffer = Pop();
8111 8130
8112 CHECK_ALIVE(VisitForValue(arguments->at(2))); 8131 CHECK_ALIVE(VisitForValue(arguments->at(2)));
8113 HValue* byte_offset = Pop(); 8132 HValue* byte_offset = Pop();
8114 8133
8115 CHECK_ALIVE(VisitForValue(arguments->at(3))); 8134 CHECK_ALIVE(VisitForValue(arguments->at(3)));
8116 HValue* byte_length = Pop(); 8135 HValue* byte_length = Pop();
8117 8136
8118 for (int offset = JSDataView::kSize; 8137 BuildArrayBufferViewInitialization<JSDataView>(
8119 offset < JSDataView::kSizeWithInternalFields; 8138 obj, buffer, byte_offset, byte_length);
8120 offset += kPointerSize) {
8121 Add<HStoreNamedField>(obj,
8122 HObjectAccess::ForJSObjectOffset(offset),
8123 Add<HConstant>(static_cast<int32_t>(0)));
8124 }
8125
8126 Add<HStoreNamedField>(obj,
8127 HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer);
8128 Add<HStoreNamedField>(obj,
8129 HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset),
8130 byte_offset);
8131 Add<HStoreNamedField>(obj,
8132 HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset),
8133 byte_length);
8134
8135 Add<HStoreNamedField>(obj,
8136 HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset),
8137 Add<HLoadNamedField>(buffer,
8138 HObjectAccess::ForJSObjectOffset(
8139 JSArrayBuffer::kWeakFirstViewOffset)));
8140 Add<HStoreNamedField>(buffer,
8141 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset),
8142 obj);
8143 } 8139 }
8144 8140
8145 8141
8142 void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
8143 CallRuntime* expr) {
8144 ZoneList<Expression*>* arguments = expr->arguments();
8145
8146 NoObservableSideEffectsScope scope(this);
8147 static const int kObjectArg = 0;
8148 static const int kArrayIdArg = 1;
8149 static const int kBufferArg = 2;
8150 static const int kByteOffsetArg = 3;
8151 static const int kByteLengthArg = 4;
8152 static const int kArgsLength = 5;
8153 ASSERT(arguments->length() == kArgsLength);
8154
8155
8156 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg)));
8157 HValue* obj = Pop();
8158
8159 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral);
8160 Handle<Object> value =
8161 static_cast<Literal*>(arguments->at(kArrayIdArg))->value();
8162 ASSERT(value->IsSmi());
8163 int array_id = Smi::cast(*value)->value();
8164
8165 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg)));
8166 HValue* buffer = Pop();
8167
8168 HValue* byte_offset;
8169 bool is_zero_byte_offset;
8170
8171 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral
8172 && Smi::FromInt(0) ==
8173 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) {
8174 byte_offset = Add<HConstant>(static_cast<int32_t>(0));
8175 is_zero_byte_offset = true;
8176 } else {
8177 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg)));
8178 byte_offset = Pop();
8179 is_zero_byte_offset = false;
8180 }
8181
8182 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
8183 HValue* byte_length = Pop();
8184
8185 IfBuilder byte_offset_smi(this);
8186
8187 if (!is_zero_byte_offset) {
8188 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
8189 byte_offset_smi.Then();
8190 }
8191
8192 { // byte_offset is Smi.
8193 BuildArrayBufferViewInitialization<JSTypedArray>(
8194 obj, buffer, byte_offset, byte_length);
8195
8196 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization.
8197 size_t element_size = 1; // Bogus initialization.
8198 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size);
8199
8200 HInstruction* length = AddUncasted<HDiv>(byte_length,
8201 Add<HConstant>(static_cast<int32_t>(element_size)));
8202
8203 Add<HStoreNamedField>(obj,
8204 HObjectAccess::ForJSTypedArrayLength(),
8205 length);
8206
8207 HValue* elements =
8208 Add<HAllocate>(
8209 Add<HConstant>(ExternalArray::kAlignedSize),
8210 HType::JSArray(),
8211 NOT_TENURED,
8212 static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type));
8213
8214 Handle<Map> external_array_map(
8215 isolate()->heap()->MapForExternalArrayType(array_type));
8216 Add<HStoreNamedField>(elements,
8217 HObjectAccess::ForMap(),
8218 Add<HConstant>(external_array_map));
8219
8220 HValue* backing_store = Add<HLoadNamedField>(
8221 buffer, HObjectAccess::ForJSArrayBufferBackingStore());
8222
8223 HValue* typed_array_start;
8224 if (is_zero_byte_offset) {
8225 typed_array_start = backing_store;
8226 } else {
8227 HInstruction* external_pointer =
8228 AddUncasted<HAdd>(backing_store, byte_offset);
8229 // Arguments are checked prior to call to TypedArrayInitialize,
8230 // including byte_offset.
8231 external_pointer->ClearFlag(HValue::kCanOverflow);
8232 typed_array_start = external_pointer;
8233 }
8234
8235 Add<HStoreNamedField>(elements,
8236 HObjectAccess::ForExternalArrayExternalPointer(),
8237 typed_array_start);
8238 Add<HStoreNamedField>(elements,
8239 HObjectAccess::ForFixedArrayLength(),
8240 length);
8241 Add<HStoreNamedField>(
8242 obj, HObjectAccess::ForElementsPointer(), elements);
8243 }
8244
8245 if (!is_zero_byte_offset) {
8246 byte_offset_smi.Else();
8247 { // byte_offset is not Smi.
8248 Push(Add<HPushArgument>(obj));
8249 VisitArgument(arguments->at(kArrayIdArg));
8250 Push(Add<HPushArgument>(buffer));
8251 Push(Add<HPushArgument>(byte_offset));
8252 Push(Add<HPushArgument>(byte_length));
8253 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
8254 Drop(kArgsLength);
8255 }
8256 }
8257 byte_offset_smi.End();
8258 }
8259
8260
8146 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 8261 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
8147 ASSERT(!HasStackOverflow()); 8262 ASSERT(!HasStackOverflow());
8148 ASSERT(current_block() != NULL); 8263 ASSERT(current_block() != NULL);
8149 ASSERT(current_block()->HasPredecessor()); 8264 ASSERT(current_block()->HasPredecessor());
8150 if (expr->is_jsruntime()) { 8265 if (expr->is_jsruntime()) {
8151 return Bailout(kCallToAJavaScriptRuntimeFunction); 8266 return Bailout(kCallToAJavaScriptRuntimeFunction);
8152 } 8267 }
8153 8268
8154 const Runtime::Function* function = expr->function(); 8269 const Runtime::Function* function = expr->function();
8155 ASSERT(function != NULL); 8270 ASSERT(function != NULL);
8156 8271
8157 if (function->function_id == Runtime::kDataViewInitialize) { 8272 if (function->function_id == Runtime::kDataViewInitialize) {
8158 return VisitDataViewInitialize(expr); 8273 return VisitDataViewInitialize(expr);
8159 } 8274 }
8160 8275
8276 if (function->function_id == Runtime::kTypedArrayInitialize) {
8277 return VisitTypedArrayInitialize(expr);
8278 }
8279
8280 if (function->function_id == Runtime::kMaxSmi) {
8281 ASSERT(expr->arguments()->length() == 0);
8282 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue));
8283 return ast_context()->ReturnInstruction(max_smi, expr->id());
8284 }
8285
8161 if (function->intrinsic_type == Runtime::INLINE) { 8286 if (function->intrinsic_type == Runtime::INLINE) {
8162 ASSERT(expr->name()->length() > 0); 8287 ASSERT(expr->name()->length() > 0);
8163 ASSERT(expr->name()->Get(0) == '_'); 8288 ASSERT(expr->name()->Get(0) == '_');
8164 // Call to an inline function. 8289 // Call to an inline function.
8165 int lookup_index = static_cast<int>(function->function_id) - 8290 int lookup_index = static_cast<int>(function->function_id) -
8166 static_cast<int>(Runtime::kFirstInlineFunction); 8291 static_cast<int>(Runtime::kFirstInlineFunction);
8167 ASSERT(lookup_index >= 0); 8292 ASSERT(lookup_index >= 0);
8168 ASSERT(static_cast<size_t>(lookup_index) < 8293 ASSERT(static_cast<size_t>(lookup_index) <
8169 ARRAY_SIZE(kInlineFunctionGenerators)); 8294 ARRAY_SIZE(kInlineFunctionGenerators));
8170 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 8295 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
8634 } 8759 }
8635 8760
8636 8761
8637 HValue* HGraphBuilder::BuildBinaryOperation( 8762 HValue* HGraphBuilder::BuildBinaryOperation(
8638 Token::Value op, 8763 Token::Value op,
8639 HValue* left, 8764 HValue* left,
8640 HValue* right, 8765 HValue* right,
8641 Handle<Type> left_type, 8766 Handle<Type> left_type,
8642 Handle<Type> right_type, 8767 Handle<Type> right_type,
8643 Handle<Type> result_type, 8768 Handle<Type> result_type,
8644 Maybe<int> fixed_right_arg, 8769 Maybe<int> fixed_right_arg) {
8645 bool binop_stub) {
8646 8770
8647 Representation left_rep = Representation::FromType(left_type); 8771 Representation left_rep = Representation::FromType(left_type);
8648 Representation right_rep = Representation::FromType(right_type); 8772 Representation right_rep = Representation::FromType(right_type);
8649 8773
8650 bool maybe_string_add = op == Token::ADD && 8774 bool maybe_string_add = op == Token::ADD &&
8651 (left_type->Maybe(Type::String()) || 8775 (left_type->Maybe(Type::String()) ||
8652 right_type->Maybe(Type::String())); 8776 right_type->Maybe(Type::String()));
8653 8777
8654 if (left_type->Is(Type::None())) { 8778 if (left_type->Is(Type::None())) {
8655 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 8779 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
(...skipping 13 matching lines...) Expand all
8669 } else { 8793 } else {
8670 if (!maybe_string_add) right = TruncateToNumber(right, &right_type); 8794 if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
8671 right_rep = Representation::FromType(right_type); 8795 right_rep = Representation::FromType(right_type);
8672 } 8796 }
8673 8797
8674 // Special case for string addition here. 8798 // Special case for string addition here.
8675 if (op == Token::ADD && 8799 if (op == Token::ADD &&
8676 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) { 8800 (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
8677 // Validate type feedback for left argument. 8801 // Validate type feedback for left argument.
8678 if (left_type->Is(Type::String())) { 8802 if (left_type->Is(Type::String())) {
8679 left = BuildCheckString( 8803 left = BuildCheckString(left);
8680 left, "Expected string for LHS of binary operation");
8681 } 8804 }
8682 8805
8683 // Validate type feedback for right argument. 8806 // Validate type feedback for right argument.
8684 if (right_type->Is(Type::String())) { 8807 if (right_type->Is(Type::String())) {
8685 right = BuildCheckString( 8808 right = BuildCheckString(right);
8686 right, "Expected string for RHS of binary operation");
8687 } 8809 }
8688 8810
8689 // Convert left argument as necessary. 8811 // Convert left argument as necessary.
8690 if (left_type->Is(Type::Number())) { 8812 if (left_type->Is(Type::Number())) {
8691 ASSERT(right_type->Is(Type::String())); 8813 ASSERT(right_type->Is(Type::String()));
8692 left = BuildNumberToString(left, left_type); 8814 left = BuildNumberToString(left, left_type);
8693 } else if (!left_type->Is(Type::String())) { 8815 } else if (!left_type->Is(Type::String())) {
8694 ASSERT(right_type->Is(Type::String())); 8816 ASSERT(right_type->Is(Type::String()));
8695 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); 8817 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
8696 Add<HPushArgument>(left); 8818 Add<HPushArgument>(left);
8697 Add<HPushArgument>(right); 8819 Add<HPushArgument>(right);
8698 return AddUncasted<HInvokeFunction>(function, 2); 8820 return AddUncasted<HInvokeFunction>(function, 2);
8699 } 8821 }
8700 8822
8701 // Convert right argument as necessary. 8823 // Convert right argument as necessary.
8702 if (right_type->Is(Type::Number())) { 8824 if (right_type->Is(Type::Number())) {
8703 ASSERT(left_type->Is(Type::String())); 8825 ASSERT(left_type->Is(Type::String()));
8704 right = BuildNumberToString(right, right_type); 8826 right = BuildNumberToString(right, right_type);
8705 } else if (!right_type->Is(Type::String())) { 8827 } else if (!right_type->Is(Type::String())) {
8706 ASSERT(left_type->Is(Type::String())); 8828 ASSERT(left_type->Is(Type::String()));
8707 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 8829 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
8708 Add<HPushArgument>(left); 8830 Add<HPushArgument>(left);
8709 Add<HPushArgument>(right); 8831 Add<HPushArgument>(right);
8710 return AddUncasted<HInvokeFunction>(function, 2); 8832 return AddUncasted<HInvokeFunction>(function, 2);
8711 } 8833 }
8712 8834
8713 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE); 8835 return AddUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_NONE);
8714 } 8836 }
8715 8837
8716 if (binop_stub) { 8838 if (graph()->info()->IsStub()) {
8717 left = EnforceNumberType(left, left_type); 8839 left = EnforceNumberType(left, left_type);
8718 right = EnforceNumberType(right, right_type); 8840 right = EnforceNumberType(right, right_type);
8719 } 8841 }
8720 8842
8721 Representation result_rep = Representation::FromType(result_type); 8843 Representation result_rep = Representation::FromType(result_type);
8722 8844
8723 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || 8845 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) ||
8724 (right_rep.IsTagged() && !right_rep.IsSmi()); 8846 (right_rep.IsTagged() && !right_rep.IsSmi());
8725 8847
8726 HInstruction* instr = NULL; 8848 HInstruction* instr = NULL;
8727 // Only the stub is allowed to call into the runtime, since otherwise we would 8849 // Only the stub is allowed to call into the runtime, since otherwise we would
8728 // inline several instructions (including the two pushes) for every tagged 8850 // inline several instructions (including the two pushes) for every tagged
8729 // operation in optimized code, which is more expensive, than a stub call. 8851 // operation in optimized code, which is more expensive, than a stub call.
8730 if (binop_stub && is_non_primitive) { 8852 if (graph()->info()->IsStub() && is_non_primitive) {
8731 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op)); 8853 HValue* function = AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op));
8732 Add<HPushArgument>(left); 8854 Add<HPushArgument>(left);
8733 Add<HPushArgument>(right); 8855 Add<HPushArgument>(right);
8734 instr = AddUncasted<HInvokeFunction>(function, 2); 8856 instr = AddUncasted<HInvokeFunction>(function, 2);
8735 } else { 8857 } else {
8736 switch (op) { 8858 switch (op) {
8737 case Token::ADD: 8859 case Token::ADD:
8738 instr = AddUncasted<HAdd>(left, right); 8860 instr = AddUncasted<HAdd>(left, right);
8739 break; 8861 break;
8740 case Token::SUB: 8862 case Token::SUB:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
8795 default: 8917 default:
8796 UNREACHABLE(); 8918 UNREACHABLE();
8797 } 8919 }
8798 } 8920 }
8799 8921
8800 if (instr->IsBinaryOperation()) { 8922 if (instr->IsBinaryOperation()) {
8801 HBinaryOperation* binop = HBinaryOperation::cast(instr); 8923 HBinaryOperation* binop = HBinaryOperation::cast(instr);
8802 binop->set_observed_input_representation(1, left_rep); 8924 binop->set_observed_input_representation(1, left_rep);
8803 binop->set_observed_input_representation(2, right_rep); 8925 binop->set_observed_input_representation(2, right_rep);
8804 binop->initialize_output_representation(result_rep); 8926 binop->initialize_output_representation(result_rep);
8805 if (binop_stub) { 8927 if (graph()->info()->IsStub()) {
8806 // Stub should not call into stub. 8928 // Stub should not call into stub.
8807 instr->SetFlag(HValue::kCannotBeTagged); 8929 instr->SetFlag(HValue::kCannotBeTagged);
8808 // And should truncate on HForceRepresentation already. 8930 // And should truncate on HForceRepresentation already.
8809 if (left->IsForceRepresentation()) { 8931 if (left->IsForceRepresentation()) {
8810 left->CopyFlag(HValue::kTruncatingToSmi, instr); 8932 left->CopyFlag(HValue::kTruncatingToSmi, instr);
8811 left->CopyFlag(HValue::kTruncatingToInt32, instr); 8933 left->CopyFlag(HValue::kTruncatingToInt32, instr);
8812 } 8934 }
8813 if (right->IsForceRepresentation()) { 8935 if (right->IsForceRepresentation()) {
8814 right->CopyFlag(HValue::kTruncatingToSmi, instr); 8936 right->CopyFlag(HValue::kTruncatingToSmi, instr);
8815 right->CopyFlag(HValue::kTruncatingToInt32, instr); 8937 right->CopyFlag(HValue::kTruncatingToInt32, instr);
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
9213 return New<HConstant>( 9335 return New<HConstant>(
9214 function_state()->compilation_info()->closure()); 9336 function_state()->compilation_info()->closure());
9215 } else { 9337 } else {
9216 return New<HThisFunction>(); 9338 return New<HThisFunction>();
9217 } 9339 }
9218 } 9340 }
9219 9341
9220 9342
9221 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 9343 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
9222 Handle<JSObject> boilerplate_object, 9344 Handle<JSObject> boilerplate_object,
9223 AllocationSiteContext* site_context) { 9345 AllocationSiteUsageContext* site_context) {
9224 NoObservableSideEffectsScope no_effects(this); 9346 NoObservableSideEffectsScope no_effects(this);
9225 InstanceType instance_type = boilerplate_object->map()->instance_type(); 9347 InstanceType instance_type = boilerplate_object->map()->instance_type();
9226 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 9348 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
9227 9349
9228 HType type = instance_type == JS_ARRAY_TYPE 9350 HType type = instance_type == JS_ARRAY_TYPE
9229 ? HType::JSArray() : HType::JSObject(); 9351 ? HType::JSArray() : HType::JSObject();
9230 HValue* object_size_constant = Add<HConstant>( 9352 HValue* object_size_constant = Add<HConstant>(
9231 boilerplate_object->map()->instance_size()); 9353 boilerplate_object->map()->instance_size());
9232 HInstruction* object = Add<HAllocate>(object_size_constant, type, 9354 HInstruction* object = Add<HAllocate>(object_size_constant, type,
9233 isolate()->heap()->GetPretenureMode(), instance_type); 9355 isolate()->heap()->GetPretenureMode(), instance_type);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
9306 object_elements = Add<HConstant>(elements_field); 9428 object_elements = Add<HConstant>(elements_field);
9307 } 9429 }
9308 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 9430 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
9309 object_elements); 9431 object_elements);
9310 } 9432 }
9311 9433
9312 9434
9313 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 9435 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
9314 Handle<JSObject> boilerplate_object, 9436 Handle<JSObject> boilerplate_object,
9315 HInstruction* object, 9437 HInstruction* object,
9316 AllocationSiteContext* site_context) { 9438 AllocationSiteUsageContext* site_context) {
9317 Handle<DescriptorArray> descriptors( 9439 Handle<DescriptorArray> descriptors(
9318 boilerplate_object->map()->instance_descriptors()); 9440 boilerplate_object->map()->instance_descriptors());
9319 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); 9441 int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
9320 9442
9321 int copied_fields = 0; 9443 int copied_fields = 0;
9322 for (int i = 0; i < limit; i++) { 9444 for (int i = 0; i < limit; i++) {
9323 PropertyDetails details = descriptors->GetDetails(i); 9445 PropertyDetails details = descriptors->GetDetails(i);
9324 if (details.type() != FIELD) continue; 9446 if (details.type() != FIELD) continue;
9325 copied_fields++; 9447 copied_fields++;
9326 int index = descriptors->GetFieldIndex(i); 9448 int index = descriptors->GetFieldIndex(i);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
9378 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset); 9500 HObjectAccess access = HObjectAccess::ForJSObjectOffset(property_offset);
9379 Add<HStoreNamedField>(object, access, value_instruction); 9501 Add<HStoreNamedField>(object, access, value_instruction);
9380 } 9502 }
9381 } 9503 }
9382 9504
9383 9505
9384 void HOptimizedGraphBuilder::BuildEmitElements( 9506 void HOptimizedGraphBuilder::BuildEmitElements(
9385 Handle<JSObject> boilerplate_object, 9507 Handle<JSObject> boilerplate_object,
9386 Handle<FixedArrayBase> elements, 9508 Handle<FixedArrayBase> elements,
9387 HValue* object_elements, 9509 HValue* object_elements,
9388 AllocationSiteContext* site_context) { 9510 AllocationSiteUsageContext* site_context) {
9389 ElementsKind kind = boilerplate_object->map()->elements_kind(); 9511 ElementsKind kind = boilerplate_object->map()->elements_kind();
9390 int elements_length = elements->length(); 9512 int elements_length = elements->length();
9391 HValue* object_elements_length = Add<HConstant>(elements_length); 9513 HValue* object_elements_length = Add<HConstant>(elements_length);
9392 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); 9514 BuildInitializeElementsHeader(object_elements, kind, object_elements_length);
9393 9515
9394 // Copy elements backing store content. 9516 // Copy elements backing store content.
9395 if (elements->IsFixedDoubleArray()) { 9517 if (elements->IsFixedDoubleArray()) {
9396 BuildEmitFixedDoubleArray(elements, kind, object_elements); 9518 BuildEmitFixedDoubleArray(elements, kind, object_elements);
9397 } else if (elements->IsFixedArray()) { 9519 } else if (elements->IsFixedArray()) {
9398 BuildEmitFixedArray(elements, kind, object_elements, 9520 BuildEmitFixedArray(elements, kind, object_elements,
(...skipping 20 matching lines...) Expand all
9419 value_instruction, kind); 9541 value_instruction, kind);
9420 store->SetFlag(HValue::kAllowUndefinedAsNaN); 9542 store->SetFlag(HValue::kAllowUndefinedAsNaN);
9421 } 9543 }
9422 } 9544 }
9423 9545
9424 9546
9425 void HOptimizedGraphBuilder::BuildEmitFixedArray( 9547 void HOptimizedGraphBuilder::BuildEmitFixedArray(
9426 Handle<FixedArrayBase> elements, 9548 Handle<FixedArrayBase> elements,
9427 ElementsKind kind, 9549 ElementsKind kind,
9428 HValue* object_elements, 9550 HValue* object_elements,
9429 AllocationSiteContext* site_context) { 9551 AllocationSiteUsageContext* site_context) {
9430 HInstruction* boilerplate_elements = Add<HConstant>(elements); 9552 HInstruction* boilerplate_elements = Add<HConstant>(elements);
9431 int elements_length = elements->length(); 9553 int elements_length = elements->length();
9432 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 9554 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
9433 for (int i = 0; i < elements_length; i++) { 9555 for (int i = 0; i < elements_length; i++) {
9434 Handle<Object> value(fast_elements->get(i), isolate()); 9556 Handle<Object> value(fast_elements->get(i), isolate());
9435 HValue* key_constant = Add<HConstant>(i); 9557 HValue* key_constant = Add<HConstant>(i);
9436 if (value->IsJSObject()) { 9558 if (value->IsJSObject()) {
9437 Handle<JSObject> value_object = Handle<JSObject>::cast(value); 9559 Handle<JSObject> value_object = Handle<JSObject>::cast(value);
9438 Handle<AllocationSite> current_site = site_context->EnterNewScope(); 9560 Handle<AllocationSite> current_site = site_context->EnterNewScope();
9439 HInstruction* result = 9561 HInstruction* result =
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
9885 return ast_context()->ReturnControl(result, call->id()); 10007 return ast_context()->ReturnControl(result, call->id());
9886 } 10008 }
9887 10009
9888 10010
9889 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { 10011 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) {
9890 // %_Log is ignored in optimized code. 10012 // %_Log is ignored in optimized code.
9891 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 10013 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
9892 } 10014 }
9893 10015
9894 10016
9895 // Fast support for Math.random().
9896 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) {
9897 HGlobalObject* global_object = Add<HGlobalObject>();
9898 HRandom* result = New<HRandom>(global_object);
9899 return ast_context()->ReturnInstruction(result, call->id());
9900 }
9901
9902
9903 // Fast support for StringAdd. 10017 // Fast support for StringAdd.
9904 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 10018 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
9905 ASSERT_EQ(2, call->arguments()->length()); 10019 ASSERT_EQ(2, call->arguments()->length());
9906 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10020 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9907 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10021 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9908 HValue* right = Pop(); 10022 HValue* right = Pop();
9909 HValue* left = Pop(); 10023 HValue* left = Pop();
9910 HInstruction* result = New<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH); 10024 HInstruction* result =
10025 NewUncasted<HStringAdd>(left, right, STRING_ADD_CHECK_BOTH);
9911 return ast_context()->ReturnInstruction(result, call->id()); 10026 return ast_context()->ReturnInstruction(result, call->id());
9912 } 10027 }
9913 10028
9914 10029
9915 // Fast support for SubString. 10030 // Fast support for SubString.
9916 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 10031 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
9917 ASSERT_EQ(3, call->arguments()->length()); 10032 ASSERT_EQ(3, call->arguments()->length());
9918 CHECK_ALIVE(VisitArgumentList(call->arguments())); 10033 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9919 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 10034 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
9920 Drop(3); 10035 Drop(3);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
10029 result->set_transcendental_type(TranscendentalCache::LOG); 10144 result->set_transcendental_type(TranscendentalCache::LOG);
10030 Drop(1); 10145 Drop(1);
10031 return ast_context()->ReturnInstruction(result, call->id()); 10146 return ast_context()->ReturnInstruction(result, call->id());
10032 } 10147 }
10033 10148
10034 10149
10035 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) { 10150 void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
10036 ASSERT(call->arguments()->length() == 1); 10151 ASSERT(call->arguments()->length() == 1);
10037 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10152 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10038 HValue* value = Pop(); 10153 HValue* value = Pop();
10039 HInstruction* result = New<HUnaryMathOperation>(value, kMathSqrt); 10154 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt);
10040 return ast_context()->ReturnInstruction(result, call->id()); 10155 return ast_context()->ReturnInstruction(result, call->id());
10041 } 10156 }
10042 10157
10043 10158
10044 // Check whether two RegExps are equivalent 10159 // Check whether two RegExps are equivalent
10045 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { 10160 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) {
10046 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); 10161 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent);
10047 } 10162 }
10048 10163
10049 10164
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
10689 if (ShouldProduceTraceOutput()) { 10804 if (ShouldProduceTraceOutput()) {
10690 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10805 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10691 } 10806 }
10692 10807
10693 #ifdef DEBUG 10808 #ifdef DEBUG
10694 graph_->Verify(false); // No full verify. 10809 graph_->Verify(false); // No full verify.
10695 #endif 10810 #endif
10696 } 10811 }
10697 10812
10698 } } // namespace v8::internal 10813 } } // 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