OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1385 matching lines...) Loading... |
1396 mul->ClearFlag(HValue::kCanOverflow); | 1396 mul->ClearFlag(HValue::kCanOverflow); |
1397 | 1397 |
1398 HConstant* header_size = | 1398 HConstant* header_size = |
1399 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); | 1399 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); |
1400 AddInstruction(header_size); | 1400 AddInstruction(header_size); |
1401 HValue* total_size = AddInstruction( | 1401 HValue* total_size = AddInstruction( |
1402 HAdd::New(zone, context, mul, header_size)); | 1402 HAdd::New(zone, context, mul, header_size)); |
1403 total_size->ChangeRepresentation(Representation::Integer32()); | 1403 total_size->ChangeRepresentation(Representation::Integer32()); |
1404 total_size->ClearFlag(HValue::kCanOverflow); | 1404 total_size->ClearFlag(HValue::kCanOverflow); |
1405 | 1405 |
1406 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1406 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
1407 if (FLAG_pretenure_literals) { | 1407 if (FLAG_pretenure_literals) { |
| 1408 // TODO(hpayer): When pretenuring can be internalized, flags can become |
| 1409 // private to HAllocate. |
1408 if (IsFastDoubleElementsKind(kind)) { | 1410 if (IsFastDoubleElementsKind(kind)) { |
1409 flags = static_cast<HAllocate::Flags>( | 1411 flags = static_cast<HAllocate::Flags>( |
1410 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 1412 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
1411 } else { | 1413 } else { |
1412 flags = static_cast<HAllocate::Flags>( | 1414 flags = static_cast<HAllocate::Flags>( |
1413 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 1415 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
1414 } | 1416 } |
1415 } | 1417 } |
1416 if (IsFastDoubleElementsKind(kind)) { | |
1417 flags = static_cast<HAllocate::Flags>( | |
1418 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
1419 } | |
1420 | 1418 |
1421 HValue* elements = | 1419 HValue* elements = |
1422 AddInstruction(new(zone) HAllocate(context, total_size, | 1420 AddInstruction(new(zone) HAllocate(context, total_size, |
1423 HType::JSArray(), flags)); | 1421 HType::JSArray(), flags)); |
1424 return elements; | 1422 return elements; |
1425 } | 1423 } |
1426 | 1424 |
1427 | 1425 |
1428 void HGraphBuilder::BuildInitializeElements(HValue* elements, | 1426 void HGraphBuilder::BuildInitializeElements(HValue* elements, |
1429 ElementsKind kind, | 1427 ElementsKind kind, |
(...skipping 15 matching lines...) Loading... |
1445 | 1443 |
1446 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1444 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1447 ElementsKind kind, | 1445 ElementsKind kind, |
1448 HValue* capacity) { | 1446 HValue* capacity) { |
1449 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1447 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1450 BuildInitializeElements(new_elements, kind, capacity); | 1448 BuildInitializeElements(new_elements, kind, capacity); |
1451 return new_elements; | 1449 return new_elements; |
1452 } | 1450 } |
1453 | 1451 |
1454 | 1452 |
| 1453 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
| 1454 HValue* array_map, |
| 1455 AllocationSiteMode mode, |
| 1456 HValue* allocation_site_payload, |
| 1457 HValue* length_field) { |
| 1458 |
| 1459 BuildStoreMap(array, array_map); |
| 1460 |
| 1461 HConstant* empty_fixed_array = |
| 1462 new(zone()) HConstant( |
| 1463 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), |
| 1464 Representation::Tagged()); |
| 1465 AddInstruction(empty_fixed_array); |
| 1466 |
| 1467 AddInstruction(new(zone()) HStoreNamedField(array, |
| 1468 isolate()->factory()->properties_field_symbol(), |
| 1469 empty_fixed_array, |
| 1470 true, |
| 1471 JSArray::kPropertiesOffset)); |
| 1472 |
| 1473 HInstruction* length_store = AddInstruction( |
| 1474 new(zone()) HStoreNamedField(array, |
| 1475 isolate()->factory()->length_field_string(), |
| 1476 length_field, |
| 1477 true, |
| 1478 JSArray::kLengthOffset)); |
| 1479 length_store->SetGVNFlag(kChangesArrayLengths); |
| 1480 |
| 1481 if (mode == TRACK_ALLOCATION_SITE) { |
| 1482 BuildCreateAllocationSiteInfo(array, |
| 1483 JSArray::kSize, |
| 1484 allocation_site_payload); |
| 1485 } |
| 1486 |
| 1487 int elements_location = JSArray::kSize; |
| 1488 if (mode == TRACK_ALLOCATION_SITE) { |
| 1489 elements_location += AllocationSiteInfo::kSize; |
| 1490 } |
| 1491 |
| 1492 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( |
| 1493 array, |
| 1494 elements_location); |
| 1495 AddInstruction(elements); |
| 1496 |
| 1497 HInstruction* elements_store = AddInstruction( |
| 1498 new(zone()) HStoreNamedField( |
| 1499 array, |
| 1500 isolate()->factory()->elements_field_string(), |
| 1501 elements, |
| 1502 true, |
| 1503 JSArray::kElementsOffset)); |
| 1504 elements_store->SetGVNFlag(kChangesElementsPointer); |
| 1505 |
| 1506 return elements; |
| 1507 } |
| 1508 |
| 1509 |
1455 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1510 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
1456 HValue* map) { | 1511 HValue* map) { |
1457 Zone* zone = this->zone(); | 1512 Zone* zone = this->zone(); |
1458 Factory* factory = isolate()->factory(); | 1513 Factory* factory = isolate()->factory(); |
1459 Handle<String> map_field_name = factory->map_field_string(); | 1514 Handle<String> map_field_name = factory->map_field_string(); |
1460 HInstruction* store_map = | 1515 HInstruction* store_map = |
1461 new(zone) HStoreNamedField(object, map_field_name, map, | 1516 new(zone) HStoreNamedField(object, map_field_name, map, |
1462 true, JSObject::kMapOffset); | 1517 true, JSObject::kMapOffset); |
1463 store_map->SetGVNFlag(kChangesMaps); | 1518 store_map->SetGVNFlag(kChangesMaps); |
1464 AddInstruction(store_map); | 1519 AddInstruction(store_map); |
(...skipping 93 matching lines...) Loading... |
1558 Factory* factory = isolate()->factory(); | 1613 Factory* factory = isolate()->factory(); |
1559 | 1614 |
1560 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1615 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1561 Zone* zone = this->zone(); | 1616 Zone* zone = this->zone(); |
1562 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1617 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1563 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1618 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
1564 Representation::Tagged())) | 1619 Representation::Tagged())) |
1565 : AddInstruction(new(zone) HConstant(nan_double, | 1620 : AddInstruction(new(zone) HConstant(nan_double, |
1566 Representation::Double())); | 1621 Representation::Double())); |
1567 | 1622 |
1568 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1623 // Special loop unfolding case |
| 1624 static const int kLoopUnfoldLimit = 4; |
| 1625 bool unfold_loop = false; |
| 1626 int initial_capacity = JSArray::kPreallocatedArrayElements; |
| 1627 if (from->IsConstant() && to->IsConstant() && |
| 1628 initial_capacity <= kLoopUnfoldLimit) { |
| 1629 HConstant* constant_from = HConstant::cast(from); |
| 1630 HConstant* constant_to = HConstant::cast(to); |
1569 | 1631 |
1570 HValue* key = builder.BeginBody(from, to, Token::LT); | 1632 if (constant_from->HasInteger32Value() && |
| 1633 constant_from->Integer32Value() == 0 && |
| 1634 constant_to->HasInteger32Value() && |
| 1635 constant_to->Integer32Value() == initial_capacity) { |
| 1636 unfold_loop = true; |
| 1637 } |
| 1638 } |
1571 | 1639 |
1572 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1640 if (unfold_loop) { |
| 1641 for (int i = 0; i < initial_capacity; i++) { |
| 1642 HInstruction* key = AddInstruction(new(zone) |
| 1643 HConstant(i, Representation::Integer32())); |
| 1644 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
| 1645 } |
| 1646 } else { |
| 1647 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1573 | 1648 |
1574 builder.EndBody(); | 1649 HValue* key = builder.BeginBody(from, to, Token::LT); |
| 1650 |
| 1651 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
| 1652 |
| 1653 builder.EndBody(); |
| 1654 } |
1575 } | 1655 } |
1576 | 1656 |
1577 | 1657 |
1578 void HGraphBuilder::BuildCopyElements(HValue* context, | 1658 void HGraphBuilder::BuildCopyElements(HValue* context, |
1579 HValue* from_elements, | 1659 HValue* from_elements, |
1580 ElementsKind from_elements_kind, | 1660 ElementsKind from_elements_kind, |
1581 HValue* to_elements, | 1661 HValue* to_elements, |
1582 ElementsKind to_elements_kind, | 1662 ElementsKind to_elements_kind, |
1583 HValue* length, | 1663 HValue* length, |
1584 HValue* capacity) { | 1664 HValue* capacity) { |
(...skipping 46 matching lines...) Loading... |
1631 if (mode == TRACK_ALLOCATION_SITE) { | 1711 if (mode == TRACK_ALLOCATION_SITE) { |
1632 size += AllocationSiteInfo::kSize; | 1712 size += AllocationSiteInfo::kSize; |
1633 } | 1713 } |
1634 int elems_offset = size; | 1714 int elems_offset = size; |
1635 if (length > 0) { | 1715 if (length > 0) { |
1636 size += IsFastDoubleElementsKind(kind) | 1716 size += IsFastDoubleElementsKind(kind) |
1637 ? FixedDoubleArray::SizeFor(length) | 1717 ? FixedDoubleArray::SizeFor(length) |
1638 : FixedArray::SizeFor(length); | 1718 : FixedArray::SizeFor(length); |
1639 } | 1719 } |
1640 | 1720 |
1641 HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1721 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
1642 if (IsFastDoubleElementsKind(kind)) { | |
1643 allocate_flags = static_cast<HAllocate::Flags>( | |
1644 allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
1645 } | |
1646 | |
1647 // Allocate both the JS array and the elements array in one big | 1722 // Allocate both the JS array and the elements array in one big |
1648 // allocation. This avoids multiple limit checks. | 1723 // allocation. This avoids multiple limit checks. |
1649 HValue* size_in_bytes = | 1724 HValue* size_in_bytes = |
1650 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1725 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
1651 HInstruction* object = | 1726 HInstruction* object = |
1652 AddInstruction(new(zone) HAllocate(context, | 1727 AddInstruction(new(zone) HAllocate(context, |
1653 size_in_bytes, | 1728 size_in_bytes, |
1654 HType::JSObject(), | 1729 HType::JSObject(), |
1655 allocate_flags)); | 1730 allocate_flags)); |
1656 | 1731 |
1657 // Copy the JS array part. | 1732 // Copy the JS array part. |
1658 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1733 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1659 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1734 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1660 HInstruction* value = | 1735 HInstruction* value = |
1661 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); | 1736 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); |
1662 if (i != JSArray::kMapOffset) { | 1737 if (i != JSArray::kMapOffset) { |
1663 AddInstruction(new(zone) HStoreNamedField(object, | 1738 AddInstruction(new(zone) HStoreNamedField(object, |
1664 factory->empty_string(), | 1739 factory->empty_string(), |
1665 value, | 1740 value, |
1666 true, i)); | 1741 true, i)); |
1667 } else { | 1742 } else { |
1668 BuildStoreMap(object, value); | 1743 BuildStoreMap(object, value); |
1669 } | 1744 } |
1670 } | 1745 } |
1671 } | 1746 } |
1672 | 1747 |
1673 // Create an allocation site info if requested. | 1748 // Create an allocation site info if requested. |
1674 if (mode == TRACK_ALLOCATION_SITE) { | 1749 if (mode == TRACK_ALLOCATION_SITE) { |
1675 HValue* alloc_site = | 1750 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
1676 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); | |
1677 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
1678 BuildStoreMap(alloc_site, alloc_site_map); | |
1679 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
1680 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
1681 factory->empty_string(), | |
1682 boilerplate, | |
1683 true, alloc_payload_offset)); | |
1684 } | 1751 } |
1685 | 1752 |
1686 if (length > 0) { | 1753 if (length > 0) { |
1687 // Get hold of the elements array of the boilerplate and setup the | 1754 // Get hold of the elements array of the boilerplate and setup the |
1688 // elements pointer in the resulting object. | 1755 // elements pointer in the resulting object. |
1689 HValue* boilerplate_elements = | 1756 HValue* boilerplate_elements = |
1690 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); | 1757 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); |
1691 HValue* object_elements = | 1758 HValue* object_elements = |
1692 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1759 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
1693 AddInstruction(new(zone) HStoreNamedField(object, | 1760 AddInstruction(new(zone) HStoreNamedField(object, |
(...skipping 28 matching lines...) Loading... |
1722 key_constant, | 1789 key_constant, |
1723 value, | 1790 value, |
1724 kind)); | 1791 kind)); |
1725 } | 1792 } |
1726 } | 1793 } |
1727 | 1794 |
1728 return object; | 1795 return object; |
1729 } | 1796 } |
1730 | 1797 |
1731 | 1798 |
| 1799 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
| 1800 int previous_object_size, |
| 1801 HValue* payload) { |
| 1802 HInnerAllocatedObject* alloc_site = new(zone()) |
| 1803 HInnerAllocatedObject(previous_object, previous_object_size); |
| 1804 AddInstruction(alloc_site); |
| 1805 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
| 1806 BuildStoreMap(alloc_site, alloc_site_map); |
| 1807 AddInstruction(new(zone()) HStoreNamedField(alloc_site, |
| 1808 isolate()->factory()->payload_string(), |
| 1809 payload, |
| 1810 true, |
| 1811 AllocationSiteInfo::kPayloadOffset)); |
| 1812 return alloc_site; |
| 1813 } |
| 1814 |
| 1815 |
| 1816 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
| 1817 ElementsKind kind, |
| 1818 HValue* allocation_site_payload, |
| 1819 AllocationSiteMode mode) : |
| 1820 builder_(builder), |
| 1821 kind_(kind), |
| 1822 allocation_site_payload_(allocation_site_payload) { |
| 1823 if (mode == DONT_TRACK_ALLOCATION_SITE) { |
| 1824 mode_ = mode; |
| 1825 } else { |
| 1826 mode_ = AllocationSiteInfo::GetMode(kind); |
| 1827 } |
| 1828 } |
| 1829 |
| 1830 |
| 1831 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
| 1832 // Get the global context, the native context, the map array |
| 1833 HInstruction* global_object = AddInstruction(new(zone()) |
| 1834 HGlobalObject(context)); |
| 1835 HInstruction* native_context = AddInstruction(new(zone()) |
| 1836 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset)); |
| 1837 size_t offset = Context::kHeaderSize + |
| 1838 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; |
| 1839 HInstruction* map_array = AddInstruction(new(zone()) |
| 1840 HLoadNamedField(native_context, true, offset)); |
| 1841 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; |
| 1842 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset)); |
| 1843 } |
| 1844 |
| 1845 |
| 1846 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
| 1847 HValue* length_node) { |
| 1848 HValue* context = builder()->environment()->LookupContext(); |
| 1849 ASSERT(length_node != NULL); |
| 1850 |
| 1851 int base_size = JSArray::kSize; |
| 1852 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1853 base_size += AllocationSiteInfo::kSize; |
| 1854 } |
| 1855 |
| 1856 if (IsFastDoubleElementsKind(kind_)) { |
| 1857 base_size += FixedDoubleArray::kHeaderSize; |
| 1858 } else { |
| 1859 base_size += FixedArray::kHeaderSize; |
| 1860 } |
| 1861 |
| 1862 HInstruction* elements_size_value = new(zone()) |
| 1863 HConstant(elements_size(), Representation::Integer32()); |
| 1864 AddInstruction(elements_size_value); |
| 1865 HInstruction* mul = HMul::New(zone(), context, length_node, |
| 1866 elements_size_value); |
| 1867 mul->ChangeRepresentation(Representation::Integer32()); |
| 1868 mul->ClearFlag(HValue::kCanOverflow); |
| 1869 AddInstruction(mul); |
| 1870 |
| 1871 HInstruction* base = new(zone()) HConstant(base_size, |
| 1872 Representation::Integer32()); |
| 1873 AddInstruction(base); |
| 1874 HInstruction* total_size = HAdd::New(zone(), context, base, mul); |
| 1875 total_size->ChangeRepresentation(Representation::Integer32()); |
| 1876 total_size->ClearFlag(HValue::kCanOverflow); |
| 1877 AddInstruction(total_size); |
| 1878 return total_size; |
| 1879 } |
| 1880 |
| 1881 |
| 1882 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { |
| 1883 int base_size = JSArray::kSize; |
| 1884 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1885 base_size += AllocationSiteInfo::kSize; |
| 1886 } |
| 1887 |
| 1888 base_size += IsFastDoubleElementsKind(kind_) |
| 1889 ? FixedDoubleArray::SizeFor(initial_capacity()) |
| 1890 : FixedArray::SizeFor(initial_capacity()); |
| 1891 |
| 1892 HConstant* array_size = |
| 1893 new(zone()) HConstant(base_size, Representation::Integer32()); |
| 1894 AddInstruction(array_size); |
| 1895 return array_size; |
| 1896 } |
| 1897 |
| 1898 |
| 1899 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 1900 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); |
| 1901 HConstant* capacity = |
| 1902 new(zone()) HConstant(initial_capacity(), Representation::Integer32()); |
| 1903 AddInstruction(capacity); |
| 1904 return AllocateArray(size_in_bytes, |
| 1905 capacity, |
| 1906 builder()->graph()->GetConstant0(), |
| 1907 true); |
| 1908 } |
| 1909 |
| 1910 |
| 1911 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, |
| 1912 HValue* length_field, |
| 1913 bool fill_with_hole) { |
| 1914 HValue* size_in_bytes = EstablishAllocationSize(capacity); |
| 1915 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); |
| 1916 } |
| 1917 |
| 1918 |
| 1919 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
| 1920 HValue* capacity, |
| 1921 HValue* length_field, |
| 1922 bool fill_with_hole) { |
| 1923 HValue* context = builder()->environment()->LookupContext(); |
| 1924 |
| 1925 // Allocate (dealing with failure appropriately) |
| 1926 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
| 1927 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, |
| 1928 HType::JSArray(), flags); |
| 1929 AddInstruction(new_object); |
| 1930 |
| 1931 // Fill in the fields: map, properties, length |
| 1932 HValue* map = EmitMapCode(context); |
| 1933 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
| 1934 map, |
| 1935 mode_, |
| 1936 allocation_site_payload_, |
| 1937 length_field); |
| 1938 |
| 1939 // Initialize the elements |
| 1940 builder()->BuildInitializeElements(elements_location_, kind_, capacity); |
| 1941 |
| 1942 if (fill_with_hole) { |
| 1943 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
| 1944 graph()->GetConstant0(), capacity); |
| 1945 } |
| 1946 |
| 1947 return new_object; |
| 1948 } |
| 1949 |
| 1950 |
1732 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1951 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1733 TypeFeedbackOracle* oracle) | 1952 TypeFeedbackOracle* oracle) |
1734 : HGraphBuilder(info), | 1953 : HGraphBuilder(info), |
1735 function_state_(NULL), | 1954 function_state_(NULL), |
1736 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1955 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
1737 ast_context_(NULL), | 1956 ast_context_(NULL), |
1738 break_scope_(NULL), | 1957 break_scope_(NULL), |
1739 inlined_count_(0), | 1958 inlined_count_(0), |
1740 globals_(10, info->zone()), | 1959 globals_(10, info->zone()), |
1741 inline_bailout_(false) { | 1960 inline_bailout_(false) { |
(...skipping 7523 matching lines...) Loading... |
9265 receiver->DeleteAndReplaceWith(NULL); | 9484 receiver->DeleteAndReplaceWith(NULL); |
9266 check->DeleteAndReplaceWith(NULL); | 9485 check->DeleteAndReplaceWith(NULL); |
9267 environment()->SetExpressionStackAt(receiver_index, function); | 9486 environment()->SetExpressionStackAt(receiver_index, function); |
9268 HInstruction* call = PreProcessCall( | 9487 HInstruction* call = PreProcessCall( |
9269 new(zone()) HCallNew(context, function, argument_count)); | 9488 new(zone()) HCallNew(context, function, argument_count)); |
9270 call->set_position(expr->position()); | 9489 call->set_position(expr->position()); |
9271 return ast_context()->ReturnInstruction(call, expr->id()); | 9490 return ast_context()->ReturnInstruction(call, expr->id()); |
9272 } else { | 9491 } else { |
9273 // The constructor function is both an operand to the instruction and an | 9492 // The constructor function is both an operand to the instruction and an |
9274 // argument to the construct call. | 9493 // argument to the construct call. |
| 9494 bool use_call_new_array = FLAG_optimize_constructed_arrays && |
| 9495 !(expr->target().is_null()) && |
| 9496 *(expr->target()) == isolate()->global_context()->array_function(); |
| 9497 |
9275 CHECK_ALIVE(VisitArgument(expr->expression())); | 9498 CHECK_ALIVE(VisitArgument(expr->expression())); |
9276 HValue* constructor = HPushArgument::cast(Top())->argument(); | 9499 HValue* constructor = HPushArgument::cast(Top())->argument(); |
9277 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 9500 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
9278 HCallNew* call; | 9501 HCallNew* call; |
9279 if (FLAG_optimize_constructed_arrays && | 9502 if (use_call_new_array) { |
9280 !(expr->target().is_null()) && | 9503 AddInstruction(new(zone()) HCheckFunction(constructor, |
9281 *(expr->target()) == isolate()->global_context()->array_function()) { | 9504 Handle<JSFunction>(isolate()->global_context()->array_function()))); |
9282 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); | 9505 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); |
9283 ASSERT(feedback->IsSmi()); | 9506 ASSERT(feedback->IsSmi()); |
| 9507 |
| 9508 // TODO(mvstanton): It would be better to use the already created global |
| 9509 // property cell that is shared by full code gen. That way, any transition |
| 9510 // information that happened after crankshaft won't be lost. The right |
| 9511 // way to do that is to begin passing the cell to the type feedback oracle |
| 9512 // instead of just the value in the cell. Do this in a follow-up checkin. |
9284 Handle<JSGlobalPropertyCell> cell = | 9513 Handle<JSGlobalPropertyCell> cell = |
9285 isolate()->factory()->NewJSGlobalPropertyCell(feedback); | 9514 isolate()->factory()->NewJSGlobalPropertyCell(feedback); |
9286 AddInstruction(new(zone()) HCheckFunction(constructor, | 9515 |
9287 Handle<JSFunction>(isolate()->global_context()->array_function()))); | 9516 // TODO(mvstanton): Here we should probably insert code to check if the |
| 9517 // type cell elements kind is different from when we compiled, and deopt |
| 9518 // in that case. Do this in a follow-up checin. |
9288 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 9519 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
9289 cell); | 9520 cell); |
9290 } else { | 9521 } else { |
9291 call = new(zone()) HCallNew(context, constructor, argument_count); | 9522 call = new(zone()) HCallNew(context, constructor, argument_count); |
9292 } | 9523 } |
9293 Drop(argument_count); | 9524 Drop(argument_count); |
9294 call->set_position(expr->position()); | 9525 call->set_position(expr->position()); |
9295 return ast_context()->ReturnInstruction(call, expr->id()); | 9526 return ast_context()->ReturnInstruction(call, expr->id()); |
9296 } | 9527 } |
9297 } | 9528 } |
(...skipping 1092 matching lines...) Loading... |
10390 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10621 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10391 value, Representation::Tagged())); | 10622 value, Representation::Tagged())); |
10392 AddInstruction(new(zone) HStoreNamedField( | 10623 AddInstruction(new(zone) HStoreNamedField( |
10393 object_properties, factory->unknown_field_string(), value_instruction, | 10624 object_properties, factory->unknown_field_string(), value_instruction, |
10394 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10625 true, boilerplate_object->GetInObjectPropertyOffset(i))); |
10395 } | 10626 } |
10396 } | 10627 } |
10397 | 10628 |
10398 // Build Allocation Site Info if desired | 10629 // Build Allocation Site Info if desired |
10399 if (create_allocation_site_info) { | 10630 if (create_allocation_site_info) { |
10400 HValue* alloc_site = | 10631 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10401 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); | |
10402 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
10403 BuildStoreMap(alloc_site, alloc_site_map); | |
10404 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
10405 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
10406 factory->payload_string(), | |
10407 original_boilerplate, | |
10408 true, alloc_payload_offset)); | |
10409 } | 10632 } |
10410 | 10633 |
10411 if (object_elements != NULL) { | 10634 if (object_elements != NULL) { |
10412 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10635 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
10413 elements, Representation::Tagged())); | 10636 elements, Representation::Tagged())); |
10414 | 10637 |
10415 int elements_length = elements->length(); | 10638 int elements_length = elements->length(); |
10416 HValue* object_elements_length = | 10639 HValue* object_elements_length = |
10417 AddInstruction(new(zone) HConstant( | 10640 AddInstruction(new(zone) HConstant( |
10418 elements_length, Representation::Integer32())); | 10641 elements_length, Representation::Integer32())); |
(...skipping 1451 matching lines...) Loading... |
11870 } | 12093 } |
11871 } | 12094 } |
11872 | 12095 |
11873 #ifdef DEBUG | 12096 #ifdef DEBUG |
11874 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12097 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11875 if (allocator_ != NULL) allocator_->Verify(); | 12098 if (allocator_ != NULL) allocator_->Verify(); |
11876 #endif | 12099 #endif |
11877 } | 12100 } |
11878 | 12101 |
11879 } } // namespace v8::internal | 12102 } } // namespace v8::internal |
OLD | NEW |