Chromium Code Reviews| 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 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1322 store_map->SetGVNFlag(kChangesMaps); | 1322 store_map->SetGVNFlag(kChangesMaps); |
| 1323 AddInstruction(store_map); | 1323 AddInstruction(store_map); |
| 1324 return store_map; | 1324 return store_map; |
| 1325 } | 1325 } |
| 1326 | 1326 |
| 1327 | 1327 |
| 1328 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1328 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1329 Handle<Map> map, | 1329 Handle<Map> map, |
| 1330 BailoutId id) { | 1330 BailoutId id) { |
| 1331 Zone* zone = this->zone(); | 1331 Zone* zone = this->zone(); |
| 1332 HValue* map_constant = | 1332 HConstant* map_constant = new(zone) HConstant(map, Representation::Tagged()); |
| 1333 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); | 1333 AddInstruction(map_constant); |
| 1334 return BuildStoreMap(object, map_constant, id); | 1334 return BuildStoreMap(object, map_constant, id); |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 | 1337 |
| 1338 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1338 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
| 1339 HValue* old_capacity) { | 1339 HValue* old_capacity) { |
| 1340 Zone* zone = this->zone(); | 1340 Zone* zone = this->zone(); |
| 1341 HValue* half_old_capacity = | 1341 HValue* half_old_capacity = |
| 1342 AddInstruction(HShr::New(zone, context, old_capacity, | 1342 AddInstruction(HShr::New(zone, context, old_capacity, |
| 1343 graph_->GetConstant1())); | 1343 graph_->GetConstant1())); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1583 key_constant, | 1583 key_constant, |
| 1584 value, | 1584 value, |
| 1585 kind)); | 1585 kind)); |
| 1586 } | 1586 } |
| 1587 } | 1587 } |
| 1588 | 1588 |
| 1589 return object; | 1589 return object; |
| 1590 } | 1590 } |
| 1591 | 1591 |
| 1592 | 1592 |
| 1593 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | |
| 1594 ElementsKind kind, | |
| 1595 HValue* allocation_site_payload) : | |
| 1596 builder_(builder), | |
| 1597 kind_(kind), | |
| 1598 allocation_site_payload_(allocation_site_payload) { | |
| 1599 // Determine mode | |
| 1600 mode_ = AllocationSiteInfo::GetMode(kind); | |
| 1601 } | |
| 1602 | |
| 1603 | |
| 1604 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | |
| 1605 // Get the global context, the native context, the map array | |
| 1606 HInstruction* global_object = AddInstruction(new(zone()) | |
| 1607 HGlobalObject(context)); | |
| 1608 HInstruction* native_context = AddInstruction(new(zone()) | |
| 1609 HLoadNamedField(global_object, true, GlobalObject::kNativeContextOffset)); | |
| 1610 size_t offset = Context::kHeaderSize + | |
| 1611 kPointerSize * Context::JS_ARRAY_MAPS_INDEX; | |
| 1612 HInstruction* map_array = AddInstruction(new(zone()) | |
| 1613 HLoadNamedField(native_context, true, offset)); | |
| 1614 offset = kind_ * kPointerSize + FixedArrayBase::kHeaderSize; | |
| 1615 return AddInstruction(new(zone()) HLoadNamedField(map_array, true, offset)); | |
| 1616 } | |
| 1617 | |
| 1618 | |
| 1619 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | |
| 1620 HValue* length_node) { | |
| 1621 HValue* context = builder()->environment()->LookupContext(); | |
| 1622 ASSERT(length_node != NULL); | |
| 1623 | |
| 1624 int base_size = JSArray::kSize; | |
| 1625 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 1626 base_size += AllocationSiteInfo::kSize; | |
| 1627 } | |
| 1628 | |
| 1629 if (IsFastDoubleElementsKind(kind_)) { | |
| 1630 base_size += FixedDoubleArray::kHeaderSize; | |
| 1631 } else { | |
| 1632 base_size += FixedArray::kHeaderSize; | |
| 1633 } | |
| 1634 | |
| 1635 HInstruction* elements_size_value = new(zone()) | |
| 1636 HConstant(elements_size(), Representation::Integer32()); | |
| 1637 AddInstruction(elements_size_value); | |
| 1638 HInstruction* mul = HMul::New(zone(), context, length_node, | |
| 1639 elements_size_value); | |
| 1640 mul->ChangeRepresentation(Representation::Integer32()); | |
| 1641 mul->ClearFlag(HValue::kCanOverflow); | |
| 1642 AddInstruction(mul); | |
| 1643 AddSimulate(); | |
| 1644 | |
| 1645 HInstruction* base = new(zone()) HConstant(base_size, | |
| 1646 Representation::Integer32()); | |
| 1647 AddInstruction(base); | |
| 1648 HInstruction* total_size = HAdd::New(zone(), context, base, mul); | |
| 1649 total_size->ChangeRepresentation(Representation::Integer32()); | |
| 1650 total_size->ClearFlag(HValue::kCanOverflow); | |
| 1651 AddInstruction(total_size); | |
| 1652 AddSimulate(); | |
| 1653 return total_size; | |
| 1654 } | |
| 1655 | |
| 1656 | |
| 1657 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { | |
| 1658 int base_size = JSArray::kSize; | |
| 1659 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 1660 base_size += AllocationSiteInfo::kSize; | |
| 1661 } | |
| 1662 | |
| 1663 if (initial_capacity() > 0) { | |
| 1664 base_size += IsFastDoubleElementsKind(kind_) | |
| 1665 ? FixedDoubleArray::SizeFor(initial_capacity()) | |
| 1666 : FixedArray::SizeFor(initial_capacity()); | |
| 1667 } | |
| 1668 | |
| 1669 HConstant* array_size = | |
| 1670 new(zone()) HConstant(base_size, Representation::Integer32()); | |
| 1671 AddInstruction(array_size); | |
| 1672 return array_size; | |
| 1673 } | |
| 1674 | |
| 1675 | |
| 1676 HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | |
| 1677 HValue* size_in_bytes = EstablishEmptyArrayAllocationSize(); | |
| 1678 HConstant* capacity = | |
| 1679 new(zone()) HConstant(initial_capacity(), Representation::Integer32()); | |
| 1680 AddInstruction(capacity); | |
| 1681 return AllocateArray(size_in_bytes, capacity, NULL, true); | |
| 1682 } | |
| 1683 | |
| 1684 | |
| 1685 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | |
| 1686 HValue* capacity, | |
| 1687 HValue* length_field, | |
| 1688 bool fill_with_hole) { | |
| 1689 HValue* context = builder()->environment()->LookupContext(); | |
| 1690 Isolate* isolate = builder()->graph()->isolate(); | |
|
mvstanton
2013/04/15 15:14:49
Hannes: How about for symmetry with BuildCopyObjec
mvstanton
2013/04/16 11:48:52
Done. And I continued in this spirit, finding seve
| |
| 1691 | |
| 1692 // Allocate (dealing with failure appropriately) | |
| 1693 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; | |
| 1694 if (IsFastDoubleElementsKind(kind_)) { | |
| 1695 flags = static_cast<HAllocate::Flags>( | |
| 1696 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); | |
| 1697 } | |
| 1698 | |
| 1699 HAllocate* new_object = new(zone()) HAllocate(context, size_in_bytes, | |
|
mvstanton
2013/04/15 15:14:49
Hannes: How about if HAllocate deals with the ALLO
mvstanton
2013/04/16 11:48:52
I made a useful helper function to improve this. I
| |
| 1700 HType::JSArray(), flags); | |
| 1701 AddInstruction(new_object); | |
| 1702 | |
| 1703 // Fill in the fields: map, properties, length | |
| 1704 HValue* map = EmitMapCode(context); | |
| 1705 builder()->BuildStoreMap(new_object, map, BailoutId::StubEntry()); | |
| 1706 | |
| 1707 HConstant* empty_fixed_array = | |
| 1708 new(zone()) HConstant( | |
| 1709 Handle<FixedArray>(isolate->heap()->empty_fixed_array()), | |
| 1710 Representation::Tagged()); | |
| 1711 AddInstruction(empty_fixed_array); | |
| 1712 | |
| 1713 AddInstruction(new(zone()) HStoreNamedField(new_object, | |
| 1714 isolate->factory()->properties_field_symbol(), | |
| 1715 empty_fixed_array, | |
| 1716 true, | |
| 1717 JSArray::kPropertiesOffset)); | |
| 1718 AddSimulate(FIXED_SIMULATE); | |
| 1719 | |
| 1720 HValue* zero = builder()->graph()->GetConstant0(); | |
| 1721 HValue* array_length_field = zero; | |
| 1722 if (length_field != NULL) { | |
| 1723 array_length_field = length_field; | |
| 1724 } | |
| 1725 AddInstruction(new(zone()) HStoreNamedField(new_object, | |
| 1726 isolate->factory()->length_field_string(), | |
| 1727 array_length_field, | |
| 1728 true, | |
| 1729 JSArray::kLengthOffset)); | |
| 1730 AddSimulate(FIXED_SIMULATE); | |
| 1731 | |
| 1732 if (mode_ == TRACK_ALLOCATION_SITE) { | |
|
mvstanton
2013/04/15 15:14:49
Hannes: Factor this out to combine with the piece
mvstanton
2013/04/16 11:48:52
Done.
| |
| 1733 // Fill in the payload | |
| 1734 HInnerAllocatedObject* allocation_info_site = new(zone()) | |
| 1735 HInnerAllocatedObject(new_object, JSArray::kSize); | |
| 1736 AddInstruction(allocation_info_site); | |
| 1737 builder()->BuildStoreMap(allocation_info_site, | |
| 1738 Handle<Map>(isolate->heap()->allocation_site_info_map()), | |
| 1739 BailoutId::StubEntry()); | |
| 1740 AddInstruction(new(zone()) HStoreNamedField(allocation_info_site, | |
| 1741 isolate->factory()->payload_field_symbol(), | |
| 1742 allocation_site_payload_, | |
| 1743 true, | |
| 1744 AllocationSiteInfo::kPayloadOffset)); | |
| 1745 AddSimulate(FIXED_SIMULATE); | |
| 1746 } | |
| 1747 | |
| 1748 if (length_field == NULL && initial_capacity() == 0) { | |
| 1749 AddInstruction(new(zone()) HStoreNamedField(new_object, | |
| 1750 isolate->factory()->elements_field_string(), | |
| 1751 empty_fixed_array, | |
| 1752 true, | |
| 1753 JSArray::kElementsOffset)); | |
| 1754 AddSimulate(FIXED_SIMULATE); | |
| 1755 } else { | |
| 1756 int elements_location = JSArray::kSize; | |
| 1757 if (mode_ == TRACK_ALLOCATION_SITE) { | |
| 1758 elements_location += AllocationSiteInfo::kSize; | |
| 1759 } | |
| 1760 | |
| 1761 elements_location_ = new(zone()) HInnerAllocatedObject(new_object, | |
| 1762 elements_location); | |
| 1763 AddInstruction(elements_location_); | |
| 1764 | |
| 1765 AddInstruction(new(zone()) HStoreNamedField(new_object, | |
| 1766 isolate->factory()->elements_field_string(), | |
| 1767 elements_location_, | |
| 1768 true, | |
| 1769 JSArray::kElementsOffset)); | |
| 1770 AddSimulate(FIXED_SIMULATE); | |
| 1771 | |
| 1772 // Initialize the elements | |
| 1773 Handle<Map> map_elements = IsFastDoubleElementsKind(kind_) | |
| 1774 ? isolate->factory()->fixed_double_array_map() | |
| 1775 : isolate->factory()->fixed_array_map(); | |
| 1776 builder()->BuildStoreMap(elements_location_, map_elements, | |
| 1777 BailoutId::StubEntry()); | |
| 1778 | |
| 1779 Handle<String> fixed_array_length_field_name = | |
| 1780 isolate->factory()->length_field_string(); | |
| 1781 HInstruction* store_length = | |
| 1782 new(zone()) HStoreNamedField(elements_location_, | |
| 1783 fixed_array_length_field_name, | |
| 1784 capacity, | |
| 1785 true, | |
| 1786 FixedArray::kLengthOffset); | |
| 1787 AddInstruction(store_length); | |
| 1788 AddSimulate(FIXED_SIMULATE); | |
| 1789 | |
| 1790 if (fill_with_hole) { | |
| 1791 FillWithHole(capacity, length_field == NULL); | |
| 1792 } | |
| 1793 } | |
| 1794 | |
| 1795 return new_object; | |
| 1796 } | |
| 1797 | |
| 1798 | |
| 1799 void HGraphBuilder::JSArrayBuilder::FillWithHole(HValue* capacity, | |
| 1800 bool nominally_empty) { | |
| 1801 Isolate* isolate = builder()->graph()->isolate(); | |
| 1802 HValue* context = builder()->environment()->LookupContext(); | |
| 1803 double nan_double = FixedDoubleArray::hole_nan_as_double(); | |
| 1804 HConstant* hole = (IsFastSmiElementsKind(kind_) || | |
| 1805 IsFastObjectElementsKind(kind_)) | |
|
mvstanton
2013/04/15 15:14:49
lines above replace with IsFastDoubleElementsKind(
mvstanton
2013/04/16 11:48:52
Done. Actually I could merge this function with an
| |
| 1806 ? new(zone()) HConstant(isolate->factory()->the_hole_value(), | |
| 1807 Representation::Tagged()) | |
| 1808 : new(zone()) HConstant(nan_double, Representation::Double()); | |
| 1809 | |
| 1810 AddInstruction(hole); | |
| 1811 | |
| 1812 static const int kLoopUnfoldLimit = 4; | |
| 1813 if (nominally_empty && initial_capacity() <= kLoopUnfoldLimit) { | |
|
mvstanton
2013/04/15 15:14:49
move kLoopUnfoldLimit up to initial_capacity() def
| |
| 1814 for (int i = 0; i < initial_capacity(); i ++) { | |
| 1815 HInstruction* key; | |
| 1816 if (i == 0) { | |
| 1817 key = graph()->GetConstant0(); | |
| 1818 } else if (i == 1) { | |
| 1819 key = graph()->GetConstant1(); | |
| 1820 } else { | |
| 1821 key = AddInstruction(new(zone()) | |
| 1822 HConstant(i, Representation::Integer32())); | |
| 1823 } | |
| 1824 AddInstruction(new(zone()) HStoreKeyed(elements_location_, key, hole, | |
| 1825 kind_)); | |
| 1826 AddSimulate(REMOVABLE_SIMULATE); | |
| 1827 } | |
| 1828 } else { | |
| 1829 LoopBuilder loop_builder(builder(), | |
| 1830 context, | |
| 1831 LoopBuilder::kPostIncrement); | |
| 1832 HValue* zero = graph()->GetConstant0(); | |
| 1833 HValue* start = zero; | |
| 1834 HValue* key = loop_builder.BeginBody(start, capacity, Token::LT); | |
| 1835 | |
| 1836 AddInstruction(new(zone()) HStoreKeyed(elements_location_, key, hole, | |
| 1837 kind_)); | |
| 1838 AddSimulate(REMOVABLE_SIMULATE); | |
| 1839 loop_builder.EndBody(); | |
| 1840 } | |
| 1841 } | |
| 1842 | |
| 1843 | |
| 1593 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1844 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
| 1594 TypeFeedbackOracle* oracle) | 1845 TypeFeedbackOracle* oracle) |
| 1595 : HGraphBuilder(info), | 1846 : HGraphBuilder(info), |
| 1596 function_state_(NULL), | 1847 function_state_(NULL), |
| 1597 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1848 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
| 1598 ast_context_(NULL), | 1849 ast_context_(NULL), |
| 1599 break_scope_(NULL), | 1850 break_scope_(NULL), |
| 1600 inlined_count_(0), | 1851 inlined_count_(0), |
| 1601 globals_(10, info->zone()), | 1852 globals_(10, info->zone()), |
| 1602 inline_bailout_(false) { | 1853 inline_bailout_(false) { |
| (...skipping 10052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11655 } | 11906 } |
| 11656 } | 11907 } |
| 11657 | 11908 |
| 11658 #ifdef DEBUG | 11909 #ifdef DEBUG |
| 11659 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11910 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11660 if (allocator_ != NULL) allocator_->Verify(); | 11911 if (allocator_ != NULL) allocator_->Verify(); |
| 11661 #endif | 11912 #endif |
| 11662 } | 11913 } |
| 11663 | 11914 |
| 11664 } } // namespace v8::internal | 11915 } } // namespace v8::internal |
| OLD | NEW |