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

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

Issue 1974793002: [IC] Only cache handlers on a map that were compiled for that map (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: make gcc happy Created 4 years, 7 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.h" 8 #include "src/api.h"
9 #include "src/api-arguments.h" 9 #include "src/api-arguments.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 TRACE_IC("LoadIC", lookup->name()); 929 TRACE_IC("LoadIC", lookup->name());
930 } 930 }
931 931
932 932
933 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 933 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
934 isolate()->stub_cache()->Set(name, map, code); 934 isolate()->stub_cache()->Set(name, map, code);
935 } 935 }
936 936
937 937
938 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { 938 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
939 // Try to find a globally shared handler stub.
940 Handle<Code> code = GetMapIndependentHandler(lookup);
941 if (!code.is_null()) return code;
942
943 // Otherwise check the map's handler cache for a map-specific handler, and
944 // compile one if the cache comes up empty.
939 bool receiver_is_holder = 945 bool receiver_is_holder =
940 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 946 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
941 CacheHolderFlag flag; 947 CacheHolderFlag flag;
942 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 948 Handle<Map> stub_holder_map;
943 receiver_map(), receiver_is_holder, isolate(), &flag); 949 if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
950 stub_holder_map = IC::GetHandlerCacheHolder(
951 receiver_map(), receiver_is_holder, isolate(), &flag);
952 } else {
953 DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
954 // Store handlers cannot be cached on prototypes.
955 flag = kCacheOnReceiver;
956 stub_holder_map = receiver_map();
957 }
944 958
945 Handle<Code> code = PropertyHandlerCompiler::Find( 959 code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(),
946 lookup->name(), stub_holder_map, kind(), flag); 960 flag);
947 // Use the cached value if it exists, and if it is different from the 961 // Use the cached value if it exists, and if it is different from the
948 // handler that just missed. 962 // handler that just missed.
949 if (!code.is_null()) { 963 if (!code.is_null()) {
950 Handle<Code> handler; 964 Handle<Code> handler;
951 if (maybe_handler_.ToHandle(&handler)) { 965 if (maybe_handler_.ToHandle(&handler)) {
952 if (!handler.is_identical_to(code)) { 966 if (!handler.is_identical_to(code)) {
953 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); 967 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
954 return code; 968 return code;
955 } 969 }
956 } else { 970 } else {
(...skipping 10 matching lines...) Expand all
967 } 981 }
968 } else { 982 } else {
969 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); 983 TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
970 return code; 984 return code;
971 } 985 }
972 } 986 }
973 } 987 }
974 988
975 code = CompileHandler(lookup, value, flag); 989 code = CompileHandler(lookup, value, flag);
976 DCHECK(code->is_handler()); 990 DCHECK(code->is_handler());
977 991 DCHECK(Code::ExtractCacheHolderFromFlags(code->flags()) == flag);
978 // TODO(mvstanton): we'd only like to cache code on the map when it's custom 992 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
979 // code compiled for this map, otherwise it's already cached in the global
980 // code cache. We are also guarding against installing code with flags that
981 // don't match the desired CacheHolderFlag computed above, which would lead to
982 // invalid lookups later.
983 bool is_normal = receiver_is_holder &&
984 !lookup->GetHolder<JSReceiver>()->HasFastProperties();
985 if (!is_normal && Code::ExtractCacheHolderFromFlags(code->flags()) == flag) {
986 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
987 }
988 993
989 return code; 994 return code;
990 } 995 }
991 996
992 997 Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
993 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
994 Handle<Object> unused,
995 CacheHolderFlag cache_holder) {
996 Handle<Object> receiver = lookup->GetReceiver(); 998 Handle<Object> receiver = lookup->GetReceiver();
997 if (receiver->IsString() && 999 if (receiver->IsString() &&
998 Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 1000 Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
999 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); 1001 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
1000 return SimpleFieldLoad(index); 1002 return SimpleFieldLoad(index);
1001 } 1003 }
1002 1004
1003 if (receiver->IsStringWrapper() && 1005 if (receiver->IsStringWrapper() &&
1004 Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 1006 Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
1005 TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub); 1007 TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub);
(...skipping 11 matching lines...) Expand all
1017 Handle<Code> stub; 1019 Handle<Code> stub;
1018 TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub); 1020 TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
1019 FunctionPrototypeStub function_prototype_stub(isolate()); 1021 FunctionPrototypeStub function_prototype_stub(isolate());
1020 return function_prototype_stub.GetCode(); 1022 return function_prototype_stub.GetCode();
1021 } 1023 }
1022 1024
1023 Handle<Map> map = receiver_map(); 1025 Handle<Map> map = receiver_map();
1024 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1026 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1025 bool receiver_is_holder = receiver.is_identical_to(holder); 1027 bool receiver_is_holder = receiver.is_identical_to(holder);
1026 switch (lookup->state()) { 1028 switch (lookup->state()) {
1027 case LookupIterator::INTERCEPTOR: { 1029 case LookupIterator::INTERCEPTOR:
1028 DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 1030 break; // Custom-compiled handler.
1029 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor);
1030 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1031 // Perform a lookup behind the interceptor. Copy the LookupIterator since
1032 // the original iterator will be used to fetch the value.
1033 LookupIterator it = *lookup;
1034 it.Next();
1035 LookupForRead(&it);
1036 return compiler.CompileLoadInterceptor(&it);
1037 }
1038 1031
1039 case LookupIterator::ACCESSOR: { 1032 case LookupIterator::ACCESSOR: {
1040 // Use simple field loads for some well-known callback properties. 1033 // Use simple field loads for some well-known callback properties.
1041 // The method will only return true for absolute truths based on the 1034 // The method will only return true for absolute truths based on the
1042 // receiver maps. 1035 // receiver maps.
1043 int object_offset; 1036 int object_offset;
1044 if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), 1037 if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
1045 &object_offset)) { 1038 &object_offset)) {
1046 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); 1039 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
1047 return SimpleFieldLoad(index); 1040 return SimpleFieldLoad(index);
1048 } 1041 }
1049 if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), 1042 if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(),
1050 &object_offset)) { 1043 &object_offset)) {
1051 TRACE_HANDLER_STATS(isolate(), LoadIC_ArrayBufferViewLoadFieldStub); 1044 TRACE_HANDLER_STATS(isolate(), LoadIC_ArrayBufferViewLoadFieldStub);
1052 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); 1045 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
1053 ArrayBufferViewLoadFieldStub stub(isolate(), index); 1046 ArrayBufferViewLoadFieldStub stub(isolate(), index);
1054 return stub.GetCode(); 1047 return stub.GetCode();
1055 } 1048 }
1056 1049
1057 if (IsCompatibleReceiver(lookup, map)) { 1050 if (IsCompatibleReceiver(lookup, map)) {
1058 Handle<Object> accessors = lookup->GetAccessors(); 1051 Handle<Object> accessors = lookup->GetAccessors();
1059 if (accessors->IsAccessorPair()) { 1052 if (accessors->IsAccessorPair()) {
1060 if (!holder->HasFastProperties()) break; 1053 if (!holder->HasFastProperties()) {
1054 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1055 return slow_stub();
1056 }
1061 // When debugging we need to go the slow path to flood the accessor. 1057 // When debugging we need to go the slow path to flood the accessor.
1062 if (GetSharedFunctionInfo()->HasDebugInfo()) break; 1058 if (GetSharedFunctionInfo()->HasDebugInfo()) {
1063 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 1059 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1064 isolate()); 1060 return slow_stub();
1065 CallOptimization call_optimization(getter);
1066 NamedLoadHandlerCompiler compiler(isolate(), map, holder,
1067 cache_holder);
1068 if (call_optimization.is_simple_api_call()) {
1069 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
1070 int index = lookup->GetAccessorIndex();
1071 return compiler.CompileLoadCallback(lookup->name(),
1072 call_optimization, index);
1073 } 1061 }
1074 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter); 1062 break; // Custom-compiled handler.
1075 int expected_arguments = Handle<JSFunction>::cast(getter)
1076 ->shared()
1077 ->internal_formal_parameter_count();
1078 return compiler.CompileLoadViaGetter(
1079 lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
1080 } else if (accessors->IsAccessorInfo()) { 1063 } else if (accessors->IsAccessorInfo()) {
1081 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 1064 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
1082 if (v8::ToCData<Address>(info->getter()) == nullptr) break; 1065 if (v8::ToCData<Address>(info->getter()) == nullptr) {
1083 if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) { 1066 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1084 // This case should be already handled in LoadIC::UpdateCaches. 1067 return slow_stub();
1085 UNREACHABLE();
1086 break;
1087 } 1068 }
1088 if (!holder->HasFastProperties()) break; 1069 // Ruled out by IsCompatibleReceiver() above.
1070 DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map));
1071 if (!holder->HasFastProperties()) return slow_stub();
1089 if (receiver_is_holder) { 1072 if (receiver_is_holder) {
1090 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub); 1073 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub);
1091 int index = lookup->GetAccessorIndex(); 1074 int index = lookup->GetAccessorIndex();
1092 LoadApiGetterStub stub(isolate(), true, index); 1075 LoadApiGetterStub stub(isolate(), true, index);
1093 return stub.GetCode(); 1076 return stub.GetCode();
1094 } 1077 }
1095 if (info->is_sloppy() && !receiver->IsJSReceiver()) break; 1078 if (info->is_sloppy() && !receiver->IsJSReceiver()) {
1096 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback); 1079 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1097 NamedLoadHandlerCompiler compiler(isolate(), map, holder, 1080 return slow_stub();
1098 cache_holder); 1081 }
1099 return compiler.CompileLoadCallback(lookup->name(), info); 1082 break; // Custom-compiled handler.
1100 } 1083 }
1101 } 1084 }
1102 break; 1085 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1086 return slow_stub();
1103 } 1087 }
1104 1088
1105 case LookupIterator::DATA: { 1089 case LookupIterator::DATA: {
1106 if (lookup->is_dictionary_holder()) { 1090 if (lookup->is_dictionary_holder()) {
1107 if (kind() != Code::LOAD_IC) break; 1091 if (kind() != Code::LOAD_IC) {
1092 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1093 return slow_stub();
1094 }
1108 if (holder->IsJSGlobalObject()) { 1095 if (holder->IsJSGlobalObject()) {
1109 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); 1096 break; // Custom-compiled handler.
1110 NamedLoadHandlerCompiler compiler(isolate(), map, holder,
1111 cache_holder);
1112 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1113 Handle<Code> code = compiler.CompileLoadGlobal(
1114 cell, lookup->name(), lookup->IsConfigurable());
1115 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1116 CacheHolderFlag flag;
1117 Handle<Map> stub_holder_map =
1118 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag);
1119 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
1120 return code;
1121 } 1097 }
1122 // There is only one shared stub for loading normalized 1098 // There is only one shared stub for loading normalized
1123 // properties. It does not traverse the prototype chain, so the 1099 // properties. It does not traverse the prototype chain, so the
1124 // property must be found in the object for the stub to be 1100 // property must be found in the object for the stub to be
1125 // applicable. 1101 // applicable.
1126 if (!receiver_is_holder) break; 1102 if (!receiver_is_holder) {
1103 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1104 return slow_stub();
1105 }
1127 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); 1106 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal);
1128 return isolate()->builtins()->LoadIC_Normal(); 1107 return isolate()->builtins()->LoadIC_Normal();
1129 } 1108 }
1130 1109
1131 // -------------- Fields -------------- 1110 // -------------- Fields --------------
1132 if (lookup->property_details().type() == DATA) { 1111 if (lookup->property_details().type() == DATA) {
1133 FieldIndex field = lookup->GetFieldIndex(); 1112 FieldIndex field = lookup->GetFieldIndex();
1134 if (receiver_is_holder) { 1113 if (receiver_is_holder) {
1135 return SimpleFieldLoad(field); 1114 return SimpleFieldLoad(field);
1136 } 1115 }
1137 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField); 1116 break; // Custom-compiled handler.
1138 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1139 return compiler.CompileLoadField(lookup->name(), field);
1140 } 1117 }
1141 1118
1142 // -------------- Constant properties -------------- 1119 // -------------- Constant properties --------------
1143 DCHECK(lookup->property_details().type() == DATA_CONSTANT); 1120 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1144 if (receiver_is_holder) { 1121 if (receiver_is_holder) {
1145 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); 1122 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub);
1146 LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); 1123 LoadConstantStub stub(isolate(), lookup->GetConstantIndex());
1147 return stub.GetCode(); 1124 return stub.GetCode();
1148 } 1125 }
1126 break; // Custom-compiled handler.
1127 }
1128
1129 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1130 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1131 return slow_stub();
1132 case LookupIterator::ACCESS_CHECK:
1133 case LookupIterator::JSPROXY:
1134 case LookupIterator::NOT_FOUND:
1135 case LookupIterator::TRANSITION:
1136 UNREACHABLE();
1137 }
1138
1139 return Handle<Code>::null();
1140 }
1141
1142 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
1143 Handle<Object> unused,
1144 CacheHolderFlag cache_holder) {
1145 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1146 #ifdef DEBUG
1147 // Only used by DCHECKs below.
1148 Handle<Object> receiver = lookup->GetReceiver();
1149 bool receiver_is_holder = receiver.is_identical_to(holder);
1150 #endif
1151 // Non-map-specific handler stubs have already been selected.
1152 DCHECK(!receiver->IsString() ||
1153 !Name::Equals(isolate()->factory()->length_string(), lookup->name()));
1154 DCHECK(!receiver->IsStringWrapper() ||
1155 !Name::Equals(isolate()->factory()->length_string(), lookup->name()));
1156
1157 DCHECK(!(
1158 receiver->IsJSFunction() &&
1159 Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) &&
1160 receiver->IsConstructor() &&
1161 !Handle<JSFunction>::cast(receiver)
1162 ->map()
1163 ->has_non_instance_prototype()));
1164
1165 Handle<Map> map = receiver_map();
1166 switch (lookup->state()) {
1167 case LookupIterator::INTERCEPTOR: {
1168 DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined());
1169 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor);
1170 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1171 // Perform a lookup behind the interceptor. Copy the LookupIterator since
1172 // the original iterator will be used to fetch the value.
1173 LookupIterator it = *lookup;
1174 it.Next();
1175 LookupForRead(&it);
1176 return compiler.CompileLoadInterceptor(&it);
1177 }
1178
1179 case LookupIterator::ACCESSOR: {
1180 #ifdef DEBUG
1181 int object_offset;
1182 DCHECK(!Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
1183 &object_offset));
1184 DCHECK(!Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(),
1185 &object_offset));
1186 #endif
1187
1188 DCHECK(IsCompatibleReceiver(lookup, map));
1189 Handle<Object> accessors = lookup->GetAccessors();
1190 if (accessors->IsAccessorPair()) {
1191 DCHECK(holder->HasFastProperties());
1192 DCHECK(!GetSharedFunctionInfo()->HasDebugInfo());
1193 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
1194 isolate());
1195 CallOptimization call_optimization(getter);
1196 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1197 if (call_optimization.is_simple_api_call()) {
1198 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
1199 int index = lookup->GetAccessorIndex();
1200 return compiler.CompileLoadCallback(lookup->name(), call_optimization,
1201 index);
1202 }
1203 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter);
1204 int expected_arguments = Handle<JSFunction>::cast(getter)
1205 ->shared()
1206 ->internal_formal_parameter_count();
1207 return compiler.CompileLoadViaGetter(
1208 lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
1209 } else {
1210 DCHECK(accessors->IsAccessorInfo());
1211 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
1212 DCHECK(v8::ToCData<Address>(info->getter()) != nullptr);
1213 DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map));
1214 DCHECK(holder->HasFastProperties());
1215 DCHECK(!receiver_is_holder);
1216 DCHECK(!info->is_sloppy() || receiver->IsJSReceiver());
1217 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
1218 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1219 return compiler.CompileLoadCallback(lookup->name(), info);
1220 }
1221 UNREACHABLE();
1222 }
1223
1224 case LookupIterator::DATA: {
1225 if (lookup->is_dictionary_holder()) {
1226 DCHECK(kind() == Code::LOAD_IC);
1227 DCHECK(holder->IsJSGlobalObject());
1228 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal);
1229 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1230 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1231 Handle<Code> code = compiler.CompileLoadGlobal(
1232 cell, lookup->name(), lookup->IsConfigurable());
1233 return code;
1234 }
1235
1236 // -------------- Fields --------------
1237 if (lookup->property_details().type() == DATA) {
1238 FieldIndex field = lookup->GetFieldIndex();
1239 DCHECK(!receiver_is_holder);
1240 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField);
1241 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1242 return compiler.CompileLoadField(lookup->name(), field);
1243 }
1244
1245 // -------------- Constant properties --------------
1246 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1247 DCHECK(!receiver_is_holder);
1149 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant); 1248 TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant);
1150 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); 1249 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
1151 return compiler.CompileLoadConstant(lookup->name(), 1250 return compiler.CompileLoadConstant(lookup->name(),
1152 lookup->GetConstantIndex()); 1251 lookup->GetConstantIndex());
1153 } 1252 }
1154 1253
1155 case LookupIterator::INTEGER_INDEXED_EXOTIC: 1254 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1156 break;
1157 case LookupIterator::ACCESS_CHECK: 1255 case LookupIterator::ACCESS_CHECK:
1158 case LookupIterator::JSPROXY: 1256 case LookupIterator::JSPROXY:
1159 case LookupIterator::NOT_FOUND: 1257 case LookupIterator::NOT_FOUND:
1160 case LookupIterator::TRANSITION: 1258 case LookupIterator::TRANSITION:
1161 UNREACHABLE(); 1259 UNREACHABLE();
1162 } 1260 }
1163 1261 UNREACHABLE();
1164 TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
1165 return slow_stub(); 1262 return slow_stub();
1166 } 1263 }
1167 1264
1168 1265
1169 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { 1266 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
1170 // This helper implements a few common fast cases for converting 1267 // This helper implements a few common fast cases for converting
1171 // non-smi keys of keyed loads/stores to a smi or a string. 1268 // non-smi keys of keyed loads/stores to a smi or a string.
1172 if (key->IsHeapNumber()) { 1269 if (key->IsHeapNumber()) {
1173 double value = Handle<HeapNumber>::cast(key)->value(); 1270 double value = Handle<HeapNumber>::cast(key)->value();
1174 if (std::isnan(value)) { 1271 if (std::isnan(value)) {
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 constant_type = Just(cell->GetConstantType()); 1603 constant_type = Just(cell->GetConstantType());
1507 } 1604 }
1508 StoreGlobalStub stub(isolate, type, constant_type, 1605 StoreGlobalStub stub(isolate, type, constant_type,
1509 receiver->IsJSGlobalProxy()); 1606 receiver->IsJSGlobalProxy());
1510 auto code = stub.GetCodeCopyFromTemplate(holder, cell); 1607 auto code = stub.GetCodeCopyFromTemplate(holder, cell);
1511 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1608 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1512 HeapObject::UpdateMapCodeCache(receiver, name, code); 1609 HeapObject::UpdateMapCodeCache(receiver, name, code);
1513 return code; 1610 return code;
1514 } 1611 }
1515 1612
1516 1613 Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
1517 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
1518 Handle<Object> value,
1519 CacheHolderFlag cache_holder) {
1520 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); 1614 DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
1521 1615
1522 // This is currently guaranteed by checks in StoreIC::Store. 1616 // This is currently guaranteed by checks in StoreIC::Store.
1523 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); 1617 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
1524 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1618 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1525 DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate()); 1619 DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
1526 1620
1527 switch (lookup->state()) { 1621 switch (lookup->state()) {
1528 case LookupIterator::TRANSITION: { 1622 case LookupIterator::TRANSITION: {
1529 auto store_target = lookup->GetStoreTarget(); 1623 auto store_target = lookup->GetStoreTarget();
1530 if (store_target->IsJSGlobalObject()) { 1624 if (store_target->IsJSGlobalObject()) {
1531 // TODO(dcarney): this currently just deopts. Use the transition cell. 1625 break; // Custom-compiled handler.
1532 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition);
1533 auto cell = isolate()->factory()->NewPropertyCell();
1534 cell->set_value(*value);
1535 auto code = PropertyCellStoreHandler(
1536 isolate(), store_target, Handle<JSGlobalObject>::cast(store_target),
1537 lookup->name(), cell, PropertyCellType::kConstant);
1538 cell->set_value(isolate()->heap()->the_hole_value());
1539 return code;
1540 } 1626 }
1541 Handle<Map> transition = lookup->transition_map();
1542 // Currently not handled by CompileStoreTransition. 1627 // Currently not handled by CompileStoreTransition.
1543 if (!holder->HasFastProperties()) { 1628 if (!holder->HasFastProperties()) {
1544 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); 1629 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow");
1545 break; 1630 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1631 return slow_stub();
1546 } 1632 }
1547 1633
1548 DCHECK(lookup->IsCacheableTransition()); 1634 DCHECK(lookup->IsCacheableTransition());
1549 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition); 1635 break; // Custom-compiled handler.
1550 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1551 return compiler.CompileStoreTransition(transition, lookup->name());
1552 } 1636 }
1553 1637
1554 case LookupIterator::INTERCEPTOR: { 1638 case LookupIterator::INTERCEPTOR: {
1555 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); 1639 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined());
1556 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); 1640 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
1557 StoreInterceptorStub stub(isolate()); 1641 StoreInterceptorStub stub(isolate());
1558 return stub.GetCode(); 1642 return stub.GetCode();
1559 } 1643 }
1560 1644
1561 case LookupIterator::ACCESSOR: { 1645 case LookupIterator::ACCESSOR: {
1562 if (!holder->HasFastProperties()) { 1646 if (!holder->HasFastProperties()) {
1563 TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map"); 1647 TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map");
1564 break; 1648 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1649 return slow_stub();
1565 } 1650 }
1566 Handle<Object> accessors = lookup->GetAccessors(); 1651 Handle<Object> accessors = lookup->GetAccessors();
1567 if (accessors->IsAccessorInfo()) { 1652 if (accessors->IsAccessorInfo()) {
1568 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 1653 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
1569 if (v8::ToCData<Address>(info->setter()) == 0) { 1654 if (v8::ToCData<Address>(info->setter()) == nullptr) {
1570 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); 1655 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == nullptr");
1571 break; 1656 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1657 return slow_stub();
1572 } 1658 }
1573 if (AccessorInfo::cast(*accessors)->is_special_data_property() && 1659 if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
1574 !lookup->HolderIsReceiverOrHiddenPrototype()) { 1660 !lookup->HolderIsReceiverOrHiddenPrototype()) {
1575 TRACE_GENERIC_IC(isolate(), "StoreIC", 1661 TRACE_GENERIC_IC(isolate(), "StoreIC",
1576 "special data property in prototype chain"); 1662 "special data property in prototype chain");
1577 break; 1663 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1664 return slow_stub();
1578 } 1665 }
1579 if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, 1666 if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info,
1580 receiver_map())) { 1667 receiver_map())) {
1581 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); 1668 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type");
1582 break; 1669 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1670 return slow_stub();
1583 } 1671 }
1584 if (info->is_sloppy() && !receiver->IsJSReceiver()) break; 1672 if (info->is_sloppy() && !receiver->IsJSReceiver()) {
1585 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); 1673 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1586 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); 1674 return slow_stub();
1587 return compiler.CompileStoreCallback(receiver, lookup->name(), info, 1675 }
1588 language_mode()); 1676 break; // Custom-compiled handler.
1589 } else if (accessors->IsAccessorPair()) { 1677 } else if (accessors->IsAccessorPair()) {
1590 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), 1678 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
1591 isolate()); 1679 isolate());
1592 if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) { 1680 if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) {
1593 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function"); 1681 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function");
1594 break; 1682 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1683 return slow_stub();
1595 } 1684 }
1596 CallOptimization call_optimization(setter); 1685 CallOptimization call_optimization(setter);
1597 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1598 if (call_optimization.is_simple_api_call()) { 1686 if (call_optimization.is_simple_api_call()) {
1599 if (call_optimization.IsCompatibleReceiver(receiver, holder)) { 1687 if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
1600 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); 1688 break; // Custom-compiled handler.
1601 return compiler.CompileStoreCallback(receiver, lookup->name(),
1602 call_optimization,
1603 lookup->GetAccessorIndex());
1604 } 1689 }
1605 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver"); 1690 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver");
1606 break; 1691 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1692 return slow_stub();
1607 } 1693 }
1608 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter); 1694 break; // Custom-compiled handler.
1609 int expected_arguments = JSFunction::cast(*setter)
1610 ->shared()
1611 ->internal_formal_parameter_count();
1612 return compiler.CompileStoreViaSetter(receiver, lookup->name(),
1613 lookup->GetAccessorIndex(),
1614 expected_arguments);
1615 } 1695 }
1616 break; 1696 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1697 return slow_stub();
1617 } 1698 }
1618 1699
1619 case LookupIterator::DATA: { 1700 case LookupIterator::DATA: {
1620 if (lookup->is_dictionary_holder()) { 1701 if (lookup->is_dictionary_holder()) {
1621 if (holder->IsJSGlobalObject()) { 1702 if (holder->IsJSGlobalObject()) {
1622 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal); 1703 break; // Custom-compiled handler.
1623 DCHECK(holder.is_identical_to(receiver) ||
1624 receiver->map()->prototype() == *holder);
1625 auto cell = lookup->GetPropertyCell();
1626 auto updated_type = PropertyCell::UpdatedType(
1627 cell, value, lookup->property_details());
1628 auto code = PropertyCellStoreHandler(
1629 isolate(), receiver, Handle<JSGlobalObject>::cast(holder),
1630 lookup->name(), cell, updated_type);
1631 return code;
1632 } 1704 }
1633 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); 1705 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal);
1634 DCHECK(holder.is_identical_to(receiver)); 1706 DCHECK(holder.is_identical_to(receiver));
1635 return isolate()->builtins()->StoreIC_Normal(); 1707 return isolate()->builtins()->StoreIC_Normal();
1636 } 1708 }
1637 1709
1638 // -------------- Fields -------------- 1710 // -------------- Fields --------------
1639 if (lookup->property_details().type() == DATA) { 1711 if (lookup->property_details().type() == DATA) {
1640 bool use_stub = true; 1712 bool use_stub = true;
1641 if (lookup->representation().IsHeapObject()) { 1713 if (lookup->representation().IsHeapObject()) {
1642 // Only use a generic stub if no types need to be tracked. 1714 // Only use a generic stub if no types need to be tracked.
1643 Handle<FieldType> field_type = lookup->GetFieldType(); 1715 Handle<FieldType> field_type = lookup->GetFieldType();
1644 use_stub = !field_type->IsClass(); 1716 use_stub = !field_type->IsClass();
1645 } 1717 }
1646 if (use_stub) { 1718 if (use_stub) {
1647 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); 1719 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub);
1648 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 1720 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
1649 lookup->representation()); 1721 lookup->representation());
1650 return stub.GetCode(); 1722 return stub.GetCode();
1651 } 1723 }
1724 break; // Custom-compiled handler.
1725 }
1726
1727 // -------------- Constant properties --------------
1728 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1729 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property");
1730 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
1731 return slow_stub();
1732 }
1733
1734 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1735 case LookupIterator::ACCESS_CHECK:
1736 case LookupIterator::JSPROXY:
1737 case LookupIterator::NOT_FOUND:
1738 UNREACHABLE();
1739 }
1740 return Handle<Code>::null();
1741 }
1742
1743 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
1744 Handle<Object> value,
1745 CacheHolderFlag cache_holder) {
1746 DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
1747
1748 // This is currently guaranteed by checks in StoreIC::Store.
1749 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
1750 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1751 DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
1752
1753 switch (lookup->state()) {
1754 case LookupIterator::TRANSITION: {
1755 auto store_target = lookup->GetStoreTarget();
1756 if (store_target->IsJSGlobalObject()) {
1757 // TODO(dcarney): this currently just deopts. Use the transition cell.
1758 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition);
1759 auto cell = isolate()->factory()->NewPropertyCell();
1760 cell->set_value(*value);
1761 auto code = PropertyCellStoreHandler(
1762 isolate(), store_target, Handle<JSGlobalObject>::cast(store_target),
1763 lookup->name(), cell, PropertyCellType::kConstant);
1764 cell->set_value(isolate()->heap()->the_hole_value());
1765 return code;
1766 }
1767 Handle<Map> transition = lookup->transition_map();
1768 // Currently not handled by CompileStoreTransition.
1769 DCHECK(holder->HasFastProperties());
1770
1771 DCHECK(lookup->IsCacheableTransition());
1772 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition);
1773 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1774 return compiler.CompileStoreTransition(transition, lookup->name());
1775 }
1776
1777 case LookupIterator::INTERCEPTOR:
1778 UNREACHABLE();
1779
1780 case LookupIterator::ACCESSOR: {
1781 DCHECK(holder->HasFastProperties());
1782 Handle<Object> accessors = lookup->GetAccessors();
1783 if (accessors->IsAccessorInfo()) {
1784 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
1785 DCHECK(v8::ToCData<Address>(info->setter()) != 0);
1786 DCHECK(!AccessorInfo::cast(*accessors)->is_special_data_property() ||
1787 lookup->HolderIsReceiverOrHiddenPrototype());
1788 DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info,
1789 receiver_map()));
1790 DCHECK(!info->is_sloppy() || receiver->IsJSReceiver());
1791 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
1792 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1793 return compiler.CompileStoreCallback(receiver, lookup->name(), info,
1794 language_mode());
1795 } else {
1796 DCHECK(accessors->IsAccessorPair());
1797 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
1798 isolate());
1799 DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo());
1800 CallOptimization call_optimization(setter);
1801 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1802 if (call_optimization.is_simple_api_call()) {
1803 DCHECK(call_optimization.IsCompatibleReceiver(receiver, holder));
1804 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
1805 return compiler.CompileStoreCallback(receiver, lookup->name(),
1806 call_optimization,
1807 lookup->GetAccessorIndex());
1808 }
1809 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter);
1810 int expected_arguments = JSFunction::cast(*setter)
1811 ->shared()
1812 ->internal_formal_parameter_count();
1813 return compiler.CompileStoreViaSetter(receiver, lookup->name(),
1814 lookup->GetAccessorIndex(),
1815 expected_arguments);
1816 }
1817 }
1818
1819 case LookupIterator::DATA: {
1820 if (lookup->is_dictionary_holder()) {
1821 DCHECK(holder->IsJSGlobalObject());
1822 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal);
1823 DCHECK(holder.is_identical_to(receiver) ||
1824 receiver->map()->prototype() == *holder);
1825 auto cell = lookup->GetPropertyCell();
1826 auto updated_type =
1827 PropertyCell::UpdatedType(cell, value, lookup->property_details());
1828 auto code = PropertyCellStoreHandler(
1829 isolate(), receiver, Handle<JSGlobalObject>::cast(holder),
1830 lookup->name(), cell, updated_type);
1831 return code;
1832 }
1833
1834 // -------------- Fields --------------
1835 if (lookup->property_details().type() == DATA) {
1836 #ifdef DEBUG
1837 bool use_stub = true;
1838 if (lookup->representation().IsHeapObject()) {
1839 // Only use a generic stub if no types need to be tracked.
1840 Handle<FieldType> field_type = lookup->GetFieldType();
1841 use_stub = !field_type->IsClass();
1842 }
1843 DCHECK(!use_stub);
1844 #endif
1652 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); 1845 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField);
1653 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); 1846 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
1654 return compiler.CompileStoreField(lookup); 1847 return compiler.CompileStoreField(lookup);
1655 } 1848 }
1656 1849
1657 // -------------- Constant properties -------------- 1850 // -------------- Constant properties --------------
1658 DCHECK(lookup->property_details().type() == DATA_CONSTANT); 1851 DCHECK(lookup->property_details().type() == DATA_CONSTANT);
1659 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); 1852 UNREACHABLE();
1660 break;
1661 } 1853 }
1662 1854
1663 case LookupIterator::INTEGER_INDEXED_EXOTIC: 1855 case LookupIterator::INTEGER_INDEXED_EXOTIC:
1664 case LookupIterator::ACCESS_CHECK: 1856 case LookupIterator::ACCESS_CHECK:
1665 case LookupIterator::JSPROXY: 1857 case LookupIterator::JSPROXY:
1666 case LookupIterator::NOT_FOUND: 1858 case LookupIterator::NOT_FOUND:
1667 UNREACHABLE(); 1859 UNREACHABLE();
1668 } 1860 }
1669 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); 1861 UNREACHABLE();
1670 return slow_stub(); 1862 return slow_stub();
1671 } 1863 }
1672 1864
1673 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, 1865 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
1674 KeyedAccessStoreMode store_mode) { 1866 KeyedAccessStoreMode store_mode) {
1675 MapHandleList target_receiver_maps; 1867 MapHandleList target_receiver_maps;
1676 TargetMaps(&target_receiver_maps); 1868 TargetMaps(&target_receiver_maps);
1677 if (target_receiver_maps.length() == 0) { 1869 if (target_receiver_maps.length() == 0) {
1678 Handle<Map> monomorphic_map = 1870 Handle<Map> monomorphic_map =
1679 ComputeTransitionedMap(receiver_map, store_mode); 1871 ComputeTransitionedMap(receiver_map, store_mode);
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2794 KeyedLoadICNexus nexus(vector, vector_slot); 2986 KeyedLoadICNexus nexus(vector, vector_slot);
2795 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 2987 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2796 ic.UpdateState(receiver, key); 2988 ic.UpdateState(receiver, key);
2797 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2989 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2798 } 2990 }
2799 2991
2800 return *result; 2992 return *result;
2801 } 2993 }
2802 } // namespace internal 2994 } // namespace internal
2803 } // namespace v8 2995 } // 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