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

Side by Side Diff: src/ic/ic.cc

Issue 2554503002: Merged: Squashed multiple commits. (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « src/factory.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // 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 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 = true> 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<Name> name,
858 Handle<Name> name, int first_index) { 858 Handle<FixedArray> array, 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
(...skipping 10 matching lines...) Expand all
879 if (fill_array) { 879 if (fill_array) {
880 Handle<Context> native_context = isolate->native_context(); 880 Handle<Context> native_context = isolate->native_context();
881 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, 881 array->set(LoadHandler::kFirstPrototypeIndex + checks_count,
882 native_context->self_weak_cell()); 882 native_context->self_weak_cell());
883 } 883 }
884 checks_count++; 884 checks_count++;
885 } 885 }
886 886
887 // Create/count entries for each global or dictionary prototype appeared in 887 // Create/count entries for each global or dictionary prototype appeared in
888 // the prototype chain contains from receiver till holder. 888 // the prototype chain contains from receiver till holder.
889 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { 889 PrototypeIterator::WhereToEnd end = name->IsPrivate()
890 ? PrototypeIterator::END_AT_NON_HIDDEN
891 : PrototypeIterator::END_AT_NULL;
892 for (PrototypeIterator iter(receiver_map, end); !iter.IsAtEnd();
893 iter.Advance()) {
890 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); 894 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
891 if (holder.is_identical_to(current)) break; 895 if (holder.is_identical_to(current)) break;
892 Handle<Map> current_map(current->map(), isolate); 896 Handle<Map> current_map(current->map(), isolate);
893 897
894 if (current_map->IsJSGlobalObjectMap()) { 898 if (current_map->IsJSGlobalObjectMap()) {
895 if (fill_array) { 899 if (fill_array) {
896 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); 900 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current);
897 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( 901 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
898 global, name, PropertyCellType::kInvalidated); 902 global, name, PropertyCellType::kInvalidated);
899 DCHECK(cell->value()->IsTheHole(isolate)); 903 DCHECK(cell->value()->IsTheHole(isolate));
(...skipping 17 matching lines...) Expand all
917 return checks_count; 921 return checks_count;
918 } 922 }
919 923
920 // Returns 0 if the validity cell check is enough to ensure that the 924 // Returns 0 if the validity cell check is enough to ensure that the
921 // prototype chain from |receiver_map| till |holder| did not change. 925 // prototype chain from |receiver_map| till |holder| did not change.
922 // If the |holder| is an empty handle then the full prototype chain is 926 // If the |holder| is an empty handle then the full prototype chain is
923 // checked. 927 // checked.
924 // Returns -1 if the handler has to be compiled or the number of prototype 928 // Returns -1 if the handler has to be compiled or the number of prototype
925 // checks otherwise. 929 // checks otherwise.
926 int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map, 930 int GetPrototypeCheckCount(Isolate* isolate, Handle<Map> receiver_map,
927 Handle<JSObject> holder) { 931 Handle<JSObject> holder, Handle<Name> name) {
928 return InitPrototypeChecks<false>(isolate, receiver_map, holder, 932 return InitPrototypeChecks<false>(isolate, receiver_map, holder, name,
929 Handle<FixedArray>(), Handle<Name>(), 0); 933 Handle<FixedArray>(), 0);
930 } 934 }
931 935
932 } // namespace 936 } // namespace
933 937
934 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, 938 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map,
935 Handle<JSObject> holder, 939 Handle<JSObject> holder,
936 Handle<Name> name, 940 Handle<Name> name,
937 Handle<Object> smi_handler) { 941 Handle<Object> smi_handler) {
938 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); 942 int checks_count =
943 GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
939 DCHECK_LE(0, checks_count); 944 DCHECK_LE(0, checks_count);
940 DCHECK(!receiver_map->IsJSGlobalObjectMap()); 945 DCHECK(!receiver_map->IsJSGlobalObjectMap());
941 946
942 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { 947 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) {
943 DCHECK(!receiver_map->is_dictionary_map()); 948 DCHECK(!receiver_map->is_dictionary_map());
944 DCHECK_LE(1, checks_count); // For native context. 949 DCHECK_LE(1, checks_count); // For native context.
945 smi_handler = 950 smi_handler =
946 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); 951 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
947 } else if (receiver_map->is_dictionary_map()) { 952 } else if (receiver_map->is_dictionary_map()) {
948 smi_handler = 953 smi_handler =
949 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); 954 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler);
950 } 955 }
951 956
952 Handle<Cell> validity_cell = 957 Handle<Cell> validity_cell =
953 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 958 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
954 DCHECK(!validity_cell.is_null()); 959 DCHECK(!validity_cell.is_null());
955 960
956 Handle<WeakCell> holder_cell = 961 Handle<WeakCell> holder_cell =
957 Map::GetOrCreatePrototypeWeakCell(holder, isolate()); 962 Map::GetOrCreatePrototypeWeakCell(holder, isolate());
958 963
959 if (checks_count == 0) { 964 if (checks_count == 0) {
960 return isolate()->factory()->NewTuple3(holder_cell, smi_handler, 965 return isolate()->factory()->NewTuple3(holder_cell, smi_handler,
961 validity_cell); 966 validity_cell);
962 } 967 }
963 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( 968 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray(
964 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); 969 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED));
965 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); 970 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
966 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); 971 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
967 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); 972 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell);
968 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, 973 InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
969 LoadHandler::kFirstPrototypeIndex); 974 LoadHandler::kFirstPrototypeIndex);
970 return handler_array; 975 return handler_array;
971 } 976 }
972 977
973 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, 978 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map,
974 Handle<Name> name) { 979 Handle<Name> name) {
975 Handle<JSObject> holder; // null handle 980 Handle<JSObject> holder; // null handle
976 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); 981 int checks_count =
982 GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
977 DCHECK_LE(0, checks_count); 983 DCHECK_LE(0, checks_count);
978 DCHECK(!receiver_map->IsJSGlobalObjectMap()); 984 DCHECK(!receiver_map->IsJSGlobalObjectMap());
979 985
980 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( 986 Handle<Object> smi_handler = LoadHandler::LoadNonExistent(
981 isolate(), receiver_map->is_dictionary_map()); 987 isolate(), receiver_map->is_dictionary_map());
982 988
983 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { 989 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) {
984 DCHECK(!receiver_map->is_dictionary_map()); 990 DCHECK(!receiver_map->is_dictionary_map());
985 DCHECK_LE(1, checks_count); // For native context. 991 DCHECK_LE(1, checks_count); // For native context.
986 smi_handler = 992 smi_handler =
987 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); 993 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler);
988 } 994 }
989 995
990 Handle<Object> validity_cell = 996 Handle<Object> validity_cell =
991 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 997 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
992 if (validity_cell.is_null()) { 998 if (validity_cell.is_null()) {
993 // This must be a case when receiver's prototype is null.
994 DCHECK_EQ(*isolate()->factory()->null_value(),
995 receiver_map->GetPrototypeChainRootMap(isolate())->prototype());
996 DCHECK_EQ(0, checks_count); 999 DCHECK_EQ(0, checks_count);
997 validity_cell = handle(Smi::FromInt(0), isolate()); 1000 validity_cell = handle(Smi::FromInt(0), isolate());
998 } 1001 }
999 1002
1000 Factory* factory = isolate()->factory(); 1003 Factory* factory = isolate()->factory();
1001 if (checks_count == 0) { 1004 if (checks_count == 0) {
1002 return factory->NewTuple3(factory->null_value(), smi_handler, 1005 return factory->NewTuple3(factory->null_value(), smi_handler,
1003 validity_cell); 1006 validity_cell);
1004 } 1007 }
1005 Handle<FixedArray> handler_array(factory->NewFixedArray( 1008 Handle<FixedArray> handler_array(factory->NewFixedArray(
1006 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); 1009 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED));
1007 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); 1010 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
1008 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); 1011 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
1009 handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value()); 1012 handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value());
1010 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, 1013 InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
1011 LoadHandler::kFirstPrototypeIndex); 1014 LoadHandler::kFirstPrototypeIndex);
1012 return handler_array; 1015 return handler_array;
1013 } 1016 }
1014 1017
1015 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { 1018 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
1016 DCHECK(lookup->state() == LookupIterator::ACCESSOR); 1019 DCHECK(lookup->state() == LookupIterator::ACCESSOR);
1017 Isolate* isolate = lookup->isolate(); 1020 Isolate* isolate = lookup->isolate();
1018 Handle<Object> accessors = lookup->GetAccessors(); 1021 Handle<Object> accessors = lookup->GetAccessors();
1019 if (accessors->IsAccessorInfo()) { 1022 if (accessors->IsAccessorInfo()) {
1020 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 1023 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
1884 1887
1885 } else { 1888 } else {
1886 DCHECK_EQ(DATA, details.type()); 1889 DCHECK_EQ(DATA, details.type());
1887 bool extend_storage = 1890 bool extend_storage =
1888 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0; 1891 Map::cast(transition->GetBackPointer())->unused_property_fields() == 0;
1889 1892
1890 FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor); 1893 FieldIndex index = FieldIndex::ForDescriptor(*transition, descriptor);
1891 smi_handler = StoreHandler::TransitionToField( 1894 smi_handler = StoreHandler::TransitionToField(
1892 isolate(), descriptor, index, representation, extend_storage); 1895 isolate(), descriptor, index, representation, extend_storage);
1893 } 1896 }
1897 // |holder| is either a receiver if the property is non-existent or
1898 // one of the prototypes.
1899 DCHECK(!holder.is_null());
1900 bool is_nonexistent = holder->map() == transition->GetBackPointer();
1901 if (is_nonexistent) holder = Handle<JSObject>::null();
1894 1902
1895 int checks_count = GetPrototypeCheckCount(isolate(), receiver_map, holder); 1903 int checks_count =
1904 GetPrototypeCheckCount(isolate(), receiver_map, holder, name);
1896 DCHECK_LE(0, checks_count); 1905 DCHECK_LE(0, checks_count);
1897 DCHECK(!receiver_map->IsJSGlobalObjectMap()); 1906 DCHECK(!receiver_map->IsJSGlobalObjectMap());
1898 1907
1899 Handle<Object> validity_cell = 1908 Handle<Object> validity_cell =
1900 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 1909 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
1901 if (validity_cell.is_null()) { 1910 if (validity_cell.is_null()) {
1902 // This must be a case when receiver's prototype is null.
1903 DCHECK_EQ(*isolate()->factory()->null_value(),
1904 receiver_map->GetPrototypeChainRootMap(isolate())->prototype());
1905 DCHECK_EQ(0, checks_count); 1911 DCHECK_EQ(0, checks_count);
1906 validity_cell = handle(Smi::FromInt(0), isolate()); 1912 validity_cell = handle(Smi::FromInt(0), isolate());
1907 } 1913 }
1908 1914
1909 Handle<WeakCell> transition_cell = Map::WeakCellForMap(transition); 1915 Handle<WeakCell> transition_cell = Map::WeakCellForMap(transition);
1910 1916
1911 Factory* factory = isolate()->factory(); 1917 Factory* factory = isolate()->factory();
1912 if (checks_count == 0) { 1918 if (checks_count == 0) {
1913 return factory->NewTuple3(transition_cell, smi_handler, validity_cell); 1919 return factory->NewTuple3(transition_cell, smi_handler, validity_cell);
1914 } 1920 }
1915 Handle<FixedArray> handler_array(factory->NewFixedArray( 1921 Handle<FixedArray> handler_array(factory->NewFixedArray(
1916 StoreHandler::kFirstPrototypeIndex + checks_count, TENURED)); 1922 StoreHandler::kFirstPrototypeIndex + checks_count, TENURED));
1917 handler_array->set(StoreHandler::kSmiHandlerIndex, *smi_handler); 1923 handler_array->set(StoreHandler::kSmiHandlerIndex, *smi_handler);
1918 handler_array->set(StoreHandler::kValidityCellIndex, *validity_cell); 1924 handler_array->set(StoreHandler::kValidityCellIndex, *validity_cell);
1919 handler_array->set(StoreHandler::kTransitionCellIndex, *transition_cell); 1925 handler_array->set(StoreHandler::kTransitionCellIndex, *transition_cell);
1920 InitPrototypeChecks(isolate(), receiver_map, holder, handler_array, name, 1926 InitPrototypeChecks(isolate(), receiver_map, holder, name, handler_array,
1921 StoreHandler::kFirstPrototypeIndex); 1927 StoreHandler::kFirstPrototypeIndex);
1922 return handler_array; 1928 return handler_array;
1923 } 1929 }
1924 1930
1925 static Handle<Code> PropertyCellStoreHandler( 1931 static Handle<Code> PropertyCellStoreHandler(
1926 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, 1932 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder,
1927 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { 1933 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) {
1928 auto constant_type = Nothing<PropertyCellConstantType>(); 1934 auto constant_type = Nothing<PropertyCellConstantType>();
1929 if (type == PropertyCellType::kConstantType) { 1935 if (type == PropertyCellType::kConstantType) {
1930 constant_type = Just(cell->GetConstantType()); 1936 constant_type = Just(cell->GetConstantType());
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
3240 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); 3246 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
3241 it.Next(); 3247 it.Next();
3242 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 3248 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
3243 Object::GetProperty(&it)); 3249 Object::GetProperty(&it));
3244 } 3250 }
3245 3251
3246 return *result; 3252 return *result;
3247 } 3253 }
3248 } // namespace internal 3254 } // namespace internal
3249 } // namespace v8 3255 } // namespace v8
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698