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 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 mul->ClearFlag(HValue::kCanOverflow); | 1334 mul->ClearFlag(HValue::kCanOverflow); |
1335 | 1335 |
1336 HConstant* header_size = | 1336 HConstant* header_size = |
1337 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); | 1337 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); |
1338 AddInstruction(header_size); | 1338 AddInstruction(header_size); |
1339 HValue* total_size = AddInstruction( | 1339 HValue* total_size = AddInstruction( |
1340 HAdd::New(zone, context, mul, header_size)); | 1340 HAdd::New(zone, context, mul, header_size)); |
1341 total_size->ChangeRepresentation(Representation::Integer32()); | 1341 total_size->ChangeRepresentation(Representation::Integer32()); |
1342 total_size->ClearFlag(HValue::kCanOverflow); | 1342 total_size->ClearFlag(HValue::kCanOverflow); |
1343 | 1343 |
1344 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1344 HAllocate::Flags flags = HAllocate::DefaultFlags(kind); |
1345 if (FLAG_pretenure_literals) { | 1345 if (FLAG_pretenure_literals) { |
| 1346 // TODO(hpayer): When pretenuring can be internalized, flags can become |
| 1347 // private to HAllocate. |
1346 if (IsFastDoubleElementsKind(kind)) { | 1348 if (IsFastDoubleElementsKind(kind)) { |
1347 flags = static_cast<HAllocate::Flags>( | 1349 flags = static_cast<HAllocate::Flags>( |
1348 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); | 1350 flags | HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); |
1349 } else { | 1351 } else { |
1350 flags = static_cast<HAllocate::Flags>( | 1352 flags = static_cast<HAllocate::Flags>( |
1351 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); | 1353 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); |
1352 } | 1354 } |
1353 } | 1355 } |
1354 if (IsFastDoubleElementsKind(kind)) { | |
1355 flags = static_cast<HAllocate::Flags>( | |
1356 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
1357 } | |
1358 | 1356 |
1359 HValue* elements = | 1357 HValue* elements = |
1360 AddInstruction(new(zone) HAllocate(context, total_size, | 1358 AddInstruction(new(zone) HAllocate(context, total_size, |
1361 HType::JSArray(), flags)); | 1359 HType::JSArray(), flags)); |
1362 return elements; | 1360 return elements; |
1363 } | 1361 } |
1364 | 1362 |
1365 | 1363 |
1366 void HGraphBuilder::BuildInitializeElements(HValue* elements, | 1364 void HGraphBuilder::BuildInitializeElements(HValue* elements, |
1367 ElementsKind kind, | 1365 ElementsKind kind, |
(...skipping 15 matching lines...) Expand all Loading... |
1383 | 1381 |
1384 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1382 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
1385 ElementsKind kind, | 1383 ElementsKind kind, |
1386 HValue* capacity) { | 1384 HValue* capacity) { |
1387 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1385 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1388 BuildInitializeElements(new_elements, kind, capacity); | 1386 BuildInitializeElements(new_elements, kind, capacity); |
1389 return new_elements; | 1387 return new_elements; |
1390 } | 1388 } |
1391 | 1389 |
1392 | 1390 |
| 1391 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
| 1392 HValue* array_map, |
| 1393 AllocationSiteMode mode, |
| 1394 HValue* allocation_site_payload, |
| 1395 HValue* length_field) { |
| 1396 |
| 1397 BuildStoreMap(array, array_map); |
| 1398 |
| 1399 HConstant* empty_fixed_array = |
| 1400 new(zone()) HConstant( |
| 1401 Handle<FixedArray>(isolate()->heap()->empty_fixed_array()), |
| 1402 Representation::Tagged()); |
| 1403 AddInstruction(empty_fixed_array); |
| 1404 |
| 1405 AddInstruction(new(zone()) HStoreNamedField(array, |
| 1406 isolate()->factory()->properties_field_symbol(), |
| 1407 empty_fixed_array, |
| 1408 true, |
| 1409 JSArray::kPropertiesOffset)); |
| 1410 |
| 1411 HInstruction* length_store = AddInstruction( |
| 1412 new(zone()) HStoreNamedField(array, |
| 1413 isolate()->factory()->length_field_string(), |
| 1414 length_field, |
| 1415 true, |
| 1416 JSArray::kLengthOffset)); |
| 1417 length_store->SetGVNFlag(kChangesArrayLengths); |
| 1418 |
| 1419 if (mode == TRACK_ALLOCATION_SITE) { |
| 1420 BuildCreateAllocationSiteInfo(array, |
| 1421 JSArray::kSize, |
| 1422 allocation_site_payload); |
| 1423 } |
| 1424 |
| 1425 int elements_location = JSArray::kSize; |
| 1426 if (mode == TRACK_ALLOCATION_SITE) { |
| 1427 elements_location += AllocationSiteInfo::kSize; |
| 1428 } |
| 1429 |
| 1430 HInnerAllocatedObject* elements = new(zone()) HInnerAllocatedObject( |
| 1431 array, |
| 1432 elements_location); |
| 1433 AddInstruction(elements); |
| 1434 |
| 1435 HInstruction* elements_store = AddInstruction( |
| 1436 new(zone()) HStoreNamedField( |
| 1437 array, |
| 1438 isolate()->factory()->elements_field_string(), |
| 1439 elements, |
| 1440 true, |
| 1441 JSArray::kElementsOffset)); |
| 1442 elements_store->SetGVNFlag(kChangesElementsPointer); |
| 1443 |
| 1444 return elements; |
| 1445 } |
| 1446 |
| 1447 |
1393 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1448 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
1394 HValue* map) { | 1449 HValue* map) { |
1395 Zone* zone = this->zone(); | 1450 Zone* zone = this->zone(); |
1396 Factory* factory = isolate()->factory(); | 1451 Factory* factory = isolate()->factory(); |
1397 Handle<String> map_field_name = factory->map_field_string(); | 1452 Handle<String> map_field_name = factory->map_field_string(); |
1398 HInstruction* store_map = | 1453 HInstruction* store_map = |
1399 new(zone) HStoreNamedField(object, map_field_name, map, | 1454 new(zone) HStoreNamedField(object, map_field_name, map, |
1400 true, JSObject::kMapOffset); | 1455 true, JSObject::kMapOffset); |
1401 store_map->SetGVNFlag(kChangesMaps); | 1456 store_map->SetGVNFlag(kChangesMaps); |
1402 AddInstruction(store_map); | 1457 AddInstruction(store_map); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 Factory* factory = isolate()->factory(); | 1551 Factory* factory = isolate()->factory(); |
1497 | 1552 |
1498 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 1553 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
1499 Zone* zone = this->zone(); | 1554 Zone* zone = this->zone(); |
1500 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 1555 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
1501 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), | 1556 ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
1502 Representation::Tagged())) | 1557 Representation::Tagged())) |
1503 : AddInstruction(new(zone) HConstant(nan_double, | 1558 : AddInstruction(new(zone) HConstant(nan_double, |
1504 Representation::Double())); | 1559 Representation::Double())); |
1505 | 1560 |
1506 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1561 // Special loop unfolding case |
| 1562 static const int kLoopUnfoldLimit = 4; |
| 1563 bool unfold_loop = false; |
| 1564 int initial_capacity = JSArray::kPreallocatedArrayElements; |
| 1565 if (from->IsConstant() && to->IsConstant() && |
| 1566 initial_capacity <= kLoopUnfoldLimit) { |
| 1567 HConstant* constant_from = HConstant::cast(from); |
| 1568 HConstant* constant_to = HConstant::cast(to); |
1507 | 1569 |
1508 HValue* key = builder.BeginBody(from, to, Token::LT); | 1570 if (constant_from->HasInteger32Value() && |
| 1571 constant_from->Integer32Value() == 0 && |
| 1572 constant_to->HasInteger32Value() && |
| 1573 constant_to->Integer32Value() == initial_capacity) { |
| 1574 unfold_loop = true; |
| 1575 } |
| 1576 } |
1509 | 1577 |
1510 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1578 if (unfold_loop) { |
| 1579 for (int i = 0; i < initial_capacity; i++) { |
| 1580 HInstruction* key = AddInstruction(new(zone) |
| 1581 HConstant(i, Representation::Integer32())); |
| 1582 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
| 1583 } |
| 1584 } else { |
| 1585 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1511 | 1586 |
1512 builder.EndBody(); | 1587 HValue* key = builder.BeginBody(from, to, Token::LT); |
| 1588 |
| 1589 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
| 1590 |
| 1591 builder.EndBody(); |
| 1592 } |
1513 } | 1593 } |
1514 | 1594 |
1515 | 1595 |
1516 void HGraphBuilder::BuildCopyElements(HValue* context, | 1596 void HGraphBuilder::BuildCopyElements(HValue* context, |
1517 HValue* from_elements, | 1597 HValue* from_elements, |
1518 ElementsKind from_elements_kind, | 1598 ElementsKind from_elements_kind, |
1519 HValue* to_elements, | 1599 HValue* to_elements, |
1520 ElementsKind to_elements_kind, | 1600 ElementsKind to_elements_kind, |
1521 HValue* length, | 1601 HValue* length, |
1522 HValue* capacity) { | 1602 HValue* capacity) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1569 if (mode == TRACK_ALLOCATION_SITE) { | 1649 if (mode == TRACK_ALLOCATION_SITE) { |
1570 size += AllocationSiteInfo::kSize; | 1650 size += AllocationSiteInfo::kSize; |
1571 } | 1651 } |
1572 int elems_offset = size; | 1652 int elems_offset = size; |
1573 if (length > 0) { | 1653 if (length > 0) { |
1574 size += IsFastDoubleElementsKind(kind) | 1654 size += IsFastDoubleElementsKind(kind) |
1575 ? FixedDoubleArray::SizeFor(length) | 1655 ? FixedDoubleArray::SizeFor(length) |
1576 : FixedArray::SizeFor(length); | 1656 : FixedArray::SizeFor(length); |
1577 } | 1657 } |
1578 | 1658 |
1579 HAllocate::Flags allocate_flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | 1659 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); |
1580 if (IsFastDoubleElementsKind(kind)) { | |
1581 allocate_flags = static_cast<HAllocate::Flags>( | |
1582 allocate_flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
1583 } | |
1584 | |
1585 // Allocate both the JS array and the elements array in one big | 1660 // Allocate both the JS array and the elements array in one big |
1586 // allocation. This avoids multiple limit checks. | 1661 // allocation. This avoids multiple limit checks. |
1587 HValue* size_in_bytes = | 1662 HValue* size_in_bytes = |
1588 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1663 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
1589 HInstruction* object = | 1664 HInstruction* object = |
1590 AddInstruction(new(zone) HAllocate(context, | 1665 AddInstruction(new(zone) HAllocate(context, |
1591 size_in_bytes, | 1666 size_in_bytes, |
1592 HType::JSObject(), | 1667 HType::JSObject(), |
1593 allocate_flags)); | 1668 allocate_flags)); |
1594 | 1669 |
1595 // Copy the JS array part. | 1670 // Copy the JS array part. |
1596 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1671 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1597 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1672 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1598 HInstruction* value = | 1673 HInstruction* value = |
1599 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); | 1674 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); |
1600 if (i != JSArray::kMapOffset) { | 1675 if (i != JSArray::kMapOffset) { |
1601 AddInstruction(new(zone) HStoreNamedField(object, | 1676 AddInstruction(new(zone) HStoreNamedField(object, |
1602 factory->empty_string(), | 1677 factory->empty_string(), |
1603 value, | 1678 value, |
1604 true, i)); | 1679 true, i)); |
1605 } else { | 1680 } else { |
1606 BuildStoreMap(object, value); | 1681 BuildStoreMap(object, value); |
1607 } | 1682 } |
1608 } | 1683 } |
1609 } | 1684 } |
1610 | 1685 |
1611 // Create an allocation site info if requested. | 1686 // Create an allocation site info if requested. |
1612 if (mode == TRACK_ALLOCATION_SITE) { | 1687 if (mode == TRACK_ALLOCATION_SITE) { |
1613 HValue* alloc_site = | 1688 BuildCreateAllocationSiteInfo(object, JSArray::kSize, boilerplate); |
1614 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); | |
1615 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
1616 BuildStoreMap(alloc_site, alloc_site_map); | |
1617 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
1618 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
1619 factory->empty_string(), | |
1620 boilerplate, | |
1621 true, alloc_payload_offset)); | |
1622 } | 1689 } |
1623 | 1690 |
1624 if (length > 0) { | 1691 if (length > 0) { |
1625 // Get hold of the elements array of the boilerplate and setup the | 1692 // Get hold of the elements array of the boilerplate and setup the |
1626 // elements pointer in the resulting object. | 1693 // elements pointer in the resulting object. |
1627 HValue* boilerplate_elements = | 1694 HValue* boilerplate_elements = |
1628 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); | 1695 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); |
1629 HValue* object_elements = | 1696 HValue* object_elements = |
1630 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1697 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
1631 AddInstruction(new(zone) HStoreNamedField(object, | 1698 AddInstruction(new(zone) HStoreNamedField(object, |
(...skipping 28 matching lines...) Expand all Loading... |
1660 key_constant, | 1727 key_constant, |
1661 value, | 1728 value, |
1662 kind)); | 1729 kind)); |
1663 } | 1730 } |
1664 } | 1731 } |
1665 | 1732 |
1666 return object; | 1733 return object; |
1667 } | 1734 } |
1668 | 1735 |
1669 | 1736 |
| 1737 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, |
| 1738 int previous_object_size, |
| 1739 HValue* payload) { |
| 1740 HInnerAllocatedObject* alloc_site = new(zone()) |
| 1741 HInnerAllocatedObject(previous_object, previous_object_size); |
| 1742 AddInstruction(alloc_site); |
| 1743 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
| 1744 BuildStoreMap(alloc_site, alloc_site_map); |
| 1745 AddInstruction(new(zone()) HStoreNamedField(alloc_site, |
| 1746 isolate()->factory()->payload_string(), |
| 1747 payload, |
| 1748 true, |
| 1749 AllocationSiteInfo::kPayloadOffset)); |
| 1750 return alloc_site; |
| 1751 } |
| 1752 |
| 1753 |
| 1754 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
| 1755 ElementsKind kind, |
| 1756 HValue* allocation_site_payload, |
| 1757 AllocationSiteMode mode) : |
| 1758 builder_(builder), |
| 1759 kind_(kind), |
| 1760 allocation_site_payload_(allocation_site_payload) { |
| 1761 if (mode == DONT_TRACK_ALLOCATION_SITE) { |
| 1762 mode_ = mode; |
| 1763 } else { |
| 1764 mode_ = AllocationSiteInfo::GetMode(kind); |
| 1765 } |
| 1766 } |
| 1767 |
| 1768 |
| 1769 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
| 1770 // Get the global context, the native context, the map array |
| 1771 HInstruction* global_object = AddInstruction(new(zone()) |
| 1772 HGlobalObject(context)); |
| 1773 HInstruction* native_context = AddInstruction(new(zone()) |
| 1774 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset)); |
| 1775 size_t offset = Context::kHeaderSize + |
| 1776 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; |
| 1777 HInstruction* map_array = AddInstruction(new(zone()) |
| 1778 HLoadNamedField(native_context, true, offset)); |
| 1779 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; |
| 1780 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset)); |
| 1781 } |
| 1782 |
| 1783 |
| 1784 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
| 1785 HValue* length_node) { |
| 1786 HValue* context = builder()->environment()->LookupContext(); |
| 1787 ASSERT(length_node != NULL); |
| 1788 |
| 1789 int base_size = JSArray::kSize; |
| 1790 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1791 base_size += AllocationSiteInfo::kSize; |
| 1792 } |
| 1793 |
| 1794 if (IsFastDoubleElementsKind(kind_)) { |
| 1795 base_size += FixedDoubleArray::kHeaderSize; |
| 1796 } else { |
| 1797 base_size += FixedArray::kHeaderSize; |
| 1798 } |
| 1799 |
| 1800 HInstruction* elements_size_value = new(zone()) |
| 1801 HConstant(elements_size(), Representation::Integer32()); |
| 1802 AddInstruction(elements_size_value); |
| 1803 HInstruction* mul = HMul::New(zone(), context, length_node, |
| 1804 elements_size_value); |
| 1805 mul->ChangeRepresentation(Representation::Integer32()); |
| 1806 mul->ClearFlag(HValue::kCanOverflow); |
| 1807 AddInstruction(mul); |
| 1808 |
| 1809 HInstruction* base = new(zone()) HConstant(base_size, |
| 1810 Representation::Integer32()); |
| 1811 AddInstruction(base); |
| 1812 HInstruction* total_size = HAdd::New(zone(), context, base, mul); |
| 1813 total_size->ChangeRepresentation(Representation::Integer32()); |
| 1814 total_size->ClearFlag(HValue::kCanOverflow); |
| 1815 AddInstruction(total_size); |
| 1816 return total_size; |
| 1817 } |
| 1818 |
| 1819 |
| 1820 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { |
| 1821 int base_size = JSArray::kSize; |
| 1822 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1823 base_size += AllocationSiteInfo::kSize; |
| 1824 } |
| 1825 |
| 1826 base_size += IsFastDoubleElementsKind(kind_) |
| 1827 ? FixedDoubleArray::SizeFor(initial_capacity()) |
| 1828 : FixedArray::SizeFor(initial_capacity()); |
| 1829 |
| 1830 HConstant* array_size = |
| 1831 new(zone()) HConstant(base_size, Representation::Integer32()); |
| 1832 AddInstruction(array_size); |
| 1833 return array_size; |
| 1834 } |
| 1835 |
| 1836 |
| 1837 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 1838 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); |
| 1839 HConstant* capacity = |
| 1840 new(zone()) HConstant(initial_capacity(), Representation::Integer32()); |
| 1841 AddInstruction(capacity); |
| 1842 return AllocateArray(size_in_bytes, |
| 1843 capacity, |
| 1844 builder()->graph()->GetConstant0(), |
| 1845 true); |
| 1846 } |
| 1847 |
| 1848 |
| 1849 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity, |
| 1850 HValue* length_field, |
| 1851 bool fill_with_hole) { |
| 1852 HValue* size_in_bytes = EstablishAllocationSize(capacity); |
| 1853 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); |
| 1854 } |
| 1855 |
| 1856 |
| 1857 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
| 1858 HValue* capacity, |
| 1859 HValue* length_field, |
| 1860 bool fill_with_hole) { |
| 1861 HValue* context = builder()->environment()->LookupContext(); |
| 1862 |
| 1863 // Allocate (dealing with failure appropriately) |
| 1864 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
| 1865 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, |
| 1866 HType::JSArray(), flags); |
| 1867 AddInstruction(new_object); |
| 1868 |
| 1869 // Fill in the fields: map, properties, length |
| 1870 HValue* map = EmitMapCode(context); |
| 1871 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
| 1872 map, |
| 1873 mode_, |
| 1874 allocation_site_payload_, |
| 1875 length_field); |
| 1876 |
| 1877 // Initialize the elements |
| 1878 builder()->BuildInitializeElements(elements_location_, kind_, capacity); |
| 1879 |
| 1880 if (fill_with_hole) { |
| 1881 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
| 1882 graph()->GetConstant0(), capacity); |
| 1883 } |
| 1884 |
| 1885 return new_object; |
| 1886 } |
| 1887 |
| 1888 |
1670 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1889 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
1671 TypeFeedbackOracle* oracle) | 1890 TypeFeedbackOracle* oracle) |
1672 : HGraphBuilder(info), | 1891 : HGraphBuilder(info), |
1673 function_state_(NULL), | 1892 function_state_(NULL), |
1674 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1893 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
1675 ast_context_(NULL), | 1894 ast_context_(NULL), |
1676 break_scope_(NULL), | 1895 break_scope_(NULL), |
1677 inlined_count_(0), | 1896 inlined_count_(0), |
1678 globals_(10, info->zone()), | 1897 globals_(10, info->zone()), |
1679 inline_bailout_(false) { | 1898 inline_bailout_(false) { |
(...skipping 7528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9208 receiver->DeleteAndReplaceWith(NULL); | 9427 receiver->DeleteAndReplaceWith(NULL); |
9209 check->DeleteAndReplaceWith(NULL); | 9428 check->DeleteAndReplaceWith(NULL); |
9210 environment()->SetExpressionStackAt(receiver_index, function); | 9429 environment()->SetExpressionStackAt(receiver_index, function); |
9211 HInstruction* call = PreProcessCall( | 9430 HInstruction* call = PreProcessCall( |
9212 new(zone()) HCallNew(context, function, argument_count)); | 9431 new(zone()) HCallNew(context, function, argument_count)); |
9213 call->set_position(expr->position()); | 9432 call->set_position(expr->position()); |
9214 return ast_context()->ReturnInstruction(call, expr->id()); | 9433 return ast_context()->ReturnInstruction(call, expr->id()); |
9215 } else { | 9434 } else { |
9216 // The constructor function is both an operand to the instruction and an | 9435 // The constructor function is both an operand to the instruction and an |
9217 // argument to the construct call. | 9436 // argument to the construct call. |
| 9437 bool use_call_new_array = FLAG_optimize_constructed_arrays && |
| 9438 !(expr->target().is_null()) && |
| 9439 *(expr->target()) == isolate()->global_context()->array_function(); |
| 9440 |
9218 CHECK_ALIVE(VisitArgument(expr->expression())); | 9441 CHECK_ALIVE(VisitArgument(expr->expression())); |
9219 HValue* constructor = HPushArgument::cast(Top())->argument(); | 9442 HValue* constructor = HPushArgument::cast(Top())->argument(); |
9220 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 9443 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
9221 HCallNew* call; | 9444 HCallNew* call; |
9222 if (FLAG_optimize_constructed_arrays && | 9445 if (use_call_new_array) { |
9223 !(expr->target().is_null()) && | 9446 AddInstruction(new(zone()) HCheckFunction(constructor, |
9224 *(expr->target()) == isolate()->global_context()->array_function()) { | 9447 Handle<JSFunction>(isolate()->global_context()->array_function()))); |
9225 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); | 9448 Handle<Object> feedback = oracle()->GetInfo(expr->CallNewFeedbackId()); |
9226 ASSERT(feedback->IsSmi()); | 9449 ASSERT(feedback->IsSmi()); |
| 9450 |
| 9451 // TODO(mvstanton): It would be better to use the already created global |
| 9452 // property cell that is shared by full code gen. That way, any transition |
| 9453 // information that happened after crankshaft won't be lost. The right |
| 9454 // way to do that is to begin passing the cell to the type feedback oracle |
| 9455 // instead of just the value in the cell. Do this in a follow-up checkin. |
9227 Handle<JSGlobalPropertyCell> cell = | 9456 Handle<JSGlobalPropertyCell> cell = |
9228 isolate()->factory()->NewJSGlobalPropertyCell(feedback); | 9457 isolate()->factory()->NewJSGlobalPropertyCell(feedback); |
9229 AddInstruction(new(zone()) HCheckFunction(constructor, | 9458 |
9230 Handle<JSFunction>(isolate()->global_context()->array_function()))); | 9459 // TODO(mvstanton): Here we should probably insert code to check if the |
| 9460 // type cell elements kind is different from when we compiled, and deopt |
| 9461 // in that case. Do this in a follow-up checin. |
9231 call = new(zone()) HCallNewArray(context, constructor, argument_count, | 9462 call = new(zone()) HCallNewArray(context, constructor, argument_count, |
9232 cell); | 9463 cell); |
9233 } else { | 9464 } else { |
9234 call = new(zone()) HCallNew(context, constructor, argument_count); | 9465 call = new(zone()) HCallNew(context, constructor, argument_count); |
9235 } | 9466 } |
9236 Drop(argument_count); | 9467 Drop(argument_count); |
9237 call->set_position(expr->position()); | 9468 call->set_position(expr->position()); |
9238 return ast_context()->ReturnInstruction(call, expr->id()); | 9469 return ast_context()->ReturnInstruction(call, expr->id()); |
9239 } | 9470 } |
9240 } | 9471 } |
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10333 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10564 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10334 value, Representation::Tagged())); | 10565 value, Representation::Tagged())); |
10335 AddInstruction(new(zone) HStoreNamedField( | 10566 AddInstruction(new(zone) HStoreNamedField( |
10336 object_properties, factory->unknown_field_string(), value_instruction, | 10567 object_properties, factory->unknown_field_string(), value_instruction, |
10337 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10568 true, boilerplate_object->GetInObjectPropertyOffset(i))); |
10338 } | 10569 } |
10339 } | 10570 } |
10340 | 10571 |
10341 // Build Allocation Site Info if desired | 10572 // Build Allocation Site Info if desired |
10342 if (create_allocation_site_info) { | 10573 if (create_allocation_site_info) { |
10343 HValue* alloc_site = | 10574 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10344 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); | |
10345 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | |
10346 BuildStoreMap(alloc_site, alloc_site_map); | |
10347 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | |
10348 AddInstruction(new(zone) HStoreNamedField(alloc_site, | |
10349 factory->payload_string(), | |
10350 original_boilerplate, | |
10351 true, alloc_payload_offset)); | |
10352 } | 10575 } |
10353 | 10576 |
10354 if (object_elements != NULL) { | 10577 if (object_elements != NULL) { |
10355 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10578 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
10356 elements, Representation::Tagged())); | 10579 elements, Representation::Tagged())); |
10357 | 10580 |
10358 int elements_length = elements->length(); | 10581 int elements_length = elements->length(); |
10359 HValue* object_elements_length = | 10582 HValue* object_elements_length = |
10360 AddInstruction(new(zone) HConstant( | 10583 AddInstruction(new(zone) HConstant( |
10361 elements_length, Representation::Integer32())); | 10584 elements_length, Representation::Integer32())); |
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11811 } | 12034 } |
11812 } | 12035 } |
11813 | 12036 |
11814 #ifdef DEBUG | 12037 #ifdef DEBUG |
11815 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12038 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11816 if (allocator_ != NULL) allocator_->Verify(); | 12039 if (allocator_ != NULL) allocator_->Verify(); |
11817 #endif | 12040 #endif |
11818 } | 12041 } |
11819 | 12042 |
11820 } } // namespace v8::internal | 12043 } } // namespace v8::internal |
OLD | NEW |