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