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

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: Merge with ToT 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
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; 1639 MapHandleList target_receiver_maps;
1622 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1640 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1623 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1641 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1624 // yet will do so and stay there. 1642 // yet will do so and stay there.
1625 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); 1643 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode);
1626 stub_kind = GetNoTransitionStubKind(stub_kind); 1644 store_mode = GetUntransitionedStoreMode(store_mode);
Toon Verwaest 2013/03/06 14:47:28 GetNonTransitioningStoreMode? The store mode itsel
danno 2013/03/06 16:56:06 Done.
1627 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1645 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1628 monomorphic_map, stub_kind, strict_mode, grow_mode); 1646 monomorphic_map, strict_mode, store_mode);
1629 } 1647 }
1630 1648
1631 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1649 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
Toon Verwaest 2013/03/06 14:47:28 Not directly related to this CL, but I think we ca
danno 2013/03/06 16:56:06 Done.
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 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1634 // yet will do so and stay there. 1652 // yet will do so and stay there.
1635 stub_kind = GetNoTransitionStubKind(stub_kind); 1653 store_mode = GetUntransitionedStoreMode(store_mode);
1636 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1654 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1637 receiver_map, stub_kind, strict_mode, grow_mode); 1655 receiver_map, strict_mode, store_mode);
1638 } 1656 }
1639 // The first time a receiver is seen that is a transitioned version of the 1657
1640 // previous monomorphic receiver type, assume the new ElementsKind is the 1658 // There are several special cases where a IC that is MONOMORPHIC can still
Toon Verwaest 2013/03/06 14:47:28 an IC
danno 2013/03/06 16:56:06 Done.
1641 // monomorphic type. This benefits global arrays that only transition 1659 // transition to a different GetUntransitionedStoreMode IC that handles a
1642 // once, and all call sites accessing them are faster if they remain 1660 // 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 1661 // changed or it has transitioned to a more general kind.
1644 // miss again and it will become polymorphic and support both the 1662 KeyedAccessStoreMode old_store_mode =
1645 // untransitioned and transitioned maps. 1663 Code::GetKeyedAccessStoreMode(target()->extra_ic_state());
Toon Verwaest 2013/03/06 14:47:28 As far as I can tell, we are not certain that the
danno 2013/03/06 16:56:06 Done.
1646 if (ic_state == MONOMORPHIC && 1664 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1647 IsTransitionStubKind(stub_kind) && 1665 if (ic_state == MONOMORPHIC && old_store_mode == STORE_NO_TRANSITION) {
1648 IsMoreGeneralElementsKindTransition( 1666 Handle<Map> transitioned_receiver_map = receiver_map;
1649 target_receiver_maps.at(0)->elements_kind(), 1667 if (IsTransitionStoreMode(store_mode)) {
1650 receiver->GetElementsKind())) { 1668 transitioned_receiver_map =
1651 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); 1669 ComputeTransitionedMap(receiver, store_mode);
1652 ASSERT(*monomorphic_map != *receiver_map); 1670 }
1653 stub_kind = GetNoTransitionStubKind(stub_kind); 1671 ElementsKind transitioned_kind =
1654 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1672 transitioned_receiver_map->elements_kind();
1655 monomorphic_map, stub_kind, strict_mode, grow_mode); 1673 bool more_general_transition =
1674 IsMoreGeneralElementsKindTransition(
1675 previous_receiver_map->elements_kind(),
1676 transitioned_kind);
1677 Map* transitioned_previous_map = more_general_transition
1678 ? previous_receiver_map->LookupElementsTransitionMap(transitioned_kind)
1679 : NULL;
1680 if (transitioned_previous_map == *transitioned_receiver_map) {
1681 store_mode = GetUntransitionedStoreMode(store_mode);
1682 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1683 transitioned_receiver_map, strict_mode, store_mode);
1684 } else if (*previous_receiver_map == receiver->map()) {
1685 if (store_mode == IsGrowStoreMode(store_mode)) {
Toon Verwaest 2013/03/06 14:47:28 It seems like store_mode == IsGrowStoreMode(store_
danno 2013/03/06 16:56:06 Done.
1686 // A "normal" IC that handles stores can switch to a version that can
1687 // grow at the end of the array and still stay MONOMORPHIC.
1688 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1689 receiver_map, strict_mode, store_mode);
1690 }
1691 }
1656 } 1692 }
1657 1693
1658 ASSERT(ic_state != GENERIC); 1694 ASSERT(ic_state != GENERIC);
1659 1695
1660 bool map_added = 1696 bool map_added =
1661 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1697 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1662 1698
1663 if (IsTransitionStubKind(stub_kind)) { 1699 if (IsTransitionStoreMode(store_mode)) {
1664 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); 1700 Handle<Map> new_map = ComputeTransitionedMap(receiver, store_mode);
Toon Verwaest 2013/03/06 14:47:28 Can we also call this transitioned_receiver_map, t
danno 2013/03/06 16:56:06 Done.
1665 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); 1701 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
1666 } 1702 }
1667 1703
1668 if (!map_added) { 1704 if (!map_added) {
1669 // If the miss wasn't due to an unseen map, a polymorphic stub 1705 // If the miss wasn't due to an unseen map, a polymorphic stub
1670 // won't help, use the generic stub. 1706 // won't help, use the generic stub.
1671 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1707 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice");
1672 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); 1708 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1673 } 1709 }
1674 1710
1675 // If the maximum number of receiver maps has been exceeded, use the generic 1711 // If the maximum number of receiver maps has been exceeded, use the generic
1676 // version of the IC. 1712 // version of the IC.
1677 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1713 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1678 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1714 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded");
1679 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); 1715 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1680 } 1716 }
1681 1717
1682 if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) == 1718 // Make sure all polymorphic handlers have the same store mode, otherwise the
1683 ALLOW_JSARRAY_GROWTH)) { 1719 // generic stub must be used.
1684 grow_mode = ALLOW_JSARRAY_GROWTH; 1720 store_mode = GetUntransitionedStoreMode(store_mode);
1721 if (old_store_mode != STORE_NO_TRANSITION) {
Toon Verwaest 2013/03/06 14:47:28 Meaning STORE_AND_GROW_NO_TRANSITION?
danno 2013/03/06 16:56:06 Well, this is currently correct, but for the next
1722 if (store_mode == STORE_NO_TRANSITION) {
1723 store_mode = old_store_mode;
1724 } else if (store_mode != old_store_mode) {
Toon Verwaest 2013/03/06 14:47:28 Can this happen? I presumed though would only be p
danno 2013/03/06 16:56:06 As discussed offline, no change needed. On 2013/0
1725 TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch");
1726 return strict_mode == kStrictMode
1727 ? generic_stub_strict()
1728 : generic_stub();
1729 }
1685 } 1730 }
1686 1731
1687 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( 1732 return isolate()->stub_cache()->ComputeStoreElementPolymorphic(
1688 &target_receiver_maps, grow_mode, strict_mode); 1733 &target_receiver_maps, store_mode, strict_mode);
1689 } 1734 }
1690 1735
1691 1736
1692 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(Handle<JSObject> receiver, 1737 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1693 StubKind stub_kind) { 1738 Handle<JSObject> receiver,
1694 switch (stub_kind) { 1739 KeyedAccessStoreMode store_mode) {
1740 switch (store_mode) {
1695 case STORE_TRANSITION_SMI_TO_OBJECT: 1741 case STORE_TRANSITION_SMI_TO_OBJECT:
1696 case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1742 case STORE_TRANSITION_DOUBLE_TO_OBJECT:
1697 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1743 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1698 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1744 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
1699 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); 1745 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
1700 case STORE_TRANSITION_SMI_TO_DOUBLE: 1746 case STORE_TRANSITION_SMI_TO_DOUBLE:
1701 case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: 1747 case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
1702 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); 1748 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
1703 case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: 1749 case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
1704 case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1750 case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1705 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: 1751 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
1706 case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1752 case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1707 return JSObject::GetElementsTransitionMap(receiver, 1753 return JSObject::GetElementsTransitionMap(receiver,
1708 FAST_HOLEY_ELEMENTS); 1754 FAST_HOLEY_ELEMENTS);
1709 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1755 case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1710 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1756 case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1711 return JSObject::GetElementsTransitionMap(receiver, 1757 return JSObject::GetElementsTransitionMap(receiver,
1712 FAST_HOLEY_DOUBLE_ELEMENTS); 1758 FAST_HOLEY_DOUBLE_ELEMENTS);
1759 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
1760 ASSERT(receiver->map()->has_external_array_elements());
1761 // Fall through
1762 case STORE_NO_TRANSITION_HANDLE_COW:
1713 case STORE_NO_TRANSITION: 1763 case STORE_NO_TRANSITION:
1714 case STORE_AND_GROW_NO_TRANSITION: 1764 case STORE_AND_GROW_NO_TRANSITION:
1715 return Handle<Map>(receiver->map()); 1765 return Handle<Map>(receiver->map());
1716 } 1766 }
1717 return Handle<Map>::null(); 1767 return Handle<Map>::null();
1718 } 1768 }
1719 1769
1720 1770
1721 KeyedStoreIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver, 1771 bool IsOutOfBoundsAccess(Handle<JSObject> receiver,
1722 Handle<Object> key, 1772 int index) {
1723 Handle<Object> value) { 1773 if (receiver->IsJSArray()) {
Toon Verwaest 2013/03/06 14:47:28 Maybe add a comment stating that for JSArrays (inc
danno 2013/03/06 16:56:06 Done.
1774 return JSArray::cast(*receiver)->length()->IsSmi() &&
1775 index >= Smi::cast(JSArray::cast(*receiver)->length())->value();
1776 }
1777 return index >= receiver->elements()->length() || index < 0;
1778 }
1779
1780
1781 KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver,
1782 Handle<Object> key,
1783 Handle<Object> value) {
1724 ASSERT(key->IsSmi()); 1784 ASSERT(key->IsSmi());
1725 int index = Smi::cast(*key)->value(); 1785 int index = Smi::cast(*key)->value();
1726 bool allow_growth = receiver->IsJSArray() && 1786 bool oob_access = IsOutOfBoundsAccess(receiver, index);
1727 JSArray::cast(*receiver)->length()->IsSmi() && 1787 bool allow_growth = receiver->IsJSArray() && oob_access;
1728 index >= Smi::cast(JSArray::cast(*receiver)->length())->value();
1729
1730 if (allow_growth) { 1788 if (allow_growth) {
1731 // Handle growing array in stub if necessary. 1789 // Handle growing array in stub if necessary.
1732 if (receiver->HasFastSmiElements()) { 1790 if (receiver->HasFastSmiElements()) {
1733 if (value->IsHeapNumber()) { 1791 if (value->IsHeapNumber()) {
1734 if (receiver->HasFastHoleyElements()) { 1792 if (receiver->HasFastHoleyElements()) {
1735 return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1793 return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE;
1736 } else { 1794 } else {
1737 return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE; 1795 return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE;
1738 } 1796 }
1739 } 1797 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 } 1830 }
1773 } else if (receiver->HasFastDoubleElements()) { 1831 } else if (receiver->HasFastDoubleElements()) {
1774 if (!value->IsSmi() && !value->IsHeapNumber()) { 1832 if (!value->IsSmi() && !value->IsHeapNumber()) {
1775 if (receiver->HasFastHoleyElements()) { 1833 if (receiver->HasFastHoleyElements()) {
1776 return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1834 return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT;
1777 } else { 1835 } else {
1778 return STORE_TRANSITION_DOUBLE_TO_OBJECT; 1836 return STORE_TRANSITION_DOUBLE_TO_OBJECT;
1779 } 1837 }
1780 } 1838 }
1781 } 1839 }
1782 return STORE_NO_TRANSITION; 1840 if (!FLAG_trace_external_array_abuse &&
1841 receiver->map()->has_external_array_elements() && oob_access) {
1842 return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
1843 } else {
1844 return STORE_NO_TRANSITION;
1845 }
1783 } 1846 }
1784 } 1847 }
1785 1848
1786 1849
1787 MaybeObject* KeyedStoreIC::Store(State state, 1850 MaybeObject* KeyedStoreIC::Store(State state,
1788 StrictModeFlag strict_mode, 1851 StrictModeFlag strict_mode,
1789 Handle<Object> object, 1852 Handle<Object> object,
1790 Handle<Object> key, 1853 Handle<Object> key,
1791 Handle<Object> value, 1854 Handle<Object> value,
1792 ICMissMode miss_mode) { 1855 ICMissMode miss_mode) {
(...skipping 19 matching lines...) Expand all
1812 Handle<Code> stub = (strict_mode == kStrictMode) 1875 Handle<Code> stub = (strict_mode == kStrictMode)
1813 ? generic_stub_strict() 1876 ? generic_stub_strict()
1814 : generic_stub(); 1877 : generic_stub();
1815 if (miss_mode != MISS_FORCE_GENERIC) { 1878 if (miss_mode != MISS_FORCE_GENERIC) {
1816 if (object->IsJSObject()) { 1879 if (object->IsJSObject()) {
1817 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1880 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1818 if (receiver->elements()->map() == 1881 if (receiver->elements()->map() ==
1819 isolate()->heap()->non_strict_arguments_elements_map()) { 1882 isolate()->heap()->non_strict_arguments_elements_map()) {
1820 stub = non_strict_arguments_stub(); 1883 stub = non_strict_arguments_stub();
1821 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1884 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1822 StubKind stub_kind = GetStubKind(receiver, key, value); 1885 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
1823 stub = StoreElementStub(receiver, stub_kind, strict_mode); 1886 stub = StoreElementStub(receiver, store_mode, strict_mode);
1824 } 1887 }
1825 } 1888 }
1826 } else { 1889 } else {
1827 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); 1890 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic");
1828 } 1891 }
1829 ASSERT(!stub.is_null()); 1892 ASSERT(!stub.is_null());
1830 set_target(*stub); 1893 set_target(*stub);
1831 TRACE_IC("KeyedStoreIC", key, state, target()); 1894 TRACE_IC("KeyedStoreIC", key, state, target());
1832 } 1895 }
1833 1896
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 #undef ADDR 2705 #undef ADDR
2643 }; 2706 };
2644 2707
2645 2708
2646 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2709 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2647 return IC_utilities[id]; 2710 return IC_utilities[id];
2648 } 2711 }
2649 2712
2650 2713
2651 } } // namespace v8::internal 2714 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/mips/stub-cache-mips.cc » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698