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

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

Issue 2421883002: [ic] Support data handlers that represent loads of constants from prototypes. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« 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 "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api-arguments-inl.h" 8 #include "src/api-arguments-inl.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) { 850 Handle<Object> LoadIC::SimpleFieldLoad(FieldIndex index) {
851 if (FLAG_tf_load_ic_stub) { 851 if (FLAG_tf_load_ic_stub) {
852 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH); 852 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
853 return SmiHandler::MakeLoadFieldHandler(isolate(), index); 853 return SmiHandler::MakeLoadFieldHandler(isolate(), index);
854 } 854 }
855 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub); 855 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
856 LoadFieldStub stub(isolate(), index); 856 LoadFieldStub stub(isolate(), index);
857 return stub.GetCode(); 857 return stub.GetCode();
858 } 858 }
859 859
860 Handle<Object> LoadIC::SimpleFieldLoadFromPrototype(FieldIndex index, 860 bool LoadIC::IsPrototypeValidityCellCheckEnough(Handle<Map> receiver_map,
861 Handle<Map> receiver_map, 861 Handle<JSObject> holder) {
862 Handle<JSObject> holder) {
863 if (!FLAG_tf_load_ic_stub) return Handle<Object>::null();
864
865 DCHECK(holder->HasFastProperties()); 862 DCHECK(holder->HasFastProperties());
866 863
867 // The following kinds of receiver maps require custom handler compilation. 864 // The following kinds of receiver maps require custom handler compilation.
868 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap() || 865 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap() ||
869 receiver_map->IsJSGlobalObjectMap() || 866 receiver_map->IsJSGlobalObjectMap() ||
870 receiver_map->is_dictionary_map()) { 867 receiver_map->is_dictionary_map()) {
871 return Handle<Object>::null(); 868 return false;
872 } 869 }
873 870
874 // Switch to custom compiled handler if the prototype chain contains global 871 // Switch to custom compiled handler if the prototype chain contains global
875 // or dictionary objects. 872 // or dictionary objects.
876 for (PrototypeIterator iter(*receiver_map); !iter.IsAtEnd(); iter.Advance()) { 873 for (PrototypeIterator iter(*receiver_map); !iter.IsAtEnd(); iter.Advance()) {
877 JSObject* current = iter.GetCurrent<JSObject>(); 874 JSObject* current = iter.GetCurrent<JSObject>();
878 if (current == *holder) break; 875 if (current == *holder) break;
879 Map* current_map = current->map(); 876 Map* current_map = current->map();
880 if (current_map->IsJSGlobalObjectMap() || 877 if (current_map->IsJSGlobalObjectMap() ||
881 current_map->IsJSGlobalProxyMap() || current_map->is_dictionary_map()) { 878 current_map->IsJSGlobalProxyMap() || current_map->is_dictionary_map()) {
882 return Handle<Object>::null(); 879 return false;
883 } 880 }
884 // Only objects that do not require access checks are allowed in stubs. 881 // Only objects that do not require access checks are allowed in stubs.
885 DCHECK(!current_map->is_access_check_needed()); 882 DCHECK(!current_map->is_access_check_needed());
886 } 883 }
887 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH); 884 return true;
885 }
886
887 Handle<Object> LoadIC::SimpleLoadFromPrototype(Handle<Map> receiver_map,
888 Handle<JSObject> holder,
889 Handle<Object> smi_handler) {
890 DCHECK(IsPrototypeValidityCellCheckEnough(receiver_map, holder));
891
888 Handle<Cell> validity_cell = 892 Handle<Cell> validity_cell =
889 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 893 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
890 DCHECK(!validity_cell.is_null()); 894 DCHECK(!validity_cell.is_null());
891 895
892 Handle<Object> handler(SmiHandler::MakeLoadFieldHandler(isolate(), index));
893 Factory* factory = isolate()->factory(); 896 Factory* factory = isolate()->factory();
894 897
895 Handle<WeakCell> holder_cell = factory->NewWeakCell(holder); 898 Handle<WeakCell> holder_cell = factory->NewWeakCell(holder);
896 return factory->NewTuple3(validity_cell, holder_cell, handler); 899 return factory->NewTuple3(validity_cell, holder_cell, smi_handler);
897 } 900 }
898 901
899 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { 902 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
900 DCHECK(lookup->state() == LookupIterator::ACCESSOR); 903 DCHECK(lookup->state() == LookupIterator::ACCESSOR);
901 Isolate* isolate = lookup->isolate(); 904 Isolate* isolate = lookup->isolate();
902 Handle<Object> accessors = lookup->GetAccessors(); 905 Handle<Object> accessors = lookup->GetAccessors();
903 if (accessors->IsAccessorInfo()) { 906 if (accessors->IsAccessorInfo()) {
904 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 907 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
905 if (info->getter() != NULL && 908 if (info->getter() != NULL &&
906 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { 909 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); 1192 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1190 return slow_stub(); 1193 return slow_stub();
1191 } 1194 }
1192 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); 1195 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal);
1193 return isolate()->builtins()->LoadIC_Normal(); 1196 return isolate()->builtins()->LoadIC_Normal();
1194 } 1197 }
1195 1198
1196 // -------------- Fields -------------- 1199 // -------------- Fields --------------
1197 if (lookup->property_details().type() == DATA) { 1200 if (lookup->property_details().type() == DATA) {
1198 FieldIndex field = lookup->GetFieldIndex(); 1201 FieldIndex field = lookup->GetFieldIndex();
1202 Handle<Object> smi_handler = SimpleFieldLoad(field);
1199 if (receiver_is_holder) { 1203 if (receiver_is_holder) {
1200 return SimpleFieldLoad(field); 1204 return smi_handler;
1201 } 1205 }
1202 Handle<Object> handler = 1206 if (FLAG_tf_load_ic_stub &&
1203 SimpleFieldLoadFromPrototype(field, map, holder); 1207 IsPrototypeValidityCellCheckEnough(map, holder)) {
1204 if (!handler.is_null()) { 1208 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
1205 return handler; 1209 return SimpleLoadFromPrototype(map, holder, smi_handler);
1206 } 1210 }
1207 break; // Custom-compiled handler. 1211 break; // Custom-compiled handler.
1208 } 1212 }
1209 1213
1210 // -------------- Constant properties -------------- 1214 // -------------- Constant properties --------------
1211 DCHECK(lookup->property_details().type() == DATA_CONSTANT); 1215 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1212 if (receiver_is_holder) { 1216 if (FLAG_tf_load_ic_stub) {
1213 if (FLAG_tf_load_ic_stub) { 1217 Handle<Object> smi_handler = SmiHandler::MakeLoadConstantHandler(
1218 isolate(), lookup->GetConstantIndex());
1219 if (receiver_is_holder) {
1214 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH); 1220 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH);
1215 return SmiHandler::MakeLoadConstantHandler( 1221 return smi_handler;
1216 isolate(), lookup->GetConstantIndex());
1217 } 1222 }
1218 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); 1223 if (IsPrototypeValidityCellCheckEnough(map, holder)) {
1219 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); 1224 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH);
1220 return stub.GetCode(); 1225 return SimpleLoadFromPrototype(map, holder, smi_handler);
1226 }
1227 } else {
1228 if (receiver_is_holder) {
1229 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub);
1230 LoadConstantStub stub(isolate(), lookup->GetConstantIndex());
1231 return stub.GetCode();
1232 }
1221 } 1233 }
1222 break; // Custom-compiled handler. 1234 break; // Custom-compiled handler.
1223 } 1235 }
1224 1236
1225 case LookupIterator::INTEGER_INDEXED_EXOTIC: 1237 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1226 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); 1238 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1227 return slow_stub(); 1239 return slow_stub();
1228 case LookupIterator::ACCESS_CHECK: 1240 case LookupIterator::ACCESS_CHECK:
1229 case LookupIterator::JSPROXY: 1241 case LookupIterator::JSPROXY:
1230 case LookupIterator::NOT_FOUND: 1242 case LookupIterator::NOT_FOUND:
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after
2966 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); 2978 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
2967 it.Next(); 2979 it.Next();
2968 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 2980 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2969 Object::GetProperty(&it)); 2981 Object::GetProperty(&it));
2970 } 2982 }
2971 2983
2972 return *result; 2984 return *result;
2973 } 2985 }
2974 } // namespace internal 2986 } // namespace internal
2975 } // namespace v8 2987 } // 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