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 |