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

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: ia32 port. small x64 beautification. 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 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 return value; 1607 return value;
1608 } 1608 }
1609 1609
1610 1610
1611 Handle<Code> StoreGlobalStub::GenerateCode() { 1611 Handle<Code> StoreGlobalStub::GenerateCode() {
1612 return DoGenerateCode(this); 1612 return DoGenerateCode(this);
1613 } 1613 }
1614 1614
1615 1615
1616 template <> 1616 template <>
1617 HValue* CodeStubGraphBuilder<LoadGlobalViaContextStub>::BuildCodeStub() {
1618 LoadGlobalViaContextStub* stub = casted_stub();
1619 int depth_value = stub->depth();
1620 HValue* depth = GetParameter(0);
1621 HValue* slot_index = GetParameter(1);
1622 HValue* name = GetParameter(2);
1623
1624 // Choose between dynamic or static context script fetching versions.
1625 depth = depth_value < LoadGlobalViaContextStub::kDynamicDepth
1626 ? nullptr
1627 : AddUncasted<HForceRepresentation>(depth, Representation::Smi());
1628 slot_index =
1629 AddUncasted<HForceRepresentation>(slot_index, Representation::Smi());
1630
1631 HValue* script_context = BuildGetParentContext(depth, depth_value);
1632 HValue* cell =
1633 Add<HLoadKeyed>(script_context, slot_index, nullptr, FAST_ELEMENTS);
1634
1635 HValue* value = Add<HLoadNamedField>(cell, nullptr,
1636 HObjectAccess::ForPropertyCellValue());
1637
1638 IfBuilder builder(this);
1639 HValue* hole_value = graph()->GetConstantHole();
1640 builder.IfNot<HCompareObjectEqAndBranch, HValue*>(value, hole_value);
1641 builder.Then();
1642 { Push(value); }
1643 builder.Else();
1644 {
1645 Add<HPushArguments>(script_context, slot_index, name);
1646 Push(Add<HCallRuntime>(
1647 isolate()->factory()->empty_string(),
1648 Runtime::FunctionForId(Runtime::kLoadGlobalViaContext), 3));
1649 }
1650 builder.End();
1651 return Pop();
1652 }
1653
1654
1655 Handle<Code> LoadGlobalViaContextStub::GenerateCode() {
1656 return DoGenerateCode(this);
1657 }
1658
1659
1660 template <>
1661 HValue* CodeStubGraphBuilder<StoreGlobalViaContextStub>::BuildCodeStub() {
1662 StoreGlobalViaContextStub* stub = casted_stub();
1663 int depth_value = stub->depth();
1664 HValue* depth = GetParameter(0);
1665 HValue* slot_index = GetParameter(1);
1666 HValue* name = GetParameter(2);
1667 HValue* value = GetParameter(3);
1668
1669 // Choose between dynamic or static context script fetching versions.
1670 depth = depth_value < StoreGlobalViaContextStub::kDynamicDepth
1671 ? nullptr
1672 : AddUncasted<HForceRepresentation>(depth, Representation::Smi());
1673 slot_index =
1674 AddUncasted<HForceRepresentation>(slot_index, Representation::Smi());
1675
1676 HValue* script_context = BuildGetParentContext(depth, depth_value);
1677 HValue* cell =
1678 Add<HLoadKeyed>(script_context, slot_index, nullptr, FAST_ELEMENTS);
1679
1680 // Fast case that requires storing to cell.
1681 HIfContinuation if_fast_store_continuation(graph()->CreateBasicBlock(),
1682 graph()->CreateBasicBlock());
1683
1684 // Fast case that does not require storing to cell.
1685 HIfContinuation if_fast_no_store_continuation(graph()->CreateBasicBlock(),
1686 graph()->CreateBasicBlock());
1687
1688 // This stub does the same as StoreGlobalStub but in a dynamic manner.
1689
1690 HValue* cell_contents = Add<HLoadNamedField>(
1691 cell, nullptr, HObjectAccess::ForPropertyCellValue());
1692
1693 IfBuilder if_hole(this);
1694 HValue* hole_value = graph()->GetConstantHole();
1695 if_hole.IfNot<HCompareObjectEqAndBranch, HValue*>(cell_contents, hole_value);
1696 if_hole.Then();
1697 {
1698 HValue* details = Add<HLoadNamedField>(
1699 cell, nullptr, HObjectAccess::ForPropertyCellDetails());
1700 HValue* cell_type =
1701 BuildDecodeField<PropertyDetails::PropertyCellTypeField>(details);
1702
1703 // The code below relies on this.
1704 STATIC_ASSERT(PropertyCellType::kUndefined < PropertyCellType::kConstant);
1705 STATIC_ASSERT(PropertyCellType::kConstant <
1706 PropertyCellType::kConstantType);
1707 STATIC_ASSERT(PropertyCellType::kConstant < PropertyCellType::kMutable);
1708
1709 // Handle all cell type cases.
1710 IfBuilder if_not_const(this);
1711
1712 int cell_type_constant = static_cast<int>(PropertyCellType::kConstant);
1713 if_not_const.If<HCompareNumericAndBranch, HValue*>(
1714 cell_type, Add<HConstant>(cell_type_constant), Token::GT);
1715 if_not_const.Then();
1716 {
1717 // kConstantType or kMutable.
1718 IfBuilder if_const_type(this);
1719 int cell_type_constant_type =
1720 static_cast<int>(PropertyCellType::kConstantType);
1721 if_const_type.If<HCompareNumericAndBranch, HValue*>(
1722 cell_type, Add<HConstant>(cell_type_constant_type), Token::EQ);
1723 if_const_type.Then();
1724 {
1725 // Check that either both value and cell_contents are smi or
1726 // both have the same map.
1727 IfBuilder if_cell_is_smi(this);
1728 if_cell_is_smi.If<HIsSmiAndBranch>(cell_contents);
1729 if_cell_is_smi.Then();
1730 {
1731 IfBuilder if_value_is_smi(this);
1732 if_value_is_smi.If<HIsSmiAndBranch>(value);
1733 if_value_is_smi.Then();
1734 {
1735 // Both cell_contents and value are smis, do store.
1736 }
1737 if_value_is_smi.Else(); // Slow case.
1738 if_value_is_smi.JoinContinuation(&if_fast_store_continuation);
1739 }
1740 if_cell_is_smi.Else();
1741 {
1742 IfBuilder if_value_is_heap_object(this);
1743 if_value_is_heap_object.IfNot<HIsSmiAndBranch>(value);
1744 if_value_is_heap_object.Then();
1745 {
1746 // Both cell_contents and value are heap objects, do store.
1747 HValue* expected_map = Add<HLoadNamedField>(
1748 cell_contents, nullptr, HObjectAccess::ForMap());
1749 HValue* map =
1750 Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
1751 IfBuilder map_check(this);
1752 map_check.If<HCompareObjectEqAndBranch>(expected_map, map);
1753 map_check.Then();
1754 map_check.Else(); // Slow case.
1755 map_check.JoinContinuation(&if_fast_store_continuation);
1756
1757 // The accessor case is handled by the map check above, since
1758 // the value must not have a AccessorPair map.
1759 }
1760 if_value_is_heap_object.Else(); // Slow case.
1761 if_value_is_heap_object.JoinContinuation(&if_fast_store_continuation);
1762 }
1763 if_cell_is_smi.EndUnreachable();
1764 }
1765 if_const_type.Else();
1766 {
1767 // Check that the property kind is kData.
1768 HValue* kind = BuildDecodeField<PropertyDetails::KindField>(details);
1769 HValue* data_kind_value = Add<HConstant>(kData);
1770
1771 IfBuilder builder(this);
1772 builder.If<HCompareNumericAndBranch, HValue*>(kind, data_kind_value,
1773 Token::EQ);
1774 builder.Then();
1775 builder.Else(); // Slow case.
1776 builder.JoinContinuation(&if_fast_store_continuation);
1777 }
1778 if_const_type.EndUnreachable();
1779 }
1780 if_not_const.Else();
1781 {
1782 // kUndefined or kConstant, just check that the value matches.
1783 IfBuilder builder(this);
1784 builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
1785 builder.Then();
1786 builder.Else(); // Slow case.
1787 builder.JoinContinuation(&if_fast_no_store_continuation);
1788 }
1789 if_not_const.EndUnreachable();
1790 }
1791 if_hole.Else(); // Slow case.
1792 if_hole.JoinContinuation(&if_fast_store_continuation);
1793
1794 // Do store for fast case.
1795 IfBuilder if_fast_store(this, &if_fast_store_continuation);
1796 if_fast_store.Then();
1797 {
1798 // All checks are done, store the value to the cell.
1799 Add<HStoreNamedField>(cell, HObjectAccess::ForPropertyCellValue(), value);
1800 }
1801 if_fast_store.Else();
1802 if_fast_store.JoinContinuation(&if_fast_no_store_continuation);
1803
1804 // Bailout to runtime call for slow case.
1805 IfBuilder if_no_fast_store(this, &if_fast_no_store_continuation);
1806 if_no_fast_store.Then();
1807 {
1808 // Nothing else to do.
1809 }
1810 if_no_fast_store.Else();
1811 {
1812 // Slow case, call runtime.
1813 HInstruction* lang_mode = Add<HConstant>(casted_stub()->language_mode());
1814 Add<HPushArguments>(script_context, slot_index, name, value);
1815 Add<HPushArguments>(lang_mode);
1816 Add<HCallRuntime>(isolate()->factory()->empty_string(),
1817 Runtime::FunctionForId(Runtime::kStoreGlobalViaContext),
1818 5);
1819 }
1820 if_no_fast_store.End();
1821 return value;
1822 }
1823
1824
1825 Handle<Code> StoreGlobalViaContextStub::GenerateCode() {
1826 return DoGenerateCode(this);
1827 }
1828
1829
1830 template <>
1831 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() { 1617 HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
1832 HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex); 1618 HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex);
1833 HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex); 1619 HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex);
1834 HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex); 1620 HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex);
1835 HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex); 1621 HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex);
1836 1622
1837 if (FLAG_trace_elements_transitions) { 1623 if (FLAG_trace_elements_transitions) {
1838 // Tracing elements transitions is the job of the runtime. 1624 // Tracing elements transitions is the job of the runtime.
1839 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions, 1625 Add<HDeoptimize>(Deoptimizer::kTracingElementsTransitions,
1840 Deoptimizer::EAGER); 1626 Deoptimizer::EAGER);
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 return Pop(); 2273 return Pop();
2488 } 2274 }
2489 2275
2490 2276
2491 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2277 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2492 return DoGenerateCode(this); 2278 return DoGenerateCode(this);
2493 } 2279 }
2494 2280
2495 } // namespace internal 2281 } // namespace internal
2496 } // namespace v8 2282 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698