Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(305)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 1238143002: [stubs] Optimize LoadGlobalViaContextStub and StoreGlobalViaContextStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix ARM typo. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/field-index.h" 9 #include "src/field-index.h"
10 #include "src/hydrogen.h" 10 #include "src/hydrogen.h"
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 return value; 1616 return value;
1617 } 1617 }
1618 1618
1619 1619
1620 Handle<Code> StoreGlobalStub::GenerateCode() { 1620 Handle<Code> StoreGlobalStub::GenerateCode() {
1621 return DoGenerateCode(this); 1621 return DoGenerateCode(this);
1622 } 1622 }
1623 1623
1624 1624
1625 template <> 1625 template <>
1626 HValue* CodeStubGraphBuilder<LoadGlobalViaContextStub>::BuildCodeStub() {
1627 LoadGlobalViaContextStub* stub = casted_stub();
1628 int depth_value = stub->depth();
1629 HValue* depth = GetParameter(0);
1630 HValue* slot_index = GetParameter(1);
1631 HValue* name = GetParameter(2);
1632
1633 // Choose between dynamic or static context script fetching versions.
1634 depth = depth_value < LoadGlobalViaContextStub::kDynamicDepth
1635 ? nullptr
1636 : AddUncasted<HForceRepresentation>(depth, Representation::Smi());
1637 slot_index =
1638 AddUncasted<HForceRepresentation>(slot_index, Representation::Smi());
1639
1640 HValue* script_context = BuildGetParentContext(depth, depth_value);
1641 HValue* cell =
1642 Add<HLoadKeyed>(script_context, slot_index, nullptr, FAST_ELEMENTS);
1643
1644 HValue* value = Add<HLoadNamedField>(cell, nullptr,
1645 HObjectAccess::ForPropertyCellValue());
1646
1647 IfBuilder builder(this);
1648 HValue* hole_value = graph()->GetConstantHole();
1649 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(value, hole_value);
1650 builder.Then();
1651 { Push(value); }
1652 builder.Else();
1653 {
1654 Add<HPushArguments>(script_context, slot_index, name);
1655 Push(Add<HCallRuntime>(
1656 isolate()->factory()->empty_string(),
1657 Runtime::FunctionForId(Runtime::kLoadGlobalViaContext), 3));
1658 }
1659 builder.End();
1660 return Pop();
1661 }
1662
1663
1664 Handle<Code> LoadGlobalViaContextStub::GenerateCode() {
1665 return DoGenerateCode(this);
1666 }
1667
1668
1669 template <>
1670 HValue* CodeStubGraphBuilder<StoreGlobalViaContextStub>::BuildCodeStub() {
1671 StoreGlobalViaContextStub* stub = casted_stub();
1672 int depth_value = stub->depth();
1673 HValue* depth = GetParameter(0);
1674 HValue* slot_index = GetParameter(1);
1675 HValue* name = GetParameter(2);
1676 HValue* value = GetParameter(3);
1677
1678 // Choose between dynamic or static context script fetching versions.
1679 depth = depth_value < StoreGlobalViaContextStub::kDynamicDepth
1680 ? nullptr
1681 : AddUncasted<HForceRepresentation>(depth, Representation::Smi());
1682 slot_index =
1683 AddUncasted<HForceRepresentation>(slot_index, Representation::Smi());
1684
1685 HValue* script_context = BuildGetParentContext(depth, depth_value);
1686 HValue* cell =
1687 Add<HLoadKeyed>(script_context, slot_index, nullptr, FAST_ELEMENTS);
1688
1689 // Fast case that requires storing to cell.
1690 HIfContinuation if_fast_store_continuation(graph()->CreateBasicBlock(),
1691 graph()->CreateBasicBlock());
1692
1693 // Fast case that does not require storing to cell.
1694 HIfContinuation if_fast_no_store_continuation(graph()->CreateBasicBlock(),
1695 graph()->CreateBasicBlock());
1696
1697 // This stub does the same as StoreGlobalStub but in a dynamic manner.
1698
1699 HValue* cell_contents = Add<HLoadNamedField>(
1700 cell, nullptr, HObjectAccess::ForPropertyCellValue());
1701
1702 IfBuilder if_hole(this);
1703 HValue* hole_value = graph()->GetConstantHole();
1704 if_hole.IfNot<HCompareObjectEqAndBranch, HValue*>(cell_contents, hole_value);
1705 if_hole.Then();
1706 {
1707 HValue* details = Add<HLoadNamedField>(
1708 cell, nullptr, HObjectAccess::ForPropertyCellDetails());
1709 HValue* cell_type =
1710 BuildDecodeField<PropertyDetails::PropertyCellTypeField>(details);
1711
1712 // The code below relies on this.
1713 STATIC_ASSERT(PropertyCellType::kUndefined < PropertyCellType::kConstant);
1714 STATIC_ASSERT(PropertyCellType::kConstant <
1715 PropertyCellType::kConstantType);
1716 STATIC_ASSERT(PropertyCellType::kConstant < PropertyCellType::kMutable);
1717
1718 // Handle all cell type cases.
1719 IfBuilder if_not_const(this);
1720
1721 int cell_type_constant = static_cast<int>(PropertyCellType::kConstant);
1722 if_not_const.If<HCompareNumericAndBranch, HValue*>(
1723 cell_type, Add<HConstant>(cell_type_constant), Token::GT);
1724 if_not_const.Then();
1725 {
1726 // kConstantType or kMutable.
1727 IfBuilder if_const_type(this);
1728 int cell_type_constant_type =
1729 static_cast<int>(PropertyCellType::kConstantType);
1730 if_const_type.If<HCompareNumericAndBranch, HValue*>(
1731 cell_type, Add<HConstant>(cell_type_constant_type), Token::EQ);
1732 if_const_type.Then();
1733 {
1734 // Check that either both value and cell_contents are smi or
1735 // both have the same map.
1736 IfBuilder if_cell_is_smi(this);
1737 if_cell_is_smi.If<HIsSmiAndBranch>(cell_contents);
1738 if_cell_is_smi.Then();
1739 {
1740 IfBuilder if_value_is_smi(this);
1741 if_value_is_smi.If<HIsSmiAndBranch>(value);
1742 if_value_is_smi.Then();
1743 {
1744 // Both cell_contents and value are smis, do store.
1745 }
1746 if_value_is_smi.Else(); // Slow case.
1747 if_value_is_smi.JoinContinuation(&if_fast_store_continuation);
1748 }
1749 if_cell_is_smi.Else();
1750 {
1751 IfBuilder if_value_is_heap_object(this);
1752 if_value_is_heap_object.IfNot<HIsSmiAndBranch>(value);
1753 if_value_is_heap_object.Then();
1754 {
1755 // Both cell_contents and value are heap objects, do store.
1756 HValue* expected_map = Add<HLoadNamedField>(
1757 cell_contents, nullptr, HObjectAccess::ForMap());
1758 HValue* map =
1759 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
1760 IfBuilder map_check(this);
1761 map_check.If<HCompareObjectEqAndBranch>(expected_map, map);
1762 map_check.Then();
1763 map_check.Else(); // Slow case.
1764 map_check.JoinContinuation(&if_fast_store_continuation);
1765
1766 // The accessor case is handled by the map check above, since
1767 // the value must not have a AccessorPair map.
1768 }
1769 if_value_is_heap_object.Else(); // Slow case.
1770 if_value_is_heap_object.JoinContinuation(&if_fast_store_continuation);
1771 }
1772 if_cell_is_smi.EndUnreachable();
1773 }
1774 if_const_type.Else();
1775 {
1776 // Check that the property kind is kData.
1777 HValue* kind = BuildDecodeField<PropertyDetails::KindField>(details);
1778 HValue* data_kind_value = Add<HConstant>(kData);
1779
1780 IfBuilder builder(this);
1781 builder.If<HCompareNumericAndBranch, HValue*>(kind, data_kind_value,
1782 Token::EQ);
1783 builder.Then();
1784 builder.Else(); // Slow case.
1785 builder.JoinContinuation(&if_fast_store_continuation);
1786 }
1787 if_const_type.EndUnreachable();
1788 }
1789 if_not_const.Else();
1790 {
1791 // kUndefined or kConstant, just check that the value matches.
1792 IfBuilder builder(this);
1793 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1794 builder.Then();
1795 builder.Else(); // Slow case.
1796 builder.JoinContinuation(&if_fast_no_store_continuation);
1797 }
1798 if_not_const.EndUnreachable();
1799 }
1800 if_hole.Else(); // Slow case.
1801 if_hole.JoinContinuation(&if_fast_store_continuation);
1802
1803 // Do store for fast case.
1804 IfBuilder if_fast_store(this, &if_fast_store_continuation);
1805 if_fast_store.Then();
1806 {
1807 // All checks are done, store the value to the cell.
1808 Add<HStoreNamedField>(cell, HObjectAccess::ForPropertyCellValue(), value);
1809 }
1810 if_fast_store.Else();
1811 if_fast_store.JoinContinuation(&if_fast_no_store_continuation);
1812
1813 // Bailout to runtime call for slow case.
1814 IfBuilder if_no_fast_store(this, &if_fast_no_store_continuation);
1815 if_no_fast_store.Then();
1816 {
1817 // Nothing else to do.
1818 }
1819 if_no_fast_store.Else();
1820 {
1821 // Slow case, call runtime.
1822 HInstruction* lang_mode = Add<HConstant>(casted_stub()->language_mode());
1823 Add<HPushArguments>(script_context, slot_index, name, value);
1824 Add<HPushArguments>(lang_mode);
1825 Add<HCallRuntime>(isolate()->factory()->empty_string(),
1826 Runtime::FunctionForId(Runtime::kStoreGlobalViaContext),
1827 5);
1828 }
1829 if_no_fast_store.End();
1830 return value;
1831 }
1832
1833
1834 Handle<Code> StoreGlobalViaContextStub::GenerateCode() {
1835 return DoGenerateCode(this);
1836 }
1837
1838
1839 template <>
1840 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() { 1626 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
1841 HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex); 1627 HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex);
1842 HValue* key = GetParameter(StoreTransitionDescriptor::kNameIndex); 1628 HValue* key = GetParameter(StoreTransitionDescriptor::kNameIndex);
1843 HValue* value = GetParameter(StoreTransitionDescriptor::kValueIndex); 1629 HValue* value = GetParameter(StoreTransitionDescriptor::kValueIndex);
1844 HValue* map = GetParameter(StoreTransitionDescriptor::kMapIndex); 1630 HValue* map = GetParameter(StoreTransitionDescriptor::kMapIndex);
1845 1631
1846 if (FLAG_trace_elements_transitions) { 1632 if (FLAG_trace_elements_transitions) {
1847 // Tracing elements transitions is the job of the runtime. 1633 // Tracing elements transitions is the job of the runtime.
1848 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions, 1634 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions,
1849 Deoptimizer::EAGER); 1635 Deoptimizer::EAGER);
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 return Pop(); 2270 return Pop();
2485 } 2271 }
2486 2272
2487 2273
2488 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2274 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2489 return DoGenerateCode(this); 2275 return DoGenerateCode(this);
2490 } 2276 }
2491 2277
2492 } // namespace internal 2278 } // namespace internal
2493 } // namespace v8 2279 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698