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

Side by Side Diff: src/ic.cc

Issue 12390031: Unify grow mode and stub kind (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 // We never see the debugger states here, because the state is 53 // We never see the debugger states here, because the state is
54 // computed from the original code - not the patched code. Let 54 // computed from the original code - not the patched code. Let
55 // these cases fall through to the unreachable code below. 55 // these cases fall through to the unreachable code below.
56 case DEBUG_STUB: break; 56 case DEBUG_STUB: break;
57 } 57 }
58 UNREACHABLE(); 58 UNREACHABLE();
59 return 0; 59 return 0;
60 } 60 }
61 61
62
63 const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) {
64 if (mode == STORE_NO_TRANSITION_HANDLE_COW) return ".COW";
65 if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
66 return ".IGNORE_OOB";
67 }
68 if (IsGrowStoreMode(mode)) return ".GROW";
69 return "";
70 }
71
72
62 void IC::TraceIC(const char* type, 73 void IC::TraceIC(const char* type,
63 Handle<Object> name, 74 Handle<Object> name,
64 State old_state, 75 State old_state,
65 Code* new_target) { 76 Code* new_target) {
66 if (FLAG_trace_ic) { 77 if (FLAG_trace_ic) {
67 Object* undef = new_target->GetHeap()->undefined_value(); 78 Object* undef = new_target->GetHeap()->undefined_value();
68 State new_state = StateFrom(new_target, undef, undef); 79 State new_state = StateFrom(new_target, undef, undef);
69 PrintF("[%s in ", type); 80 PrintF("[%s in ", type);
70 Isolate* isolate = new_target->GetIsolate(); 81 Isolate* isolate = new_target->GetIsolate();
71 StackFrameIterator it(isolate); 82 StackFrameIterator it(isolate);
72 while (it.frame()->fp() != this->fp()) it.Advance(); 83 while (it.frame()->fp() != this->fp()) it.Advance();
73 StackFrame* raw_frame = it.frame(); 84 StackFrame* raw_frame = it.frame();
74 if (raw_frame->is_internal()) { 85 if (raw_frame->is_internal()) {
75 Code* apply_builtin = isolate->builtins()->builtin( 86 Code* apply_builtin = isolate->builtins()->builtin(
76 Builtins::kFunctionApply); 87 Builtins::kFunctionApply);
77 if (raw_frame->unchecked_code() == apply_builtin) { 88 if (raw_frame->unchecked_code() == apply_builtin) {
78 PrintF("apply from "); 89 PrintF("apply from ");
79 it.Advance(); 90 it.Advance();
80 raw_frame = it.frame(); 91 raw_frame = it.frame();
81 } 92 }
82 } 93 }
83 JavaScriptFrame::PrintTop(isolate, stdout, false, true); 94 JavaScriptFrame::PrintTop(isolate, stdout, false, true);
84 bool new_can_grow = 95 Code::ExtraICState state = new_target->extra_ic_state();
85 Code::GetKeyedAccessGrowMode(new_target->extra_ic_state()) == 96 const char* modifier =
86 ALLOW_JSARRAY_GROWTH; 97 GetTransitionMarkModifier(Code::GetKeyedAccessStoreMode(state));
87 PrintF(" (%c->%c%s)", 98 PrintF(" (%c->%c%s)",
88 TransitionMarkFromState(old_state), 99 TransitionMarkFromState(old_state),
89 TransitionMarkFromState(new_state), 100 TransitionMarkFromState(new_state),
90 new_can_grow ? ".GROW" : ""); 101 modifier);
91 name->Print(); 102 name->Print();
92 PrintF("]\n"); 103 PrintF("]\n");
93 } 104 }
94 } 105 }
95 106
96 #define TRACE_GENERIC_IC(isolate, type, reason) \ 107 #define TRACE_GENERIC_IC(isolate, type, reason) \
97 do { \ 108 do { \
98 if (FLAG_trace_ic) { \ 109 if (FLAG_trace_ic) { \
99 PrintF("[%s patching generic stub in ", type); \ 110 PrintF("[%s patching generic stub in ", type); \
100 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ 111 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 case NONEXISTENT: 1606 case NONEXISTENT:
1596 case HANDLER: 1607 case HANDLER:
1597 UNREACHABLE(); 1608 UNREACHABLE();
1598 break; 1609 break;
1599 } 1610 }
1600 return Handle<Code>::null(); 1611 return Handle<Code>::null();
1601 } 1612 }
1602 1613
1603 1614
1604 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1615 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1605 StubKind stub_kind, 1616 KeyedAccessStoreMode store_mode,
1606 StrictModeFlag strict_mode) { 1617 StrictModeFlag strict_mode) {
1607 State ic_state = target()->ic_state();
1608 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind)
1609 ? ALLOW_JSARRAY_GROWTH
1610 : DO_NOT_ALLOW_JSARRAY_GROWTH;
1611
1612 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1618 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1613 // via megamorphic stubs, since they don't have a map in their relocation info 1619 // via megamorphic stubs, since they don't have a map in their relocation info
1614 // and so the stubs can't be harvested for the object needed for a map check. 1620 // and so the stubs can't be harvested for the object needed for a map check.
1615 if (target()->type() != Code::NORMAL) { 1621 if (target()->type() != Code::NORMAL) {
1616 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1622 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type");
1617 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); 1623 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1618 } 1624 }
1619 1625
1626 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
1627 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS)) {
1628 // TODO(danno): We'll soon handle MONOMORPHIC ICs that also support
1629 // copying COW arrays and silently ignoring some OOB stores into external
1630 // arrays, but for now use the generic.
1631 TRACE_GENERIC_IC(isolate(), "KeyedIC", "COW/OOB external array");
1632 return strict_mode == kStrictMode
1633 ? generic_stub_strict()
1634 : generic_stub();
1635 }
1636
1637 State ic_state = target()->ic_state();
1620 Handle<Map> receiver_map(receiver->map()); 1638 Handle<Map> receiver_map(receiver->map());
1621 MapHandleList target_receiver_maps;
1622 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1639 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1623 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1640 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1624 // yet will do so and stay there. 1641 // yet will do so and stay there.
1625 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); 1642 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
1626 stub_kind = GetNoTransitionStubKind(stub_kind); 1643 store_mode = GetNonTransitioningStoreMode(store_mode);
1627 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1644 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1628 monomorphic_map, stub_kind, strict_mode, grow_mode); 1645 monomorphic_map, strict_mode, store_mode);
1629 } 1646 }
1630 1647
1631 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1648 MapHandleList target_receiver_maps;
1649 target()->FindAllMaps(&target_receiver_maps);
1632 if (target_receiver_maps.length() == 0) { 1650 if (target_receiver_maps.length() == 0) {
1633 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1651 // In the case that there is a non-map-specific IC is installed (e.g. keyed
1634 // yet will do so and stay there. 1652 // stores into properties in dictionary mode), then there will be not
1635 stub_kind = GetNoTransitionStubKind(stub_kind); 1653 // receiver maps in the target.
1636 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1654 return strict_mode == kStrictMode
1637 receiver_map, stub_kind, strict_mode, grow_mode); 1655 ? generic_stub_strict()
1656 : generic_stub();
1638 } 1657 }
1639 // The first time a receiver is seen that is a transitioned version of the 1658
1640 // previous monomorphic receiver type, assume the new ElementsKind is the 1659 // There are several special cases where an IC that is MONOMORPHIC can still
1641 // monomorphic type. This benefits global arrays that only transition 1660 // transition to a different GetNonTransitioningStoreMode IC that handles a
1642 // once, and all call sites accessing them are faster if they remain 1661 // superset of the original IC. Handle those here if the receiver map hasn't
1643 // monomorphic. If this optimistic assumption is not true, the IC will 1662 // changed or it has transitioned to a more general kind.
1644 // miss again and it will become polymorphic and support both the 1663 KeyedAccessStoreMode old_store_mode =
1645 // untransitioned and transitioned maps. 1664 Code::GetKeyedAccessStoreMode(target()->extra_ic_state());
1646 if (ic_state == MONOMORPHIC && 1665 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1647 IsTransitionStubKind(stub_kind) && 1666 if (ic_state == MONOMORPHIC && old_store_mode == STANDARD_STORE) {
1648 IsMoreGeneralElementsKindTransition( 1667 // If the "old" and "new" maps are in the same elements map family, stay
1649 target_receiver_maps.at(0)->elements_kind(), 1668 // MONOMORPHIC and use the map for the most generic ElementsKind.
1650 receiver->GetElementsKind())) { 1669 Handle<Map> transitioned_receiver_map = receiver_map;
1651 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); 1670 if (IsTransitionStoreMode(store_mode)) {
1652 ASSERT(*monomorphic_map != *receiver_map); 1671 transitioned_receiver_map =
1653 stub_kind = GetNoTransitionStubKind(stub_kind); 1672 ComputeTransitionedMap(receiver, store_mode);
1654 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1673 }
1655 monomorphic_map, stub_kind, strict_mode, grow_mode); 1674 ElementsKind transitioned_kind =
1675 transitioned_receiver_map->elements_kind();
1676 bool more_general_transition =
1677 IsMoreGeneralElementsKindTransition(
1678 previous_receiver_map->elements_kind(),
1679 transitioned_kind);
1680 Map* transitioned_previous_map = more_general_transition
1681 ? previous_receiver_map->LookupElementsTransitionMap(transitioned_kind)
1682 : NULL;
1683 if (transitioned_previous_map == *transitioned_receiver_map) {
1684 // Element family is the same, use the "worst" case map.
1685 store_mode = GetNonTransitioningStoreMode(store_mode);
1686 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1687 transitioned_receiver_map, strict_mode, store_mode);
1688 } else if (*previous_receiver_map == receiver->map()) {
1689 if (IsGrowStoreMode(store_mode)) {
1690 // A "normal" IC that handles stores can switch to a version that can
1691 // grow at the end of the array and still stay MONOMORPHIC.
1692 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1693 receiver_map, strict_mode, store_mode);
1694 }
1695 }
1656 } 1696 }
1657 1697
1658 ASSERT(ic_state != GENERIC); 1698 ASSERT(ic_state != GENERIC);
1659 1699
1660 bool map_added = 1700 bool map_added =
1661 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1701 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1662 1702
1663 if (IsTransitionStubKind(stub_kind)) { 1703 if (IsTransitionStoreMode(store_mode)) {
1664 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); 1704 Handle<Map> transitioned_receiver_map =
1665 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); 1705 ComputeTransitionedMap(receiver, store_mode);
1706 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1707 transitioned_receiver_map);
1666 } 1708 }
1667 1709
1668 if (!map_added) { 1710 if (!map_added) {
1669 // If the miss wasn't due to an unseen map, a polymorphic stub 1711 // If the miss wasn't due to an unseen map, a polymorphic stub
1670 // won't help, use the generic stub. 1712 // won't help, use the generic stub.
1671 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1713 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice");
1672 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); 1714 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1673 } 1715 }
1674 1716
1675 // If the maximum number of receiver maps has been exceeded, use the generic 1717 // If the maximum number of receiver maps has been exceeded, use the generic
1676 // version of the IC. 1718 // version of the IC.
1677 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1719 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1678 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1720 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded");
1679 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); 1721 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1680 } 1722 }
1681 1723
1682 if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) == 1724 // Make sure all polymorphic handlers have the same store mode, otherwise the
1683 ALLOW_JSARRAY_GROWTH)) { 1725 // generic stub must be used.
1684 grow_mode = ALLOW_JSARRAY_GROWTH; 1726 store_mode = GetNonTransitioningStoreMode(store_mode);
1727 if (old_store_mode != STANDARD_STORE) {
1728 if (store_mode == STANDARD_STORE) {
1729 store_mode = old_store_mode;
1730 } else if (store_mode != old_store_mode) {
1731 TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch");
1732 return strict_mode == kStrictMode
1733 ? generic_stub_strict()
1734 : generic_stub();
1735 }
1685 } 1736 }
1686 1737
1687 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( 1738 return isolate()->stub_cache()->ComputeStoreElementPolymorphic(
1688 &target_receiver_maps, grow_mode, strict_mode); 1739 &target_receiver_maps, store_mode, strict_mode);
1689 } 1740 }
1690 1741
1691 1742
1692 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(Handle<JSObject> receiver, 1743 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1693 StubKind stub_kind) { 1744 Handle<JSObject> receiver,
1694 switch (stub_kind) { 1745 KeyedAccessStoreMode store_mode) {
1746 switch (store_mode) {
1695 case STORE_TRANSITION_SMI_TO_OBJECT: 1747 case STORE_TRANSITION_SMI_TO_OBJECT:
1696 case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1748 case STORE_TRANSITION_DOUBLE_TO_OBJECT:
1697 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1749 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1698 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1750 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
1699 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); 1751 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
1700 case STORE_TRANSITION_SMI_TO_DOUBLE: 1752 case STORE_TRANSITION_SMI_TO_DOUBLE:
1701 case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: 1753 case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
1702 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); 1754 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
1703 case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: 1755 case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
1704 case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1756 case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1705 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: 1757 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
1706 case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1758 case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1707 return JSObject::GetElementsTransitionMap(receiver, 1759 return JSObject::GetElementsTransitionMap(receiver,
1708 FAST_HOLEY_ELEMENTS); 1760 FAST_HOLEY_ELEMENTS);
1709 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1761 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1710 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1762 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1711 return JSObject::GetElementsTransitionMap(receiver, 1763 return JSObject::GetElementsTransitionMap(receiver,
1712 FAST_HOLEY_DOUBLE_ELEMENTS); 1764 FAST_HOLEY_DOUBLE_ELEMENTS);
1713 case STORE_NO_TRANSITION: 1765 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
1766 ASSERT(receiver->map()->has_external_array_elements());
1767 // Fall through
1768 case STORE_NO_TRANSITION_HANDLE_COW:
1769 case STANDARD_STORE:
1714 case STORE_AND_GROW_NO_TRANSITION: 1770 case STORE_AND_GROW_NO_TRANSITION:
1715 return Handle<Map>(receiver->map()); 1771 return Handle<Map>(receiver->map());
1716 } 1772 }
1717 return Handle<Map>::null(); 1773 return Handle<Map>::null();
1718 } 1774 }
1719 1775
1720 1776
1721 KeyedStoreIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver, 1777 bool IsOutOfBoundsAccess(Handle<JSObject> receiver,
1722 Handle<Object> key, 1778 int index) {
1723 Handle<Object> value) { 1779 if (receiver->IsJSArray()) {
1780 return JSArray::cast(*receiver)->length()->IsSmi() &&
1781 index >= Smi::cast(JSArray::cast(*receiver)->length())->value();
1782 }
1783 return index >= receiver->elements()->length();
1784 }
1785
1786
1787 KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
1788 Handle<Object> key,
1789 Handle<Object> value) {
1724 ASSERT(key->IsSmi()); 1790 ASSERT(key->IsSmi());
1725 int index = Smi::cast(*key)->value(); 1791 int index = Smi::cast(*key)->value();
1726 bool allow_growth = receiver->IsJSArray() && 1792 bool oob_access = IsOutOfBoundsAccess(receiver, index);
1727 JSArray::cast(*receiver)->length()->IsSmi() && 1793 bool allow_growth = receiver->IsJSArray() && oob_access;
1728 index >= Smi::cast(JSArray::cast(*receiver)->length())->value();
1729
1730 if (allow_growth) { 1794 if (allow_growth) {
1731 // Handle growing array in stub if necessary. 1795 // Handle growing array in stub if necessary.
1732 if (receiver->HasFastSmiElements()) { 1796 if (receiver->HasFastSmiElements()) {
1733 if (value->IsHeapNumber()) { 1797 if (value->IsHeapNumber()) {
1734 if (receiver->HasFastHoleyElements()) { 1798 if (receiver->HasFastHoleyElements()) {
1735 return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1799 return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE;
1736 } else { 1800 } else {
1737 return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE; 1801 return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE;
1738 } 1802 }
1739 } 1803 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 } 1836 }
1773 } else if (receiver->HasFastDoubleElements()) { 1837 } else if (receiver->HasFastDoubleElements()) {
1774 if (!value->IsSmi() && !value->IsHeapNumber()) { 1838 if (!value->IsSmi() && !value->IsHeapNumber()) {
1775 if (receiver->HasFastHoleyElements()) { 1839 if (receiver->HasFastHoleyElements()) {
1776 return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1840 return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
1777 } else { 1841 } else {
1778 return STORE_TRANSITION_DOUBLE_TO_OBJECT; 1842 return STORE_TRANSITION_DOUBLE_TO_OBJECT;
1779 } 1843 }
1780 } 1844 }
1781 } 1845 }
1782 return STORE_NO_TRANSITION; 1846 if (!FLAG_trace_external_array_abuse &&
1847 receiver->map()->has_external_array_elements() && oob_access) {
1848 return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
1849 } else {
1850 return STANDARD_STORE;
1851 }
1783 } 1852 }
1784 } 1853 }
1785 1854
1786 1855
1787 MaybeObject* KeyedStoreIC::Store(State state, 1856 MaybeObject* KeyedStoreIC::Store(State state,
1788 StrictModeFlag strict_mode, 1857 StrictModeFlag strict_mode,
1789 Handle<Object> object, 1858 Handle<Object> object,
1790 Handle<Object> key, 1859 Handle<Object> key,
1791 Handle<Object> value, 1860 Handle<Object> value,
1792 ICMissMode miss_mode) { 1861 ICMissMode miss_mode) {
(...skipping 19 matching lines...) Expand all
1812 Handle<Code> stub = (strict_mode == kStrictMode) 1881 Handle<Code> stub = (strict_mode == kStrictMode)
1813 ? generic_stub_strict() 1882 ? generic_stub_strict()
1814 : generic_stub(); 1883 : generic_stub();
1815 if (miss_mode != MISS_FORCE_GENERIC) { 1884 if (miss_mode != MISS_FORCE_GENERIC) {
1816 if (object->IsJSObject()) { 1885 if (object->IsJSObject()) {
1817 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1886 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1818 if (receiver->elements()->map() == 1887 if (receiver->elements()->map() ==
1819 isolate()->heap()->non_strict_arguments_elements_map()) { 1888 isolate()->heap()->non_strict_arguments_elements_map()) {
1820 stub = non_strict_arguments_stub(); 1889 stub = non_strict_arguments_stub();
1821 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1890 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1822 StubKind stub_kind = GetStubKind(receiver, key, value); 1891 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
1823 stub = StoreElementStub(receiver, stub_kind, strict_mode); 1892 stub = StoreElementStub(receiver, store_mode, strict_mode);
1824 } 1893 }
1825 } 1894 }
1826 } else { 1895 } else {
1827 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); 1896 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic");
1828 } 1897 }
1829 ASSERT(!stub.is_null()); 1898 ASSERT(!stub.is_null());
1830 set_target(*stub); 1899 set_target(*stub);
1831 TRACE_IC("KeyedStoreIC", key, state, target()); 1900 TRACE_IC("KeyedStoreIC", key, state, target());
1832 } 1901 }
1833 1902
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 #undef ADDR 2711 #undef ADDR
2643 }; 2712 };
2644 2713
2645 2714
2646 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2715 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2647 return IC_utilities[id]; 2716 return IC_utilities[id];
2648 } 2717 }
2649 2718
2650 2719
2651 } } // namespace v8::internal 2720 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698