Chromium Code Reviews| 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 <iostream> | 7 #include <iostream> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/api-arguments-inl.h" | 10 #include "src/api-arguments-inl.h" |
| (...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH); | 845 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH); |
| 846 return LoadHandler::LoadField(isolate(), index); | 846 return LoadHandler::LoadField(isolate(), index); |
| 847 } | 847 } |
| 848 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); | 848 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); |
| 849 LoadFieldStub stub(isolate(), index); | 849 LoadFieldStub stub(isolate(), index); |
| 850 return stub.GetCode(); | 850 return stub.GetCode(); |
| 851 } | 851 } |
| 852 | 852 |
| 853 namespace { | 853 namespace { |
| 854 | 854 |
| 855 template <bool fill_array> | 855 template <bool fill_array = true> |
| 856 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, | 856 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, |
| 857 Handle<JSObject> holder, Handle<FixedArray> array, | 857 Handle<JSObject> holder, Handle<FixedArray> array, |
| 858 Handle<Name> name) { | 858 Handle<Name> name, int first_index) { |
| 859 DCHECK(holder.is_null() || holder->HasFastProperties()); | 859 DCHECK(holder.is_null() || holder->HasFastProperties()); |
| 860 | 860 |
| 861 // The following kinds of receiver maps require custom handler compilation. | 861 // The following kinds of receiver maps require custom handler compilation. |
| 862 if (receiver_map->IsJSGlobalObjectMap()) { | 862 if (receiver_map->IsJSGlobalObjectMap()) { |
| 863 return -1; | 863 return -1; |
| 864 } | 864 } |
| 865 // We don't encode the requirement to check access rights because we already | 865 // We don't encode the requirement to check access rights because we already |
| 866 // passed the access check for current native context and the access | 866 // passed the access check for current native context and the access |
| 867 // can't be revoked. | 867 // can't be revoked. |
| 868 | 868 |
| 869 HandleScope scope(isolate); | 869 HandleScope scope(isolate); |
| 870 int checks_count = 0; | 870 int checks_count = 0; |
| 871 | 871 |
| 872 // Create/count entries for each global or dictionary prototype appeared in | 872 // Create/count entries for each global or dictionary prototype appeared in |
| 873 // the prototype chain contains from receiver till holder. | 873 // the prototype chain contains from receiver till holder. |
| 874 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { | 874 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { |
| 875 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); | 875 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); |
| 876 if (holder.is_identical_to(current)) break; | 876 if (holder.is_identical_to(current)) break; |
| 877 Handle<Map> current_map(current->map(), isolate); | 877 Handle<Map> current_map(current->map(), isolate); |
| 878 | 878 |
| 879 if (current_map->IsJSGlobalObjectMap()) { | 879 if (current_map->IsJSGlobalObjectMap()) { |
| 880 if (fill_array) { | 880 if (fill_array) { |
| 881 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); | 881 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); |
| 882 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( | 882 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( |
| 883 global, name, PropertyCellType::kInvalidated); | 883 global, name, PropertyCellType::kInvalidated); |
| 884 DCHECK(cell->value()->IsTheHole(isolate)); | 884 DCHECK(cell->value()->IsTheHole(isolate)); |
| 885 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); | 885 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); |
| 886 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, | 886 array->set(first_index + checks_count, *weak_cell); |
| 887 *weak_cell); | |
| 888 } | 887 } |
| 889 checks_count++; | 888 checks_count++; |
| 890 | 889 |
| 891 } else if (current_map->is_dictionary_map()) { | 890 } else if (current_map->is_dictionary_map()) { |
| 892 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. | 891 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. |
| 893 if (fill_array) { | 892 if (fill_array) { |
| 894 DCHECK_EQ(NameDictionary::kNotFound, | 893 DCHECK_EQ(NameDictionary::kNotFound, |
| 895 current->property_dictionary()->FindEntry(name)); | 894 current->property_dictionary()->FindEntry(name)); |
| 896 Handle<WeakCell> weak_cell = | 895 Handle<WeakCell> weak_cell = |
| 897 Map::GetOrCreatePrototypeWeakCell(current, isolate); | 896 Map::GetOrCreatePrototypeWeakCell(current, isolate); |
| 898 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, | 897 array->set(first_index + checks_count, *weak_cell); |
| 899 *weak_cell); | |
| 900 } | 898 } |
| 901 checks_count++; | 899 checks_count++; |
| 902 } | 900 } |
| 903 } | 901 } |
| 904 return checks_count; | 902 return checks_count; |
| 905 } | 903 } |
| 906 | 904 |
| 905 // Returns 0 if the validity cell check is enough to ensure that the | |
| 906 // prototype chain from |receiver_map| till |holder| did not change. | |
| 907 // If the |holder| is an empty handle then the full prototype chain is | |
| 908 // checked. | |
| 909 // Returns -1 if the handler has to be compiled or the number of prototype | |
| 910 // checks otherwise. | |
| 911 int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map, | |
| 912 Handle<JSObject> holder) { | |
| 913 return InitPrototypeChecks<false>(isolate, receiver_map, holder, | |
| 914 Handle<FixedArray>(), Handle<Name>(), 0); | |
| 915 } | |
| 916 | |
| 907 } // namespace | 917 } // namespace |
| 908 | 918 |
| 909 int LoadIC::GetPrototypeCheckCount(Handle<Map> receiver_map, | |
| 910 Handle<JSObject> holder) { | |
| 911 return InitPrototypeChecks<false>(isolate(), receiver_map, holder, | |
| 912 Handle<FixedArray>(), Handle<Name>()); | |
| 913 } | |
| 914 | |
| 915 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, | 919 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, |
| 916 Handle<JSObject> holder, | 920 Handle<JSObject> holder, |
| 917 Handle<Name> name, | 921 Handle<Name> name, |
| 918 Handle<Object> smi_handler) { | 922 Handle<Object> smi_handler) { |
| 919 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 923 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); |
| 920 DCHECK_LE(0, checks_count); | 924 DCHECK_LE(0, checks_count); |
| 921 | 925 |
| 922 if (receiver_map->IsJSGlobalObjectMap()) { | 926 if (receiver_map->IsJSGlobalObjectMap()) { |
| 923 UNREACHABLE(); | 927 UNREACHABLE(); |
| 924 } else if (receiver_map->is_dictionary_map()) { | 928 } else if (receiver_map->is_dictionary_map()) { |
| 925 smi_handler = | 929 smi_handler = |
| 926 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); | 930 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); |
| 927 } | 931 } |
| 928 | 932 |
| 929 Handle<Cell> validity_cell = | 933 Handle<Cell> validity_cell = |
| 930 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 934 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
| 931 DCHECK(!validity_cell.is_null()); | 935 DCHECK(!validity_cell.is_null()); |
| 932 | 936 |
| 933 Handle<WeakCell> holder_cell = | 937 Handle<WeakCell> holder_cell = |
| 934 Map::GetOrCreatePrototypeWeakCell(holder, isolate()); | 938 Map::GetOrCreatePrototypeWeakCell(holder, isolate()); |
| 935 | 939 |
| 936 if (checks_count == 0) { | 940 if (checks_count == 0) { |
| 937 return isolate()->factory()->NewTuple3(holder_cell, smi_handler, | 941 return isolate()->factory()->NewTuple3(holder_cell, smi_handler, |
| 938 validity_cell); | 942 validity_cell); |
| 939 } | 943 } |
| 940 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( | 944 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( |
| 941 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); | 945 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); |
| 942 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); | 946 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); |
| 943 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); | 947 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); |
| 944 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); | 948 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); |
| 945 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array, | 949 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, |
| 946 name); | 950 LoadHandler::kFirstPrototypeIndex); |
| 947 return handler_array; | 951 return handler_array; |
| 948 } | 952 } |
| 949 | 953 |
| 950 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, | 954 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, |
| 951 Handle<Name> name) { | 955 Handle<Name> name) { |
| 952 Handle<JSObject> holder; // null handle | 956 Handle<JSObject> holder; // null handle |
| 953 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 957 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); |
| 954 DCHECK_LE(0, checks_count); | 958 DCHECK_LE(0, checks_count); |
| 955 DCHECK(!receiver_map->IsJSGlobalObjectMap()); | 959 DCHECK(!receiver_map->IsJSGlobalObjectMap()); |
| 956 | 960 |
| 957 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( | 961 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( |
| 958 isolate(), receiver_map->is_dictionary_map()); | 962 isolate(), receiver_map->is_dictionary_map()); |
| 959 | 963 |
| 960 Handle<Object> validity_cell = | 964 Handle<Object> validity_cell = |
| 961 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 965 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
| 962 if (validity_cell.is_null()) { | 966 if (validity_cell.is_null()) { |
| 963 // This must be a case when receiver's prototype is null. | 967 // This must be a case when receiver's prototype is null. |
| 964 DCHECK_EQ(*isolate()->factory()->null_value(), | 968 DCHECK_EQ(*isolate()->factory()->null_value(), |
| 965 receiver_map->GetPrototypeChainRootMap(isolate())->prototype()); | 969 receiver_map->GetPrototypeChainRootMap(isolate())->prototype()); |
| 966 DCHECK_EQ(0, checks_count); | 970 DCHECK_EQ(0, checks_count); |
| 967 validity_cell = handle(Smi::FromInt(0), isolate()); | 971 validity_cell = handle(Smi::FromInt(0), isolate()); |
| 968 } | 972 } |
| 969 | 973 |
| 970 Factory* factory = isolate()->factory(); | 974 Factory* factory = isolate()->factory(); |
| 971 if (checks_count == 0) { | 975 if (checks_count == 0) { |
| 972 return factory->NewTuple3(factory->null_value(), smi_handler, | 976 return factory->NewTuple3(factory->null_value(), smi_handler, |
| 973 validity_cell); | 977 validity_cell); |
| 974 } | 978 } |
| 975 Handle<FixedArray> handler_array(factory->NewFixedArray( | 979 Handle<FixedArray> handler_array(factory->NewFixedArray( |
| 976 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); | 980 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); |
| 977 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); | 981 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); |
| 978 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); | 982 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); |
| 979 handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value()); | 983 handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value()); |
| 980 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array, | 984 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, |
| 981 name); | 985 LoadHandler::kFirstPrototypeIndex); |
| 982 return handler_array; | 986 return handler_array; |
| 983 } | 987 } |
| 984 | 988 |
| 985 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { | 989 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
| 986 DCHECK(lookup->state() == LookupIterator::ACCESSOR); | 990 DCHECK(lookup->state() == LookupIterator::ACCESSOR); |
| 987 Isolate* isolate = lookup->isolate(); | 991 Isolate* isolate = lookup->isolate(); |
| 988 Handle<Object> accessors = lookup->GetAccessors(); | 992 Handle<Object> accessors = lookup->GetAccessors(); |
| 989 if (accessors->IsAccessorInfo()) { | 993 if (accessors->IsAccessorInfo()) { |
| 990 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 994 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
| 991 if (info->getter() != NULL && | 995 if (info->getter() != NULL && |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1812 if (!use_ic) { | 1816 if (!use_ic) { |
| 1813 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1817 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
| 1814 } | 1818 } |
| 1815 Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) | 1819 Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) |
| 1816 : Handle<Object>::cast(slow_stub()); | 1820 : Handle<Object>::cast(slow_stub()); |
| 1817 | 1821 |
| 1818 PatchCache(lookup->name(), handler); | 1822 PatchCache(lookup->name(), handler); |
| 1819 TRACE_IC("StoreIC", lookup->name()); | 1823 TRACE_IC("StoreIC", lookup->name()); |
| 1820 } | 1824 } |
| 1821 | 1825 |
| 1826 Handle<Object> StoreIC::StoreTransition(Handle<Map> receiver_map, | |
| 1827 Handle<JSObject> holder, | |
| 1828 Handle<Map> transition, | |
| 1829 Handle<Name> name) { | |
| 1830 int descriptor = transition->LastAdded(); | |
| 1831 Handle<DescriptorArray> descriptors(transition->instance_descriptors()); | |
| 1832 PropertyDetails details = descriptors->GetDetails(descriptor); | |
| 1833 Representation representation = details.representation(); | |
| 1834 DCHECK(!representation.IsNone()); | |
| 1835 | |
| 1836 // Stub is never generated for objects that require access checks. | |
|
Jakob Kummerow
2016/11/10 14:13:07
No stubs are generated at all ;-) Suggestion:
"Dec
Igor Sheludko
2016/11/10 15:31:55
Done.
| |
| 1837 DCHECK(!transition->is_access_check_needed()); | |
| 1838 | |
| 1839 Handle<Object> smi_handler; | |
| 1840 if (details.type() == DATA_CONSTANT) { | |
| 1841 smi_handler = StoreHandler::TransitionToConstant(isolate(), descriptor); | |
| 1842 | |
| 1843 } else { | |
| 1844 DCHECK_EQ(DATA, details.type()); | |
| 1845 bool extend_storage = | |
| 1846 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0; | |
| 1847 | |
| 1848 FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor); | |
| 1849 smi_handler = StoreHandler::TransitionToField( | |
| 1850 isolate(), descriptor, index, representation, extend_storage); | |
| 1851 } | |
| 1852 | |
| 1853 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); | |
| 1854 DCHECK_LE(0, checks_count); | |
| 1855 DCHECK(!receiver_map->IsJSGlobalObjectMap()); | |
| 1856 | |
| 1857 // Stub is never generated for objects that require access checks. | |
|
Jakob Kummerow
2016/11/10 14:13:07
You've already checked this above.
Igor Sheludko
2016/11/10 15:31:55
Done.
| |
| 1858 DCHECK(!transition->is_access_check_needed()); | |
| 1859 | |
| 1860 Handle<Object> validity_cell = | |
| 1861 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | |
| 1862 if (validity_cell.is_null()) { | |
| 1863 // This must be a case when receiver's prototype is null. | |
| 1864 DCHECK_EQ(*isolate()->factory()->null_value(), | |
| 1865 receiver_map->GetPrototypeChainRootMap(isolate())->prototype()); | |
| 1866 DCHECK_EQ(0, checks_count); | |
| 1867 validity_cell = handle(Smi::FromInt(0), isolate()); | |
| 1868 } | |
| 1869 | |
| 1870 Handle<WeakCell> transition_cell = Map::WeakCellForMap(transition); | |
| 1871 | |
| 1872 Factory* factory = isolate()->factory(); | |
| 1873 if (checks_count == 0) { | |
| 1874 return factory->NewTuple3(transition_cell, smi_handler, validity_cell); | |
| 1875 } | |
| 1876 Handle<FixedArray> handler_array(factory->NewFixedArray( | |
| 1877 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); | |
|
Jakob Kummerow
2016/11/10 14:13:07
s/LoadHandler/StoreHandler/ here and in the next t
Igor Sheludko
2016/11/10 15:31:55
Done.
| |
| 1878 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); | |
| 1879 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); | |
| 1880 handler_array->set(LoadHandler::kHolderCellIndex, *transition_cell); | |
|
Jakob Kummerow
2016/11/10 14:13:07
s/kHolderCellIndex/kTransitionCellIndex/
Igor Sheludko
2016/11/10 15:31:55
Done.
| |
| 1881 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, | |
| 1882 StoreHandler::kFirstPrototypeIndex); | |
| 1883 return handler_array; | |
| 1884 } | |
| 1822 | 1885 |
| 1823 static Handle<Code> PropertyCellStoreHandler( | 1886 static Handle<Code> PropertyCellStoreHandler( |
| 1824 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, | 1887 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, |
| 1825 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 1888 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { |
| 1826 auto constant_type = Nothing<PropertyCellConstantType>(); | 1889 auto constant_type = Nothing<PropertyCellConstantType>(); |
| 1827 if (type == PropertyCellType::kConstantType) { | 1890 if (type == PropertyCellType::kConstantType) { |
| 1828 constant_type = Just(cell->GetConstantType()); | 1891 constant_type = Just(cell->GetConstantType()); |
| 1829 } | 1892 } |
| 1830 StoreGlobalStub stub(isolate, type, constant_type, | 1893 StoreGlobalStub stub(isolate, type, constant_type, |
| 1831 receiver->IsJSGlobalProxy()); | 1894 receiver->IsJSGlobalProxy()); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1848 auto store_target = lookup->GetStoreTarget(); | 1911 auto store_target = lookup->GetStoreTarget(); |
| 1849 if (store_target->IsJSGlobalObject()) { | 1912 if (store_target->IsJSGlobalObject()) { |
| 1850 break; // Custom-compiled handler. | 1913 break; // Custom-compiled handler. |
| 1851 } | 1914 } |
| 1852 // Currently not handled by CompileStoreTransition. | 1915 // Currently not handled by CompileStoreTransition. |
| 1853 if (!holder->HasFastProperties()) { | 1916 if (!holder->HasFastProperties()) { |
| 1854 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 1917 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |
| 1855 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 1918 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); |
| 1856 return slow_stub(); | 1919 return slow_stub(); |
| 1857 } | 1920 } |
| 1858 | |
| 1859 DCHECK(lookup->IsCacheableTransition()); | 1921 DCHECK(lookup->IsCacheableTransition()); |
| 1922 if (FLAG_tf_store_ic_stub) { | |
| 1923 Handle<Map> transition = lookup->transition_map(); | |
| 1924 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransitionDH); | |
| 1925 return StoreTransition(receiver_map(), holder, transition, | |
| 1926 lookup->name()); | |
| 1927 } | |
| 1860 break; // Custom-compiled handler. | 1928 break; // Custom-compiled handler. |
| 1861 } | 1929 } |
| 1862 | 1930 |
| 1863 case LookupIterator::INTERCEPTOR: { | 1931 case LookupIterator::INTERCEPTOR: { |
| 1864 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate())); | 1932 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate())); |
| 1865 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); | 1933 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); |
| 1866 StoreInterceptorStub stub(isolate()); | 1934 StoreInterceptorStub stub(isolate()); |
| 1867 return stub.GetCode(); | 1935 return stub.GetCode(); |
| 1868 } | 1936 } |
| 1869 | 1937 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1989 if (store_target->IsJSGlobalObject()) { | 2057 if (store_target->IsJSGlobalObject()) { |
| 1990 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition); | 2058 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition); |
| 1991 Handle<PropertyCell> cell = lookup->transition_cell(); | 2059 Handle<PropertyCell> cell = lookup->transition_cell(); |
| 1992 cell->set_value(*value); | 2060 cell->set_value(*value); |
| 1993 Handle<Code> code = PropertyCellStoreHandler( | 2061 Handle<Code> code = PropertyCellStoreHandler( |
| 1994 isolate(), store_target, Handle<JSGlobalObject>::cast(store_target), | 2062 isolate(), store_target, Handle<JSGlobalObject>::cast(store_target), |
| 1995 lookup->name(), cell, PropertyCellType::kConstant); | 2063 lookup->name(), cell, PropertyCellType::kConstant); |
| 1996 cell->set_value(isolate()->heap()->the_hole_value()); | 2064 cell->set_value(isolate()->heap()->the_hole_value()); |
| 1997 return code; | 2065 return code; |
| 1998 } | 2066 } |
| 2067 DCHECK(!FLAG_tf_store_ic_stub); | |
| 1999 Handle<Map> transition = lookup->transition_map(); | 2068 Handle<Map> transition = lookup->transition_map(); |
| 2000 // Currently not handled by CompileStoreTransition. | 2069 // Currently not handled by CompileStoreTransition. |
| 2001 DCHECK(holder->HasFastProperties()); | 2070 DCHECK(holder->HasFastProperties()); |
| 2002 | 2071 |
| 2003 DCHECK(lookup->IsCacheableTransition()); | 2072 DCHECK(lookup->IsCacheableTransition()); |
| 2004 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition); | 2073 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition); |
| 2005 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 2074 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
| 2006 return compiler.CompileStoreTransition(transition, lookup->name()); | 2075 return compiler.CompileStoreTransition(transition, lookup->name()); |
| 2007 } | 2076 } |
| 2008 | 2077 |
| (...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3145 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3214 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 3146 it.Next(); | 3215 it.Next(); |
| 3147 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3216 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 3148 Object::GetProperty(&it)); | 3217 Object::GetProperty(&it)); |
| 3149 } | 3218 } |
| 3150 | 3219 |
| 3151 return *result; | 3220 return *result; |
| 3152 } | 3221 } |
| 3153 } // namespace internal | 3222 } // namespace internal |
| 3154 } // namespace v8 | 3223 } // namespace v8 |
| OLD | NEW |