OLD | NEW |
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/ic/ic.h" | 5 #include "src/ic/ic.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // then print "apply from" and advance one frame | 110 // then print "apply from" and advance one frame |
111 | 111 |
112 Object* maybe_function = | 112 Object* maybe_function = |
113 Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset); | 113 Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset); |
114 if (maybe_function->IsJSFunction()) { | 114 if (maybe_function->IsJSFunction()) { |
115 JSFunction* function = JSFunction::cast(maybe_function); | 115 JSFunction* function = JSFunction::cast(maybe_function); |
116 JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(), | 116 JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(), |
117 stdout, true); | 117 stdout, true); |
118 } | 118 } |
119 | 119 |
120 ExtraICState extra_state = new_target->extra_ic_state(); | |
121 const char* modifier = ""; | 120 const char* modifier = ""; |
122 if (new_target->kind() == Code::KEYED_STORE_IC) { | 121 if (new_target->kind() == Code::KEYED_STORE_IC) { |
123 KeyedAccessStoreMode mode = | 122 KeyedAccessStoreMode mode = |
124 FLAG_vector_stores | 123 casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode(); |
125 ? casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode() | |
126 : KeyedStoreIC::GetKeyedAccessStoreMode(extra_state); | |
127 modifier = GetTransitionMarkModifier(mode); | 124 modifier = GetTransitionMarkModifier(mode); |
128 } | 125 } |
129 PrintF(" (%c->%c%s) ", TransitionMarkFromState(old_state), | 126 PrintF(" (%c->%c%s) ", TransitionMarkFromState(old_state), |
130 TransitionMarkFromState(new_state), modifier); | 127 TransitionMarkFromState(new_state), modifier); |
131 #ifdef OBJECT_PRINT | 128 #ifdef OBJECT_PRINT |
132 OFStream os(stdout); | 129 OFStream os(stdout); |
133 name->Print(os); | 130 name->Print(os); |
134 #else | 131 #else |
135 name->ShortPrint(stdout); | 132 name->ShortPrint(stdout); |
136 #endif | 133 #endif |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 | 460 |
464 void IC::Clear(Isolate* isolate, Address address, Address constant_pool) { | 461 void IC::Clear(Isolate* isolate, Address address, Address constant_pool) { |
465 Code* target = GetTargetAtAddress(address, constant_pool); | 462 Code* target = GetTargetAtAddress(address, constant_pool); |
466 | 463 |
467 // Don't clear debug break inline cache as it will remove the break point. | 464 // Don't clear debug break inline cache as it will remove the break point. |
468 if (target->is_debug_stub()) return; | 465 if (target->is_debug_stub()) return; |
469 | 466 |
470 switch (target->kind()) { | 467 switch (target->kind()) { |
471 case Code::LOAD_IC: | 468 case Code::LOAD_IC: |
472 case Code::KEYED_LOAD_IC: | 469 case Code::KEYED_LOAD_IC: |
| 470 case Code::STORE_IC: |
| 471 case Code::KEYED_STORE_IC: |
473 return; | 472 return; |
474 case Code::STORE_IC: | |
475 if (FLAG_vector_stores) return; | |
476 return StoreIC::Clear(isolate, address, target, constant_pool); | |
477 case Code::KEYED_STORE_IC: | |
478 if (FLAG_vector_stores) return; | |
479 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); | |
480 case Code::COMPARE_IC: | 473 case Code::COMPARE_IC: |
481 return CompareIC::Clear(isolate, address, target, constant_pool); | 474 return CompareIC::Clear(isolate, address, target, constant_pool); |
482 case Code::COMPARE_NIL_IC: | 475 case Code::COMPARE_NIL_IC: |
483 return CompareNilIC::Clear(address, target, constant_pool); | 476 return CompareNilIC::Clear(address, target, constant_pool); |
484 case Code::CALL_IC: // CallICs are vector-based and cleared differently. | 477 case Code::CALL_IC: // CallICs are vector-based and cleared differently. |
485 case Code::BINARY_OP_IC: | 478 case Code::BINARY_OP_IC: |
486 case Code::TO_BOOLEAN_IC: | 479 case Code::TO_BOOLEAN_IC: |
487 // Clearing these is tricky and does not | 480 // Clearing these is tricky and does not |
488 // make any performance difference. | 481 // make any performance difference. |
489 return; | 482 return; |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 if (UseVector()) { | 796 if (UseVector()) { |
804 if (!nexus()->FindHandlers(&handlers, maps.length())) return false; | 797 if (!nexus()->FindHandlers(&handlers, maps.length())) return false; |
805 } else { | 798 } else { |
806 if (!target()->FindHandlers(&handlers, maps.length())) return false; | 799 if (!target()->FindHandlers(&handlers, maps.length())) return false; |
807 } | 800 } |
808 | 801 |
809 number_of_valid_maps++; | 802 number_of_valid_maps++; |
810 if (number_of_valid_maps > 1 && target()->is_keyed_stub()) return false; | 803 if (number_of_valid_maps > 1 && target()->is_keyed_stub()) return false; |
811 Handle<Code> ic; | 804 Handle<Code> ic; |
812 if (number_of_valid_maps == 1) { | 805 if (number_of_valid_maps == 1) { |
813 if (UseVector()) { | 806 ConfigureVectorState(name, receiver_map(), code); |
814 ConfigureVectorState(name, receiver_map(), code); | |
815 } else { | |
816 ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, map, code, | |
817 extra_ic_state()); | |
818 } | |
819 } else { | 807 } else { |
820 if (handler_to_overwrite >= 0) { | 808 if (handler_to_overwrite >= 0) { |
821 handlers.Set(handler_to_overwrite, code); | 809 handlers.Set(handler_to_overwrite, code); |
822 if (!map.is_identical_to(maps.at(handler_to_overwrite))) { | 810 if (!map.is_identical_to(maps.at(handler_to_overwrite))) { |
823 maps.Set(handler_to_overwrite, map); | 811 maps.Set(handler_to_overwrite, map); |
824 } | 812 } |
825 } else { | 813 } else { |
826 maps.Add(map); | 814 maps.Add(map); |
827 handlers.Add(code); | 815 handlers.Add(code); |
828 } | 816 } |
829 | 817 |
830 if (UseVector()) { | 818 ConfigureVectorState(name, &maps, &handlers); |
831 ConfigureVectorState(name, &maps, &handlers); | |
832 } else { | |
833 ic = PropertyICCompiler::ComputePolymorphic(kind(), &maps, &handlers, | |
834 number_of_valid_maps, name, | |
835 extra_ic_state()); | |
836 } | |
837 } | 819 } |
838 | 820 |
839 if (!UseVector()) set_target(*ic); | 821 if (!UseVector()) set_target(*ic); |
840 return true; | 822 return true; |
841 } | 823 } |
842 | 824 |
843 | 825 |
844 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { | 826 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { |
845 DCHECK(handler->is_handler()); | 827 DCHECK(handler->is_handler()); |
846 if (UseVector()) { | 828 ConfigureVectorState(name, receiver_map(), handler); |
847 ConfigureVectorState(name, receiver_map(), handler); | |
848 } else { | |
849 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( | |
850 kind(), name, receiver_map(), handler, extra_ic_state()); | |
851 set_target(*ic); | |
852 } | |
853 } | 829 } |
854 | 830 |
855 | 831 |
856 void IC::CopyICToMegamorphicCache(Handle<Name> name) { | 832 void IC::CopyICToMegamorphicCache(Handle<Name> name) { |
857 MapHandleList maps; | 833 MapHandleList maps; |
858 CodeHandleList handlers; | 834 CodeHandleList handlers; |
859 TargetMaps(&maps); | 835 TargetMaps(&maps); |
860 if (!target()->FindHandlers(&handlers, maps.length())) return; | 836 if (!target()->FindHandlers(&handlers, maps.length())) return; |
861 for (int i = 0; i < maps.length(); i++) { | 837 for (int i = 0; i < maps.length(); i++) { |
862 UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i)); | 838 UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i)); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 default: | 942 default: |
967 UNREACHABLE(); | 943 UNREACHABLE(); |
968 } | 944 } |
969 return Handle<Code>(); | 945 return Handle<Code>(); |
970 } | 946 } |
971 | 947 |
972 | 948 |
973 Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate, | 949 Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate, |
974 LanguageMode language_mode, | 950 LanguageMode language_mode, |
975 State initialization_state) { | 951 State initialization_state) { |
976 if (FLAG_vector_stores && initialization_state != MEGAMORPHIC) { | 952 if (initialization_state != MEGAMORPHIC) { |
977 VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); | 953 VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); |
978 return stub.GetCode(); | 954 return stub.GetCode(); |
979 } | 955 } |
980 | 956 |
981 return KeyedStoreICInitializeStubHelper(isolate, language_mode, | 957 return KeyedStoreICInitializeStubHelper(isolate, language_mode, |
982 initialization_state); | 958 initialization_state); |
983 } | 959 } |
984 | 960 |
985 | 961 |
986 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code( | 962 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code( |
987 Isolate* isolate, LanguageMode language_mode, State initialization_state) { | 963 Isolate* isolate, LanguageMode language_mode, State initialization_state) { |
988 if (FLAG_vector_stores && initialization_state != MEGAMORPHIC) { | 964 if (initialization_state != MEGAMORPHIC) { |
989 VectorKeyedStoreICStub stub(isolate, StoreICState(language_mode)); | 965 VectorKeyedStoreICStub stub(isolate, StoreICState(language_mode)); |
990 return stub.GetCode(); | 966 return stub.GetCode(); |
991 } | 967 } |
992 | 968 |
993 return KeyedStoreICInitializeStubHelper(isolate, language_mode, | 969 return KeyedStoreICInitializeStubHelper(isolate, language_mode, |
994 initialization_state); | 970 initialization_state); |
995 } | 971 } |
996 | 972 |
997 | 973 |
998 Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, | 974 Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 return ic; | 1589 return ic; |
1614 } | 1590 } |
1615 | 1591 |
1616 | 1592 |
1617 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | 1593 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
1618 LanguageMode language_mode, | 1594 LanguageMode language_mode, |
1619 State initialization_state) { | 1595 State initialization_state) { |
1620 DCHECK(initialization_state == UNINITIALIZED || | 1596 DCHECK(initialization_state == UNINITIALIZED || |
1621 initialization_state == PREMONOMORPHIC || | 1597 initialization_state == PREMONOMORPHIC || |
1622 initialization_state == MEGAMORPHIC); | 1598 initialization_state == MEGAMORPHIC); |
1623 if (FLAG_vector_stores) { | 1599 VectorStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); |
1624 VectorStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); | 1600 return stub.GetCode(); |
1625 return stub.GetCode(); | |
1626 } | |
1627 | |
1628 return StoreICInitializeStubHelper( | |
1629 isolate, ComputeExtraICState(language_mode), initialization_state); | |
1630 } | 1601 } |
1631 | 1602 |
1632 | 1603 |
1633 Handle<Code> StoreIC::initialize_stub_in_optimized_code( | 1604 Handle<Code> StoreIC::initialize_stub_in_optimized_code( |
1634 Isolate* isolate, LanguageMode language_mode, State initialization_state) { | 1605 Isolate* isolate, LanguageMode language_mode, State initialization_state) { |
1635 DCHECK(initialization_state == UNINITIALIZED || | 1606 DCHECK(initialization_state == UNINITIALIZED || |
1636 initialization_state == PREMONOMORPHIC || | 1607 initialization_state == PREMONOMORPHIC || |
1637 initialization_state == MEGAMORPHIC); | 1608 initialization_state == MEGAMORPHIC); |
1638 if (FLAG_vector_stores && initialization_state != MEGAMORPHIC) { | 1609 if (initialization_state != MEGAMORPHIC) { |
1639 VectorStoreICStub stub(isolate, StoreICState(language_mode)); | 1610 VectorStoreICStub stub(isolate, StoreICState(language_mode)); |
1640 return stub.GetCode(); | 1611 return stub.GetCode(); |
1641 } | 1612 } |
1642 | 1613 |
1643 return StoreICInitializeStubHelper( | 1614 return StoreICInitializeStubHelper( |
1644 isolate, ComputeExtraICState(language_mode), initialization_state); | 1615 isolate, ComputeExtraICState(language_mode), initialization_state); |
1645 } | 1616 } |
1646 | 1617 |
1647 | 1618 |
1648 Handle<Code> StoreIC::megamorphic_stub() { | 1619 Handle<Code> StoreIC::megamorphic_stub() { |
(...skipping 26 matching lines...) Expand all Loading... |
1675 ExtraICState state = ComputeExtraICState(language_mode); | 1646 ExtraICState state = ComputeExtraICState(language_mode); |
1676 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); | 1647 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); |
1677 } | 1648 } |
1678 | 1649 |
1679 | 1650 |
1680 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, | 1651 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, |
1681 JSReceiver::StoreFromKeyed store_mode) { | 1652 JSReceiver::StoreFromKeyed store_mode) { |
1682 if (state() == UNINITIALIZED) { | 1653 if (state() == UNINITIALIZED) { |
1683 // This is the first time we execute this inline cache. Set the target to | 1654 // This is the first time we execute this inline cache. Set the target to |
1684 // the pre monomorphic stub to delay setting the monomorphic state. | 1655 // the pre monomorphic stub to delay setting the monomorphic state. |
1685 if (FLAG_vector_stores) { | 1656 ConfigureVectorState(PREMONOMORPHIC); |
1686 ConfigureVectorState(PREMONOMORPHIC); | |
1687 } else { | |
1688 set_target(*pre_monomorphic_stub()); | |
1689 } | |
1690 TRACE_IC("StoreIC", lookup->name()); | 1657 TRACE_IC("StoreIC", lookup->name()); |
1691 return; | 1658 return; |
1692 } | 1659 } |
1693 | 1660 |
1694 bool use_ic = LookupForWrite(lookup, value, store_mode); | 1661 bool use_ic = LookupForWrite(lookup, value, store_mode); |
1695 if (!use_ic) { | 1662 if (!use_ic) { |
1696 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1663 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
1697 } | 1664 } |
1698 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); | 1665 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
1699 | 1666 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1875 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type"); | 1842 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type"); |
1876 return megamorphic_stub(); | 1843 return megamorphic_stub(); |
1877 } | 1844 } |
1878 | 1845 |
1879 MapHandleList target_receiver_maps; | 1846 MapHandleList target_receiver_maps; |
1880 TargetMaps(&target_receiver_maps); | 1847 TargetMaps(&target_receiver_maps); |
1881 if (target_receiver_maps.length() == 0) { | 1848 if (target_receiver_maps.length() == 0) { |
1882 Handle<Map> monomorphic_map = | 1849 Handle<Map> monomorphic_map = |
1883 ComputeTransitionedMap(receiver_map, store_mode); | 1850 ComputeTransitionedMap(receiver_map, store_mode); |
1884 store_mode = GetNonTransitioningStoreMode(store_mode); | 1851 store_mode = GetNonTransitioningStoreMode(store_mode); |
1885 if (FLAG_vector_stores) { | 1852 Handle<Code> handler = |
1886 Handle<Code> handler = | 1853 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1887 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1854 monomorphic_map, language_mode(), store_mode); |
1888 monomorphic_map, language_mode(), store_mode); | 1855 ConfigureVectorState(Handle<Name>::null(), monomorphic_map, handler); |
1889 ConfigureVectorState(Handle<Name>::null(), monomorphic_map, handler); | 1856 return null_handle; |
1890 return null_handle; | |
1891 } | |
1892 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( | |
1893 monomorphic_map, language_mode(), store_mode); | |
1894 } | 1857 } |
1895 | 1858 |
1896 // There are several special cases where an IC that is MONOMORPHIC can still | 1859 // There are several special cases where an IC that is MONOMORPHIC can still |
1897 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1860 // transition to a different GetNonTransitioningStoreMode IC that handles a |
1898 // superset of the original IC. Handle those here if the receiver map hasn't | 1861 // superset of the original IC. Handle those here if the receiver map hasn't |
1899 // changed or it has transitioned to a more general kind. | 1862 // changed or it has transitioned to a more general kind. |
1900 KeyedAccessStoreMode old_store_mode = | 1863 KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); |
1901 FLAG_vector_stores | |
1902 ? GetKeyedAccessStoreMode() | |
1903 : KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); | |
1904 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1864 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); |
1905 if (state() == MONOMORPHIC) { | 1865 if (state() == MONOMORPHIC) { |
1906 Handle<Map> transitioned_receiver_map = receiver_map; | 1866 Handle<Map> transitioned_receiver_map = receiver_map; |
1907 if (IsTransitionStoreMode(store_mode)) { | 1867 if (IsTransitionStoreMode(store_mode)) { |
1908 transitioned_receiver_map = | 1868 transitioned_receiver_map = |
1909 ComputeTransitionedMap(receiver_map, store_mode); | 1869 ComputeTransitionedMap(receiver_map, store_mode); |
1910 } | 1870 } |
1911 if ((receiver_map.is_identical_to(previous_receiver_map) && | 1871 if ((receiver_map.is_identical_to(previous_receiver_map) && |
1912 IsTransitionStoreMode(store_mode)) || | 1872 IsTransitionStoreMode(store_mode)) || |
1913 IsTransitionOfMonomorphicTarget(*previous_receiver_map, | 1873 IsTransitionOfMonomorphicTarget(*previous_receiver_map, |
1914 *transitioned_receiver_map)) { | 1874 *transitioned_receiver_map)) { |
1915 // If the "old" and "new" maps are in the same elements map family, or | 1875 // If the "old" and "new" maps are in the same elements map family, or |
1916 // if they at least come from the same origin for a transitioning store, | 1876 // if they at least come from the same origin for a transitioning store, |
1917 // stay MONOMORPHIC and use the map for the most generic ElementsKind. | 1877 // stay MONOMORPHIC and use the map for the most generic ElementsKind. |
1918 store_mode = GetNonTransitioningStoreMode(store_mode); | 1878 store_mode = GetNonTransitioningStoreMode(store_mode); |
1919 if (FLAG_vector_stores) { | 1879 Handle<Code> handler = |
1920 Handle<Code> handler = | 1880 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1921 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1881 transitioned_receiver_map, language_mode(), store_mode); |
1922 transitioned_receiver_map, language_mode(), store_mode); | 1882 ConfigureVectorState(Handle<Name>::null(), transitioned_receiver_map, |
1923 ConfigureVectorState(Handle<Name>::null(), transitioned_receiver_map, | 1883 handler); |
1924 handler); | 1884 return null_handle; |
1925 return null_handle; | |
1926 } | |
1927 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( | |
1928 transitioned_receiver_map, language_mode(), store_mode); | |
1929 } else if (receiver_map.is_identical_to(previous_receiver_map) && | 1885 } else if (receiver_map.is_identical_to(previous_receiver_map) && |
1930 old_store_mode == STANDARD_STORE && | 1886 old_store_mode == STANDARD_STORE && |
1931 (store_mode == STORE_AND_GROW_NO_TRANSITION || | 1887 (store_mode == STORE_AND_GROW_NO_TRANSITION || |
1932 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1888 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
1933 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { | 1889 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { |
1934 // A "normal" IC that handles stores can switch to a version that can | 1890 // A "normal" IC that handles stores can switch to a version that can |
1935 // grow at the end of the array, handle OOB accesses or copy COW arrays | 1891 // grow at the end of the array, handle OOB accesses or copy COW arrays |
1936 // and still stay MONOMORPHIC. | 1892 // and still stay MONOMORPHIC. |
1937 if (FLAG_vector_stores) { | 1893 Handle<Code> handler = |
1938 Handle<Code> handler = | 1894 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1939 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1895 receiver_map, language_mode(), store_mode); |
1940 receiver_map, language_mode(), store_mode); | 1896 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler); |
1941 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler); | 1897 return null_handle; |
1942 return null_handle; | |
1943 } | |
1944 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( | |
1945 receiver_map, language_mode(), store_mode); | |
1946 } | 1898 } |
1947 } | 1899 } |
1948 | 1900 |
1949 DCHECK(state() != GENERIC); | 1901 DCHECK(state() != GENERIC); |
1950 | 1902 |
1951 bool map_added = | 1903 bool map_added = |
1952 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1904 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1953 | 1905 |
1954 if (IsTransitionStoreMode(store_mode)) { | 1906 if (IsTransitionStoreMode(store_mode)) { |
1955 Handle<Map> transitioned_receiver_map = | 1907 Handle<Map> transitioned_receiver_map = |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1994 } | 1946 } |
1995 } | 1947 } |
1996 if (external_arrays != 0 && | 1948 if (external_arrays != 0 && |
1997 external_arrays != target_receiver_maps.length()) { | 1949 external_arrays != target_receiver_maps.length()) { |
1998 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 1950 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
1999 "unsupported combination of external and normal arrays"); | 1951 "unsupported combination of external and normal arrays"); |
2000 return megamorphic_stub(); | 1952 return megamorphic_stub(); |
2001 } | 1953 } |
2002 } | 1954 } |
2003 | 1955 |
2004 if (FLAG_vector_stores) { | 1956 MapHandleList transitioned_maps(target_receiver_maps.length()); |
2005 MapHandleList transitioned_maps(target_receiver_maps.length()); | 1957 CodeHandleList handlers(target_receiver_maps.length()); |
2006 CodeHandleList handlers(target_receiver_maps.length()); | 1958 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( |
2007 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( | 1959 &target_receiver_maps, &transitioned_maps, &handlers, store_mode, |
2008 &target_receiver_maps, &transitioned_maps, &handlers, store_mode, | 1960 language_mode()); |
2009 language_mode()); | 1961 ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers); |
2010 ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers); | 1962 return null_handle; |
2011 return null_handle; | |
2012 } | |
2013 | |
2014 return PropertyICCompiler::ComputeKeyedStorePolymorphic( | |
2015 &target_receiver_maps, store_mode, language_mode()); | |
2016 } | 1963 } |
2017 | 1964 |
2018 | 1965 |
2019 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( | 1966 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( |
2020 Handle<Map> map, KeyedAccessStoreMode store_mode) { | 1967 Handle<Map> map, KeyedAccessStoreMode store_mode) { |
2021 switch (store_mode) { | 1968 switch (store_mode) { |
2022 case STORE_TRANSITION_TO_OBJECT: | 1969 case STORE_TRANSITION_TO_OBJECT: |
2023 case STORE_AND_GROW_TRANSITION_TO_OBJECT: { | 1970 case STORE_AND_GROW_TRANSITION_TO_OBJECT: { |
2024 ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind()) | 1971 ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind()) |
2025 ? FAST_HOLEY_ELEMENTS | 1972 ? FAST_HOLEY_ELEMENTS |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 Heap* heap = receiver->GetHeap(); | 2046 Heap* heap = receiver->GetHeap(); |
2100 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { | 2047 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { |
2101 return STORE_NO_TRANSITION_HANDLE_COW; | 2048 return STORE_NO_TRANSITION_HANDLE_COW; |
2102 } else { | 2049 } else { |
2103 return STANDARD_STORE; | 2050 return STANDARD_STORE; |
2104 } | 2051 } |
2105 } | 2052 } |
2106 } | 2053 } |
2107 | 2054 |
2108 | 2055 |
2109 void KeyedStoreIC::ValidateStoreMode(Handle<Code> stub) { | |
2110 #ifdef DEBUG | |
2111 DCHECK(!FLAG_vector_stores); | |
2112 if (stub.is_null() || *stub == *megamorphic_stub() || *stub == *slow_stub()) { | |
2113 return; | |
2114 } | |
2115 | |
2116 // Query the keyed store mode. | |
2117 ExtraICState state = stub->extra_ic_state(); | |
2118 KeyedAccessStoreMode stub_mode = GetKeyedAccessStoreMode(state); | |
2119 | |
2120 MapHandleList map_list; | |
2121 stub->FindAllMaps(&map_list); | |
2122 CodeHandleList list; | |
2123 stub->FindHandlers(&list, map_list.length()); | |
2124 for (int i = 0; i < list.length(); i++) { | |
2125 Handle<Code> handler = list.at(i); | |
2126 CHECK(handler->is_handler()); | |
2127 CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key()); | |
2128 uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key()); | |
2129 // Ensure that we only see handlers we know have the store mode embedded. | |
2130 CHECK(major_key == CodeStub::KeyedStoreSloppyArguments || | |
2131 major_key == CodeStub::StoreFastElement || | |
2132 major_key == CodeStub::StoreElement || | |
2133 major_key == CodeStub::ElementsTransitionAndStore || | |
2134 *handler == *isolate()->builtins()->KeyedStoreIC_Slow()); | |
2135 // Ensure that the store mode matches that of the IC. | |
2136 CHECK(major_key == CodeStub::NoCache || | |
2137 stub_mode == CommonStoreModeBits::decode(minor_key)); | |
2138 // The one exception is the keyed store slow builtin, which doesn't include | |
2139 // store mode. | |
2140 CHECK(major_key != CodeStub::NoCache || | |
2141 *handler == *isolate()->builtins()->KeyedStoreIC_Slow()); | |
2142 } | |
2143 #endif // DEBUG | |
2144 } | |
2145 | |
2146 | |
2147 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, | 2056 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, |
2148 Handle<Object> key, | 2057 Handle<Object> key, |
2149 Handle<Object> value) { | 2058 Handle<Object> value) { |
2150 // TODO(verwaest): Let SetProperty do the migration, since storing a property | 2059 // TODO(verwaest): Let SetProperty do the migration, since storing a property |
2151 // might deprecate the current map again, if value does not fit. | 2060 // might deprecate the current map again, if value does not fit. |
2152 if (MigrateDeprecated(object)) { | 2061 if (MigrateDeprecated(object)) { |
2153 Handle<Object> result; | 2062 Handle<Object> result; |
2154 ASSIGN_RETURN_ON_EXCEPTION( | 2063 ASSIGN_RETURN_ON_EXCEPTION( |
2155 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, | 2064 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, |
2156 value, language_mode()), | 2065 value, language_mode()), |
(...skipping 10 matching lines...) Expand all Loading... |
2167 | 2076 |
2168 uint32_t index; | 2077 uint32_t index; |
2169 if ((key->IsInternalizedString() && | 2078 if ((key->IsInternalizedString() && |
2170 !String::cast(*key)->AsArrayIndex(&index)) || | 2079 !String::cast(*key)->AsArrayIndex(&index)) || |
2171 key->IsSymbol()) { | 2080 key->IsSymbol()) { |
2172 ASSIGN_RETURN_ON_EXCEPTION( | 2081 ASSIGN_RETURN_ON_EXCEPTION( |
2173 isolate(), store_handle, | 2082 isolate(), store_handle, |
2174 StoreIC::Store(object, Handle<Name>::cast(key), value, | 2083 StoreIC::Store(object, Handle<Name>::cast(key), value, |
2175 JSReceiver::MAY_BE_STORE_FROM_KEYED), | 2084 JSReceiver::MAY_BE_STORE_FROM_KEYED), |
2176 Object); | 2085 Object); |
2177 if (FLAG_vector_stores) { | 2086 if (!is_vector_set()) { |
2178 if (!is_vector_set()) { | 2087 ConfigureVectorState(MEGAMORPHIC); |
2179 ConfigureVectorState(MEGAMORPHIC); | 2088 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
2180 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 2089 "unhandled internalized string key"); |
2181 "unhandled internalized string key"); | 2090 TRACE_IC("StoreIC", key); |
2182 TRACE_IC("StoreIC", key); | |
2183 } | |
2184 } else { | |
2185 if (!is_target_set()) { | |
2186 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | |
2187 "unhandled internalized string key"); | |
2188 TRACE_IC("StoreIC", key); | |
2189 set_target(*stub); | |
2190 } | |
2191 } | 2091 } |
2192 return store_handle; | 2092 return store_handle; |
2193 } | 2093 } |
2194 | 2094 |
2195 bool use_ic = | 2095 bool use_ic = |
2196 FLAG_use_ic && !object->IsStringWrapper() && | 2096 FLAG_use_ic && !object->IsStringWrapper() && |
2197 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() && | 2097 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() && |
2198 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed()); | 2098 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed()); |
2199 if (use_ic && !object->IsSmi()) { | 2099 if (use_ic && !object->IsSmi()) { |
2200 // Don't use ICs for maps of the objects in Array's prototype chain. We | 2100 // Don't use ICs for maps of the objects in Array's prototype chain. We |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2237 if (!old_receiver_map.is_null()) { | 2137 if (!old_receiver_map.is_null()) { |
2238 if (sloppy_arguments_elements) { | 2138 if (sloppy_arguments_elements) { |
2239 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); | 2139 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); |
2240 } else if (key_is_valid_index) { | 2140 } else if (key_is_valid_index) { |
2241 // We should go generic if receiver isn't a dictionary, but our | 2141 // We should go generic if receiver isn't a dictionary, but our |
2242 // prototype chain does have dictionary elements. This ensures that | 2142 // prototype chain does have dictionary elements. This ensures that |
2243 // other non-dictionary receivers in the polymorphic case benefit | 2143 // other non-dictionary receivers in the polymorphic case benefit |
2244 // from fast path keyed stores. | 2144 // from fast path keyed stores. |
2245 if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) { | 2145 if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) { |
2246 stub = StoreElementStub(old_receiver_map, store_mode); | 2146 stub = StoreElementStub(old_receiver_map, store_mode); |
2247 | |
2248 // Validate that the store_mode in the stub can also be derived | |
2249 // from peeking in the code bits of the handlers. | |
2250 if (!FLAG_vector_stores) ValidateStoreMode(stub); | |
2251 } else { | 2147 } else { |
2252 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 2148 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
2253 "dictionary or proxy prototype"); | 2149 "dictionary or proxy prototype"); |
2254 } | 2150 } |
2255 } else { | 2151 } else { |
2256 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); | 2152 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); |
2257 } | 2153 } |
2258 } else { | 2154 } else { |
2259 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); | 2155 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); |
2260 } | 2156 } |
2261 } | 2157 } |
2262 | 2158 |
2263 if (FLAG_vector_stores) { | 2159 if (!is_vector_set() || stub.is_null()) { |
2264 if (!is_vector_set() || stub.is_null()) { | |
2265 Code* megamorphic = *megamorphic_stub(); | |
2266 if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) { | |
2267 ConfigureVectorState(MEGAMORPHIC); | |
2268 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | |
2269 *stub == megamorphic ? "set generic" : "slow stub"); | |
2270 } | |
2271 } | |
2272 } else { | |
2273 DCHECK(!is_target_set()); | |
2274 Code* megamorphic = *megamorphic_stub(); | 2160 Code* megamorphic = *megamorphic_stub(); |
2275 if (*stub == megamorphic) { | 2161 if (!stub.is_null() && (*stub == megamorphic || *stub == *slow_stub())) { |
2276 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); | 2162 ConfigureVectorState(MEGAMORPHIC); |
2277 } else if (*stub == *slow_stub()) { | 2163 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
2278 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); | 2164 *stub == megamorphic ? "set generic" : "slow stub"); |
2279 } | |
2280 | |
2281 DCHECK(!stub.is_null()); | |
2282 if (!AddressIsDeoptimizedCode()) { | |
2283 set_target(*stub); | |
2284 } | 2165 } |
2285 } | 2166 } |
2286 TRACE_IC("StoreIC", key); | 2167 TRACE_IC("StoreIC", key); |
2287 | 2168 |
2288 return store_handle; | 2169 return store_handle; |
2289 } | 2170 } |
2290 | 2171 |
2291 | 2172 |
2292 void CallIC::HandleMiss(Handle<Object> function) { | 2173 void CallIC::HandleMiss(Handle<Object> function) { |
2293 Handle<Object> name = isolate()->factory()->empty_string(); | 2174 Handle<Object> name = isolate()->factory()->empty_string(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2429 | 2310 |
2430 // Used from ic-<arch>.cc. | 2311 // Used from ic-<arch>.cc. |
2431 RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { | 2312 RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { |
2432 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2313 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2433 HandleScope scope(isolate); | 2314 HandleScope scope(isolate); |
2434 Handle<Object> receiver = args.at<Object>(0); | 2315 Handle<Object> receiver = args.at<Object>(0); |
2435 Handle<Name> key = args.at<Name>(1); | 2316 Handle<Name> key = args.at<Name>(1); |
2436 Handle<Object> value = args.at<Object>(2); | 2317 Handle<Object> value = args.at<Object>(2); |
2437 Handle<Object> result; | 2318 Handle<Object> result; |
2438 | 2319 |
2439 if (FLAG_vector_stores) { | 2320 DCHECK(args.length() == 5 || args.length() == 6); |
2440 DCHECK(args.length() == 5 || args.length() == 6); | 2321 Handle<Smi> slot = args.at<Smi>(3); |
2441 Handle<Smi> slot = args.at<Smi>(3); | 2322 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); |
2442 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); | 2323 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
2443 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2324 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { |
2444 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { | 2325 StoreICNexus nexus(vector, vector_slot); |
2445 StoreICNexus nexus(vector, vector_slot); | 2326 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2446 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | |
2447 ic.UpdateState(receiver, key); | |
2448 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
2449 ic.Store(receiver, key, value)); | |
2450 } else { | |
2451 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, | |
2452 vector->GetKind(vector_slot)); | |
2453 KeyedStoreICNexus nexus(vector, vector_slot); | |
2454 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | |
2455 ic.UpdateState(receiver, key); | |
2456 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
2457 ic.Store(receiver, key, value)); | |
2458 } | |
2459 } else { | |
2460 DCHECK(args.length() == 3); | |
2461 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | |
2462 ic.UpdateState(receiver, key); | 2327 ic.UpdateState(receiver, key); |
2463 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2328 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2464 ic.Store(receiver, key, value)); | 2329 ic.Store(receiver, key, value)); |
| 2330 } else { |
| 2331 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, |
| 2332 vector->GetKind(vector_slot)); |
| 2333 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2334 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2335 ic.UpdateState(receiver, key); |
| 2336 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2337 ic.Store(receiver, key, value)); |
2465 } | 2338 } |
2466 return *result; | 2339 return *result; |
2467 } | 2340 } |
2468 | 2341 |
2469 | 2342 |
2470 RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) { | 2343 RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) { |
2471 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2344 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2472 HandleScope scope(isolate); | 2345 HandleScope scope(isolate); |
2473 Handle<Object> receiver = args.at<Object>(0); | 2346 Handle<Object> receiver = args.at<Object>(0); |
2474 Handle<Name> key = args.at<Name>(1); | 2347 Handle<Name> key = args.at<Name>(1); |
2475 Handle<Object> value = args.at<Object>(2); | 2348 Handle<Object> value = args.at<Object>(2); |
2476 Handle<Object> result; | 2349 Handle<Object> result; |
2477 | 2350 |
2478 if (FLAG_vector_stores) { | 2351 int length = args.length(); |
2479 int length = args.length(); | 2352 DCHECK(length == 5 || length == 6); |
2480 DCHECK(length == 5 || length == 6); | 2353 // We might have slot and vector, for a normal miss (slot(3), vector(4)). |
2481 // We might have slot and vector, for a normal miss (slot(3), vector(4)). | 2354 // Or, map and vector for a transitioning store miss (map(3), vector(4)). |
2482 // Or, map and vector for a transitioning store miss (map(3), vector(4)). | 2355 // In this case, we need to recover the slot from a virtual register. |
2483 // In this case, we need to recover the slot from a virtual register. | 2356 // If length == 6, then a map is included (map(3), slot(4), vector(5)). |
2484 // If length == 6, then a map is included (map(3), slot(4), vector(5)). | 2357 Handle<Smi> slot; |
2485 Handle<Smi> slot; | 2358 Handle<TypeFeedbackVector> vector; |
2486 Handle<TypeFeedbackVector> vector; | 2359 if (length == 5) { |
2487 if (length == 5) { | 2360 if (args.at<Object>(3)->IsMap()) { |
2488 if (args.at<Object>(3)->IsMap()) { | 2361 vector = args.at<TypeFeedbackVector>(4); |
2489 vector = args.at<TypeFeedbackVector>(4); | 2362 slot = handle( |
2490 slot = handle( | 2363 *reinterpret_cast<Smi**>(isolate->virtual_slot_register_address()), |
2491 *reinterpret_cast<Smi**>(isolate->virtual_slot_register_address()), | 2364 isolate); |
2492 isolate); | |
2493 } else { | |
2494 vector = args.at<TypeFeedbackVector>(4); | |
2495 slot = args.at<Smi>(3); | |
2496 } | |
2497 } else { | 2365 } else { |
2498 vector = args.at<TypeFeedbackVector>(5); | 2366 vector = args.at<TypeFeedbackVector>(4); |
2499 slot = args.at<Smi>(4); | 2367 slot = args.at<Smi>(3); |
2500 } | |
2501 | |
2502 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | |
2503 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { | |
2504 StoreICNexus nexus(vector, vector_slot); | |
2505 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | |
2506 ic.UpdateState(receiver, key); | |
2507 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
2508 ic.Store(receiver, key, value)); | |
2509 } else { | |
2510 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, | |
2511 vector->GetKind(vector_slot)); | |
2512 KeyedStoreICNexus nexus(vector, vector_slot); | |
2513 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | |
2514 ic.UpdateState(receiver, key); | |
2515 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
2516 ic.Store(receiver, key, value)); | |
2517 } | 2368 } |
2518 } else { | 2369 } else { |
2519 DCHECK(args.length() == 3 || args.length() == 4); | 2370 vector = args.at<TypeFeedbackVector>(5); |
2520 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | 2371 slot = args.at<Smi>(4); |
| 2372 } |
| 2373 |
| 2374 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
| 2375 if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) { |
| 2376 StoreICNexus nexus(vector, vector_slot); |
| 2377 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2521 ic.UpdateState(receiver, key); | 2378 ic.UpdateState(receiver, key); |
2522 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2379 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2523 ic.Store(receiver, key, value)); | 2380 ic.Store(receiver, key, value)); |
| 2381 } else { |
| 2382 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, |
| 2383 vector->GetKind(vector_slot)); |
| 2384 KeyedStoreICNexus nexus(vector, vector_slot); |
| 2385 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2386 ic.UpdateState(receiver, key); |
| 2387 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2388 ic.Store(receiver, key, value)); |
2524 } | 2389 } |
2525 return *result; | 2390 return *result; |
2526 } | 2391 } |
2527 | 2392 |
2528 | 2393 |
2529 // Used from ic-<arch>.cc. | 2394 // Used from ic-<arch>.cc. |
2530 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { | 2395 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { |
2531 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2396 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2532 HandleScope scope(isolate); | 2397 HandleScope scope(isolate); |
2533 Handle<Object> receiver = args.at<Object>(0); | 2398 Handle<Object> receiver = args.at<Object>(0); |
2534 Handle<Object> key = args.at<Object>(1); | 2399 Handle<Object> key = args.at<Object>(1); |
2535 Handle<Object> value = args.at<Object>(2); | 2400 Handle<Object> value = args.at<Object>(2); |
2536 Handle<Object> result; | 2401 Handle<Object> result; |
2537 | 2402 |
2538 if (FLAG_vector_stores) { | 2403 DCHECK(args.length() == 5); |
2539 DCHECK(args.length() == 5); | 2404 Handle<Smi> slot = args.at<Smi>(3); |
2540 Handle<Smi> slot = args.at<Smi>(3); | 2405 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); |
2541 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); | 2406 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
2542 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2407 KeyedStoreICNexus nexus(vector, vector_slot); |
2543 KeyedStoreICNexus nexus(vector, vector_slot); | 2408 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2544 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2409 ic.UpdateState(receiver, key); |
2545 ic.UpdateState(receiver, key); | 2410 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2546 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2411 ic.Store(receiver, key, value)); |
2547 ic.Store(receiver, key, value)); | |
2548 } else { | |
2549 DCHECK(args.length() == 3); | |
2550 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | |
2551 ic.UpdateState(receiver, key); | |
2552 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | |
2553 ic.Store(receiver, key, value)); | |
2554 } | |
2555 return *result; | 2412 return *result; |
2556 } | 2413 } |
2557 | 2414 |
2558 | 2415 |
2559 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) { | 2416 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) { |
2560 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2417 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2561 HandleScope scope(isolate); | 2418 HandleScope scope(isolate); |
2562 Handle<Object> receiver = args.at<Object>(0); | 2419 Handle<Object> receiver = args.at<Object>(0); |
2563 Handle<Object> key = args.at<Object>(1); | 2420 Handle<Object> key = args.at<Object>(1); |
2564 Handle<Object> value = args.at<Object>(2); | 2421 Handle<Object> value = args.at<Object>(2); |
2565 Handle<Object> result; | 2422 Handle<Object> result; |
2566 | 2423 |
2567 if (FLAG_vector_stores) { | 2424 DCHECK(args.length() == 5); |
2568 DCHECK(args.length() == 5); | 2425 Handle<Smi> slot = args.at<Smi>(3); |
2569 Handle<Smi> slot = args.at<Smi>(3); | 2426 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); |
2570 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4); | 2427 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); |
2571 FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value()); | 2428 KeyedStoreICNexus nexus(vector, vector_slot); |
2572 KeyedStoreICNexus nexus(vector, vector_slot); | 2429 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2573 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2430 ic.UpdateState(receiver, key); |
2574 ic.UpdateState(receiver, key); | 2431 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2575 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2432 ic.Store(receiver, key, value)); |
2576 ic.Store(receiver, key, value)); | |
2577 } else { | |
2578 DCHECK(args.length() == 3); | |
2579 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | |
2580 ic.UpdateState(receiver, key); | |
2581 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
2582 isolate, result, ic.Store(receiver, key, args.at<Object>(2))); | |
2583 } | |
2584 return *result; | 2433 return *result; |
2585 } | 2434 } |
2586 | 2435 |
2587 | 2436 |
2588 RUNTIME_FUNCTION(Runtime_StoreIC_Slow) { | 2437 RUNTIME_FUNCTION(Runtime_StoreIC_Slow) { |
2589 HandleScope scope(isolate); | 2438 HandleScope scope(isolate); |
2590 DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3)); | 2439 DCHECK(args.length() == 5); |
2591 Handle<Object> object = args.at<Object>(0); | 2440 Handle<Object> object = args.at<Object>(0); |
2592 Handle<Object> key = args.at<Object>(1); | 2441 Handle<Object> key = args.at<Object>(1); |
2593 Handle<Object> value = args.at<Object>(2); | 2442 Handle<Object> value = args.at<Object>(2); |
2594 LanguageMode language_mode; | 2443 LanguageMode language_mode; |
2595 if (FLAG_vector_stores) { | 2444 StoreICNexus nexus(isolate); |
2596 StoreICNexus nexus(isolate); | 2445 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2597 StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2446 language_mode = ic.language_mode(); |
2598 language_mode = ic.language_mode(); | |
2599 } else { | |
2600 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); | |
2601 language_mode = ic.language_mode(); | |
2602 } | |
2603 Handle<Object> result; | 2447 Handle<Object> result; |
2604 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2448 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2605 isolate, result, | 2449 isolate, result, |
2606 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2450 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
2607 return *result; | 2451 return *result; |
2608 } | 2452 } |
2609 | 2453 |
2610 | 2454 |
2611 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { | 2455 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { |
2612 HandleScope scope(isolate); | 2456 HandleScope scope(isolate); |
2613 DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3)); | 2457 DCHECK(args.length() == 5); |
2614 Handle<Object> object = args.at<Object>(0); | 2458 Handle<Object> object = args.at<Object>(0); |
2615 Handle<Object> key = args.at<Object>(1); | 2459 Handle<Object> key = args.at<Object>(1); |
2616 Handle<Object> value = args.at<Object>(2); | 2460 Handle<Object> value = args.at<Object>(2); |
2617 LanguageMode language_mode; | 2461 LanguageMode language_mode; |
2618 if (FLAG_vector_stores) { | 2462 KeyedStoreICNexus nexus(isolate); |
2619 KeyedStoreICNexus nexus(isolate); | 2463 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
2620 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2464 language_mode = ic.language_mode(); |
2621 language_mode = ic.language_mode(); | |
2622 } else { | |
2623 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); | |
2624 language_mode = ic.language_mode(); | |
2625 } | |
2626 Handle<Object> result; | 2465 Handle<Object> result; |
2627 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2466 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2628 isolate, result, | 2467 isolate, result, |
2629 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2468 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
2630 return *result; | 2469 return *result; |
2631 } | 2470 } |
2632 | 2471 |
2633 | 2472 |
2634 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { | 2473 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { |
2635 TimerEventScope<TimerEventIcMiss> timer(isolate); | 2474 TimerEventScope<TimerEventIcMiss> timer(isolate); |
2636 HandleScope scope(isolate); | 2475 HandleScope scope(isolate); |
2637 // Without vector stores, length == 4. | 2476 // Length == 5 or 6, depending on whether the vector slot |
2638 // With vector stores, length == 5 or 6, depending on whether the vector slot | |
2639 // is passed in a virtual register or not. | 2477 // is passed in a virtual register or not. |
2640 DCHECK(!FLAG_vector_stores || args.length() == 5 || args.length() == 6); | 2478 DCHECK(args.length() == 5 || args.length() == 6); |
2641 Handle<Object> object = args.at<Object>(0); | 2479 Handle<Object> object = args.at<Object>(0); |
2642 Handle<Object> key = args.at<Object>(1); | 2480 Handle<Object> key = args.at<Object>(1); |
2643 Handle<Object> value = args.at<Object>(2); | 2481 Handle<Object> value = args.at<Object>(2); |
2644 Handle<Map> map = args.at<Map>(3); | 2482 Handle<Map> map = args.at<Map>(3); |
2645 LanguageMode language_mode; | 2483 LanguageMode language_mode; |
2646 if (FLAG_vector_stores) { | 2484 KeyedStoreICNexus nexus(isolate); |
2647 KeyedStoreICNexus nexus(isolate); | 2485 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2648 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2486 language_mode = ic.language_mode(); |
2649 language_mode = ic.language_mode(); | |
2650 } else { | |
2651 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); | |
2652 language_mode = ic.language_mode(); | |
2653 } | |
2654 if (object->IsJSObject()) { | 2487 if (object->IsJSObject()) { |
2655 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), | 2488 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), |
2656 map->elements_kind()); | 2489 map->elements_kind()); |
2657 } | 2490 } |
2658 Handle<Object> result; | 2491 Handle<Object> result; |
2659 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2492 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2660 isolate, result, | 2493 isolate, result, |
2661 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); | 2494 Runtime::SetObjectProperty(isolate, object, key, value, language_mode)); |
2662 return *result; | 2495 return *result; |
2663 } | 2496 } |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3145 KeyedLoadICNexus nexus(vector, vector_slot); | 2978 KeyedLoadICNexus nexus(vector, vector_slot); |
3146 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2979 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
3147 ic.UpdateState(receiver, key); | 2980 ic.UpdateState(receiver, key); |
3148 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2981 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
3149 } | 2982 } |
3150 | 2983 |
3151 return *result; | 2984 return *result; |
3152 } | 2985 } |
3153 } // namespace internal | 2986 } // namespace internal |
3154 } // namespace v8 | 2987 } // namespace v8 |
OLD | NEW |