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

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

Issue 2471613006: [ic] Data handlers for loads of non-existent properties. (Closed)
Patch Set: Addressing comments Created 4 years, 1 month 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/ic/ic.h ('k') | no next file » | 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 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 LoadFieldStub stub(isolate(), index); 852 LoadFieldStub stub(isolate(), index);
853 return stub.GetCode(); 853 return stub.GetCode();
854 } 854 }
855 855
856 namespace { 856 namespace {
857 857
858 template <bool fill_array> 858 template <bool fill_array>
859 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, 859 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map,
860 Handle<JSObject> holder, Handle<FixedArray> array, 860 Handle<JSObject> holder, Handle<FixedArray> array,
861 Handle<Name> name) { 861 Handle<Name> name) {
862 DCHECK(holder->HasFastProperties()); 862 DCHECK(holder.is_null() || holder->HasFastProperties());
863 863
864 // The following kinds of receiver maps require custom handler compilation. 864 // The following kinds of receiver maps require custom handler compilation.
865 if (receiver_map->IsJSGlobalObjectMap()) { 865 if (receiver_map->IsJSGlobalObjectMap()) {
866 return -1; 866 return -1;
867 } 867 }
868 // We don't encode the requirement to check access rights because we already 868 // We don't encode the requirement to check access rights because we already
869 // passed the access check for current native context and the access 869 // passed the access check for current native context and the access
870 // can't be revoked. 870 // can't be revoked.
871 871
872 HandleScope scope(isolate); 872 HandleScope scope(isolate);
873 int checks_count = 0; 873 int checks_count = 0;
874 874
875 // Switch to custom compiled handler if the prototype chain contains global 875 // Create/count entries for each global or dictionary prototype appeared in
876 // or dictionary objects. 876 // the prototype chain contains from receiver till holder.
877 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { 877 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) {
878 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); 878 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
879 if (*current == *holder) break; 879 if (holder.is_identical_to(current)) break;
880 Handle<Map> current_map(current->map(), isolate); 880 Handle<Map> current_map(current->map(), isolate);
881 881
882 if (current_map->IsJSGlobalObjectMap()) { 882 if (current_map->IsJSGlobalObjectMap()) {
883 if (fill_array) { 883 if (fill_array) {
884 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); 884 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current);
885 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( 885 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell(
886 global, name, PropertyCellType::kInvalidated); 886 global, name, PropertyCellType::kInvalidated);
887 DCHECK(cell->value()->IsTheHole(isolate)); 887 DCHECK(cell->value()->IsTheHole(isolate));
888 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); 888 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell);
889 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, 889 array->set(LoadHandler::kFirstPrototypeIndex + checks_count,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray( 943 Handle<FixedArray> handler_array(isolate()->factory()->NewFixedArray(
944 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED)); 944 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED));
945 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler); 945 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
946 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell); 946 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
947 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell); 947 handler_array->set(LoadHandler::kHolderCellIndex, *holder_cell);
948 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array, 948 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array,
949 name); 949 name);
950 return handler_array; 950 return handler_array;
951 } 951 }
952 952
953 Handle<Object> LoadIC::SimpleLoadNonExistent(Handle<Map> receiver_map,
954 Handle<Name> name) {
955 Handle<JSObject> holder; // null handle
956 int checks_count = GetPrototypeCheckCount(receiver_map, holder);
957 DCHECK_LE(0, checks_count);
958 DCHECK(!receiver_map->IsJSGlobalObjectMap());
959
960 Handle<Object> smi_handler = LoadHandler::LoadNonExistent(
961 isolate(), receiver_map->is_dictionary_map());
962
963 Handle<Object> validity_cell =
964 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
965 if (validity_cell.is_null()) {
966 // This must be a case when receiver's prototype is null.
967 DCHECK_EQ(*isolate()->factory()->null_value(),
968 receiver_map->GetPrototypeChainRootMap(isolate())->prototype());
969 DCHECK_EQ(0, checks_count);
970 validity_cell = handle(Smi::FromInt(0), isolate());
971 }
972
973 Factory* factory = isolate()->factory();
974 if (checks_count == 0) {
975 return factory->NewTuple3(factory->null_value(), smi_handler,
976 validity_cell);
977 }
978 Handle<FixedArray> handler_array(factory->NewFixedArray(
979 LoadHandler::kFirstPrototypeIndex + checks_count, TENURED));
980 handler_array->set(LoadHandler::kSmiHandlerIndex, *smi_handler);
981 handler_array->set(LoadHandler::kValidityCellIndex, *validity_cell);
982 handler_array->set(LoadHandler::kHolderCellIndex, *factory->null_value());
983 InitPrototypeChecks<true>(isolate(), receiver_map, holder, handler_array,
984 name);
985 return handler_array;
986 }
987
953 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { 988 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
954 DCHECK(lookup->state() == LookupIterator::ACCESSOR); 989 DCHECK(lookup->state() == LookupIterator::ACCESSOR);
955 Isolate* isolate = lookup->isolate(); 990 Isolate* isolate = lookup->isolate();
956 Handle<Object> accessors = lookup->GetAccessors(); 991 Handle<Object> accessors = lookup->GetAccessors();
957 if (accessors->IsAccessorInfo()) { 992 if (accessors->IsAccessorInfo()) {
958 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 993 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
959 if (info->getter() != NULL && 994 if (info->getter() != NULL &&
960 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { 995 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) {
961 return false; 996 return false;
962 } 997 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); 1032 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
998 TRACE_IC("LoadIC", lookup->name()); 1033 TRACE_IC("LoadIC", lookup->name());
999 return; 1034 return;
1000 } 1035 }
1001 1036
1002 Handle<Object> code; 1037 Handle<Object> code;
1003 if (lookup->state() == LookupIterator::JSPROXY || 1038 if (lookup->state() == LookupIterator::JSPROXY ||
1004 lookup->state() == LookupIterator::ACCESS_CHECK) { 1039 lookup->state() == LookupIterator::ACCESS_CHECK) {
1005 code = slow_stub(); 1040 code = slow_stub();
1006 } else if (!lookup->IsFound()) { 1041 } else if (!lookup->IsFound()) {
1007 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) { 1042 if (kind() == Code::LOAD_IC) {
1043 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
1044 code = SimpleLoadNonExistent(receiver_map(), lookup->name());
1045 } else if (kind() == Code::LOAD_GLOBAL_IC) {
1008 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), 1046 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
1009 receiver_map()); 1047 receiver_map());
1010 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 1048 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
1011 if (code.is_null()) code = slow_stub(); 1049 if (code.is_null()) code = slow_stub();
1012 } else { 1050 } else {
1013 code = slow_stub(); 1051 code = slow_stub();
1014 } 1052 }
1015 } else { 1053 } else {
1016 if (kind() == Code::LOAD_GLOBAL_IC && 1054 if (kind() == Code::LOAD_GLOBAL_IC &&
1017 lookup->state() == LookupIterator::DATA && 1055 lookup->state() == LookupIterator::DATA &&
(...skipping 2116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3134 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); 3172 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
3135 it.Next(); 3173 it.Next();
3136 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 3174 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
3137 Object::GetProperty(&it)); 3175 Object::GetProperty(&it));
3138 } 3176 }
3139 3177
3140 return *result; 3178 return *result;
3141 } 3179 }
3142 } // namespace internal 3180 } // namespace internal
3143 } // namespace v8 3181 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698