| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 // If there's no appropriate stub we simply avoid updating the caches. | 776 // If there's no appropriate stub we simply avoid updating the caches. |
| 777 // TODO(verwaest): Install a slow fallback in this case to avoid not learning, | 777 // TODO(verwaest): Install a slow fallback in this case to avoid not learning, |
| 778 // and deopting Crankshaft code. | 778 // and deopting Crankshaft code. |
| 779 if (code.is_null()) return; | 779 if (code.is_null()) return; |
| 780 | 780 |
| 781 Handle<JSObject> cache_object = object->IsJSObject() | 781 Handle<JSObject> cache_object = object->IsJSObject() |
| 782 ? Handle<JSObject>::cast(object) | 782 ? Handle<JSObject>::cast(object) |
| 783 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), | 783 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), |
| 784 isolate()); | 784 isolate()); |
| 785 | 785 |
| 786 PatchCache(handle(Type::CurrentOf(cache_object), isolate()), name, code); | 786 PatchCache(CurrentTypeOf(cache_object, isolate()), name, code); |
| 787 TRACE_IC("CallIC", name); | 787 TRACE_IC("CallIC", name); |
| 788 } | 788 } |
| 789 | 789 |
| 790 | 790 |
| 791 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, | 791 MaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, |
| 792 Handle<Object> key) { | 792 Handle<Object> key) { |
| 793 if (key->IsInternalizedString()) { | 793 if (key->IsInternalizedString()) { |
| 794 return CallICBase::LoadFunction(object, Handle<String>::cast(key)); | 794 return CallICBase::LoadFunction(object, Handle<String>::cast(key)); |
| 795 } | 795 } |
| 796 | 796 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 number_of_valid_types = number_of_types; | 982 number_of_valid_types = number_of_types; |
| 983 | 983 |
| 984 for (int i = 0; i < number_of_types; i++) { | 984 for (int i = 0; i < number_of_types; i++) { |
| 985 Handle<Type> current_type = types.at(i); | 985 Handle<Type> current_type = types.at(i); |
| 986 // Filter out deprecated maps to ensure their instances get migrated. | 986 // Filter out deprecated maps to ensure their instances get migrated. |
| 987 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { | 987 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { |
| 988 number_of_valid_types--; | 988 number_of_valid_types--; |
| 989 // If the receiver type is already in the polymorphic IC, this indicates | 989 // If the receiver type is already in the polymorphic IC, this indicates |
| 990 // there was a prototoype chain failure. In that case, just overwrite the | 990 // there was a prototoype chain failure. In that case, just overwrite the |
| 991 // handler. | 991 // handler. |
| 992 } else if (type->Is(current_type)) { | 992 } else if (type->IsCurrently(current_type)) { |
| 993 ASSERT(handler_to_overwrite == -1); | 993 ASSERT(handler_to_overwrite == -1); |
| 994 number_of_valid_types--; | 994 number_of_valid_types--; |
| 995 handler_to_overwrite = i; | 995 handler_to_overwrite = i; |
| 996 } | 996 } |
| 997 } | 997 } |
| 998 | 998 |
| 999 if (number_of_valid_types >= 4) return false; | 999 if (number_of_valid_types >= 4) return false; |
| 1000 if (number_of_types == 0) return false; | 1000 if (number_of_types == 0) return false; |
| 1001 if (!target()->FindHandlers(&handlers, types.length())) return false; | 1001 if (!target()->FindHandlers(&handlers, types.length())) return false; |
| 1002 | 1002 |
| 1003 number_of_valid_types++; | 1003 number_of_valid_types++; |
| 1004 if (handler_to_overwrite >= 0) { | 1004 if (handler_to_overwrite >= 0) { |
| 1005 handlers.Set(handler_to_overwrite, code); | 1005 handlers.Set(handler_to_overwrite, code); |
| 1006 } else { | 1006 } else { |
| 1007 types.Add(type); | 1007 types.Add(type); |
| 1008 handlers.Add(code); | 1008 handlers.Add(code); |
| 1009 } | 1009 } |
| 1010 | 1010 |
| 1011 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1011 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
| 1012 &types, &handlers, number_of_valid_types, name, strict_mode()); | 1012 &types, &handlers, number_of_valid_types, name, strict_mode()); |
| 1013 set_target(*ic); | 1013 set_target(*ic); |
| 1014 return true; | 1014 return true; |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 | 1017 |
| 1018 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
| 1019 Type* type = object->IsJSGlobalObject() |
| 1020 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) |
| 1021 : Type::OfCurrently(object); |
| 1022 return handle(type, isolate); |
| 1023 } |
| 1024 |
| 1025 |
| 1018 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { | 1026 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { |
| 1019 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); | 1027 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); |
| 1020 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); | 1028 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); |
| 1029 if (type->IsConstant()) { |
| 1030 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); |
| 1031 } |
| 1021 ASSERT(type->IsClass()); | 1032 ASSERT(type->IsClass()); |
| 1022 return type->AsClass(); | 1033 return type->AsClass(); |
| 1023 } | 1034 } |
| 1024 | 1035 |
| 1025 | 1036 |
| 1026 Type* IC::MapToType(Handle<Map> map) { | 1037 Type* IC::MapToType(Handle<Map> map) { |
| 1027 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); | 1038 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); |
| 1028 // The only oddballs that can be recorded in ICs are booleans. | 1039 // The only oddballs that can be recorded in ICs are booleans. |
| 1029 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); | 1040 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); |
| 1030 return Type::Class(map); | 1041 return Type::Class(map); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 Handle<String> name) { | 1138 Handle<String> name) { |
| 1128 if (state() == UNINITIALIZED) { | 1139 if (state() == UNINITIALIZED) { |
| 1129 // This is the first time we execute this inline cache. | 1140 // This is the first time we execute this inline cache. |
| 1130 // Set the target to the pre monomorphic stub to delay | 1141 // Set the target to the pre monomorphic stub to delay |
| 1131 // setting the monomorphic state. | 1142 // setting the monomorphic state. |
| 1132 set_target(*pre_monomorphic_stub()); | 1143 set_target(*pre_monomorphic_stub()); |
| 1133 TRACE_IC("LoadIC", name); | 1144 TRACE_IC("LoadIC", name); |
| 1134 return; | 1145 return; |
| 1135 } | 1146 } |
| 1136 | 1147 |
| 1148 Handle<Type> type = CurrentTypeOf(object, isolate()); |
| 1137 Handle<Code> code; | 1149 Handle<Code> code; |
| 1138 if (!lookup->IsCacheable()) { | 1150 if (!lookup->IsCacheable()) { |
| 1139 // Bail out if the result is not cacheable. | 1151 // Bail out if the result is not cacheable. |
| 1140 code = slow_stub(); | 1152 code = slow_stub(); |
| 1141 } else if (!lookup->IsProperty()) { | 1153 } else if (!lookup->IsProperty()) { |
| 1142 if (kind() == Code::LOAD_IC) { | 1154 if (kind() == Code::LOAD_IC) { |
| 1143 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, object); | 1155 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); |
| 1144 } else { | 1156 } else { |
| 1145 code = slow_stub(); | 1157 code = slow_stub(); |
| 1146 } | 1158 } |
| 1147 } else { | 1159 } else { |
| 1148 code = ComputeHandler(lookup, object, name); | 1160 code = ComputeHandler(lookup, object, name); |
| 1149 } | 1161 } |
| 1150 | 1162 |
| 1151 PatchCache(handle(Type::CurrentOf(object), isolate()), name, code); | 1163 PatchCache(type, name, code); |
| 1152 TRACE_IC("LoadIC", name); | 1164 TRACE_IC("LoadIC", name); |
| 1153 } | 1165 } |
| 1154 | 1166 |
| 1155 | 1167 |
| 1156 void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { | 1168 void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { |
| 1157 // Cache code holding map should be consistent with | 1169 // Cache code holding map should be consistent with |
| 1158 // GenerateMonomorphicCacheProbe. | 1170 // GenerateMonomorphicCacheProbe. |
| 1159 Map* map = *TypeToMap(type, isolate()); | 1171 Map* map = *TypeToMap(type, isolate()); |
| 1160 isolate()->stub_cache()->Set(name, map, code); | 1172 isolate()->stub_cache()->Set(name, map, code); |
| 1161 } | 1173 } |
| 1162 | 1174 |
| 1163 | 1175 |
| 1164 Handle<Code> IC::ComputeHandler(LookupResult* lookup, | 1176 Handle<Code> IC::ComputeHandler(LookupResult* lookup, |
| 1165 Handle<Object> object, | 1177 Handle<Object> object, |
| 1166 Handle<String> name, | 1178 Handle<String> name, |
| 1167 Handle<Object> value) { | 1179 Handle<Object> value) { |
| 1168 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); | 1180 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); |
| 1169 Handle<HeapObject> stub_holder(GetCodeCacheHolder( | 1181 Handle<HeapObject> stub_holder(GetCodeCacheHolder( |
| 1170 isolate(), *object, cache_holder)); | 1182 isolate(), *object, cache_holder)); |
| 1171 | 1183 |
| 1172 Handle<Code> code = isolate()->stub_cache()->FindHandler( | 1184 Handle<Code> code = isolate()->stub_cache()->FindHandler( |
| 1173 name, stub_holder, kind(), cache_holder, strict_mode()); | 1185 name, handle(stub_holder->map()), kind(), cache_holder, strict_mode()); |
| 1174 if (!code.is_null()) return code; | 1186 if (!code.is_null()) return code; |
| 1175 | 1187 |
| 1176 code = CompileHandler(lookup, object, name, value, cache_holder); | 1188 code = CompileHandler(lookup, object, name, value, cache_holder); |
| 1177 ASSERT(code->is_handler()); | 1189 ASSERT(code->is_handler()); |
| 1178 | 1190 |
| 1179 if (code->type() != Code::NORMAL) { | 1191 if (code->type() != Code::NORMAL) { |
| 1180 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 1192 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 1181 } | 1193 } |
| 1182 | 1194 |
| 1183 return code; | 1195 return code; |
| 1184 } | 1196 } |
| 1185 | 1197 |
| 1186 | 1198 |
| 1187 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, | 1199 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, |
| 1188 Handle<Object> object, | 1200 Handle<Object> object, |
| 1189 Handle<String> name, | 1201 Handle<String> name, |
| 1190 Handle<Object> unused, | 1202 Handle<Object> unused, |
| 1191 InlineCacheHolderFlag cache_holder) { | 1203 InlineCacheHolderFlag cache_holder) { |
| 1192 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { | 1204 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { |
| 1193 int length_index = String::kLengthOffset / kPointerSize; | 1205 int length_index = String::kLengthOffset / kPointerSize; |
| 1194 return SimpleFieldLoad(length_index); | 1206 return SimpleFieldLoad(length_index); |
| 1195 } | 1207 } |
| 1196 | 1208 |
| 1209 Handle<Type> type = CurrentTypeOf(object, isolate()); |
| 1197 Handle<JSObject> holder(lookup->holder()); | 1210 Handle<JSObject> holder(lookup->holder()); |
| 1198 LoadStubCompiler compiler(isolate(), cache_holder, kind()); | 1211 LoadStubCompiler compiler(isolate(), cache_holder, kind()); |
| 1199 | 1212 |
| 1200 switch (lookup->type()) { | 1213 switch (lookup->type()) { |
| 1201 case FIELD: { | 1214 case FIELD: { |
| 1202 PropertyIndex field = lookup->GetFieldIndex(); | 1215 PropertyIndex field = lookup->GetFieldIndex(); |
| 1203 if (object.is_identical_to(holder)) { | 1216 if (object.is_identical_to(holder)) { |
| 1204 return SimpleFieldLoad(field.translate(holder), | 1217 return SimpleFieldLoad(field.translate(holder), |
| 1205 field.is_inobject(holder), | 1218 field.is_inobject(holder), |
| 1206 lookup->representation()); | 1219 lookup->representation()); |
| 1207 } | 1220 } |
| 1208 return compiler.CompileLoadField( | 1221 return compiler.CompileLoadField( |
| 1209 object, holder, name, field, lookup->representation()); | 1222 type, holder, name, field, lookup->representation()); |
| 1210 } | 1223 } |
| 1211 case CONSTANT: { | 1224 case CONSTANT: { |
| 1212 Handle<Object> constant(lookup->GetConstant(), isolate()); | 1225 Handle<Object> constant(lookup->GetConstant(), isolate()); |
| 1213 // TODO(2803): Don't compute a stub for cons strings because they cannot | 1226 // TODO(2803): Don't compute a stub for cons strings because they cannot |
| 1214 // be embedded into code. | 1227 // be embedded into code. |
| 1215 if (constant->IsConsString()) break; | 1228 if (constant->IsConsString()) break; |
| 1216 return compiler.CompileLoadConstant(object, holder, name, constant); | 1229 return compiler.CompileLoadConstant(type, holder, name, constant); |
| 1217 } | 1230 } |
| 1218 case NORMAL: | 1231 case NORMAL: |
| 1219 if (kind() != Code::LOAD_IC) break; | 1232 if (kind() != Code::LOAD_IC) break; |
| 1220 if (holder->IsGlobalObject()) { | 1233 if (holder->IsGlobalObject()) { |
| 1221 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); | 1234 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); |
| 1222 Handle<PropertyCell> cell( | 1235 Handle<PropertyCell> cell( |
| 1223 global->GetPropertyCell(lookup), isolate()); | 1236 global->GetPropertyCell(lookup), isolate()); |
| 1224 Handle<Code> code = compiler.CompileLoadGlobal( | 1237 Handle<Code> code = compiler.CompileLoadGlobal( |
| 1225 object, global, cell, name, lookup->IsDontDelete()); | 1238 type, global, cell, name, lookup->IsDontDelete()); |
| 1226 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1239 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1227 Handle<HeapObject> stub_holder(GetCodeCacheHolder( | 1240 Handle<HeapObject> stub_holder(GetCodeCacheHolder( |
| 1228 isolate(), *object, cache_holder)); | 1241 isolate(), *object, cache_holder)); |
| 1229 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 1242 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 1230 return code; | 1243 return code; |
| 1231 } | 1244 } |
| 1232 // There is only one shared stub for loading normalized | 1245 // There is only one shared stub for loading normalized |
| 1233 // properties. It does not traverse the prototype chain, so the | 1246 // properties. It does not traverse the prototype chain, so the |
| 1234 // property must be found in the object for the stub to be | 1247 // property must be found in the object for the stub to be |
| 1235 // applicable. | 1248 // applicable. |
| 1236 if (!object.is_identical_to(holder)) break; | 1249 if (!object.is_identical_to(holder)) break; |
| 1237 return isolate()->builtins()->LoadIC_Normal(); | 1250 return isolate()->builtins()->LoadIC_Normal(); |
| 1238 case CALLBACKS: { | 1251 case CALLBACKS: { |
| 1239 // Use simple field loads for some well-known callback properties. | 1252 // Use simple field loads for some well-known callback properties. |
| 1240 if (object->IsJSObject()) { | 1253 if (object->IsJSObject()) { |
| 1241 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1254 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1242 Handle<Map> map(receiver->map()); | 1255 Handle<Map> map(receiver->map()); |
| 1243 int object_offset; | 1256 int object_offset; |
| 1244 if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) { | 1257 if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) { |
| 1245 return SimpleFieldLoad(object_offset / kPointerSize); | 1258 return SimpleFieldLoad(object_offset / kPointerSize); |
| 1246 } | 1259 } |
| 1247 } | 1260 } |
| 1248 | 1261 |
| 1249 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 1262 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
| 1250 if (callback->IsExecutableAccessorInfo()) { | 1263 if (callback->IsExecutableAccessorInfo()) { |
| 1251 Handle<ExecutableAccessorInfo> info = | 1264 Handle<ExecutableAccessorInfo> info = |
| 1252 Handle<ExecutableAccessorInfo>::cast(callback); | 1265 Handle<ExecutableAccessorInfo>::cast(callback); |
| 1253 if (v8::ToCData<Address>(info->getter()) == 0) break; | 1266 if (v8::ToCData<Address>(info->getter()) == 0) break; |
| 1254 if (!info->IsCompatibleReceiver(*object)) break; | 1267 if (!info->IsCompatibleReceiver(*object)) break; |
| 1255 return compiler.CompileLoadCallback(object, holder, name, info); | 1268 return compiler.CompileLoadCallback(type, holder, name, info); |
| 1256 } else if (callback->IsAccessorPair()) { | 1269 } else if (callback->IsAccessorPair()) { |
| 1257 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), | 1270 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), |
| 1258 isolate()); | 1271 isolate()); |
| 1259 if (!getter->IsJSFunction()) break; | 1272 if (!getter->IsJSFunction()) break; |
| 1260 if (holder->IsGlobalObject()) break; | 1273 if (holder->IsGlobalObject()) break; |
| 1261 if (!holder->HasFastProperties()) break; | 1274 if (!holder->HasFastProperties()) break; |
| 1262 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); | 1275 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| 1263 if (!object->IsJSObject() && | 1276 if (!object->IsJSObject() && |
| 1264 !function->IsBuiltin() && | 1277 !function->IsBuiltin() && |
| 1265 function->shared()->is_classic_mode()) { | 1278 function->shared()->is_classic_mode()) { |
| 1266 // Calling non-strict non-builtins with a value as the receiver | 1279 // Calling non-strict non-builtins with a value as the receiver |
| 1267 // requires boxing. | 1280 // requires boxing. |
| 1268 break; | 1281 break; |
| 1269 } | 1282 } |
| 1270 CallOptimization call_optimization(function); | 1283 CallOptimization call_optimization(function); |
| 1271 if (call_optimization.is_simple_api_call() && | 1284 if (call_optimization.is_simple_api_call() && |
| 1272 call_optimization.IsCompatibleReceiver(*object)) { | 1285 call_optimization.IsCompatibleReceiver(*object)) { |
| 1273 return compiler.CompileLoadCallback( | 1286 return compiler.CompileLoadCallback( |
| 1274 object, holder, name, call_optimization); | 1287 type, holder, name, call_optimization); |
| 1275 } | 1288 } |
| 1276 return compiler.CompileLoadViaGetter(object, holder, name, function); | 1289 return compiler.CompileLoadViaGetter(type, holder, name, function); |
| 1277 } | 1290 } |
| 1278 // TODO(dcarney): Handle correctly. | 1291 // TODO(dcarney): Handle correctly. |
| 1279 if (callback->IsDeclaredAccessorInfo()) break; | 1292 if (callback->IsDeclaredAccessorInfo()) break; |
| 1280 ASSERT(callback->IsForeign()); | 1293 ASSERT(callback->IsForeign()); |
| 1281 // No IC support for old-style native accessors. | 1294 // No IC support for old-style native accessors. |
| 1282 break; | 1295 break; |
| 1283 } | 1296 } |
| 1284 case INTERCEPTOR: | 1297 case INTERCEPTOR: |
| 1285 ASSERT(HasInterceptorGetter(*holder)); | 1298 ASSERT(HasInterceptorGetter(*holder)); |
| 1286 return compiler.CompileLoadInterceptor(object, holder, name); | 1299 return compiler.CompileLoadInterceptor(type, holder, name); |
| 1287 default: | 1300 default: |
| 1288 break; | 1301 break; |
| 1289 } | 1302 } |
| 1290 | 1303 |
| 1291 return slow_stub(); | 1304 return slow_stub(); |
| 1292 } | 1305 } |
| 1293 | 1306 |
| 1294 | 1307 |
| 1295 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { | 1308 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { |
| 1296 // This helper implements a few common fast cases for converting | 1309 // This helper implements a few common fast cases for converting |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 Handle<String> name, | 1615 Handle<String> name, |
| 1603 Handle<Object> value) { | 1616 Handle<Object> value) { |
| 1604 ASSERT(!receiver->IsJSGlobalProxy()); | 1617 ASSERT(!receiver->IsJSGlobalProxy()); |
| 1605 ASSERT(lookup->IsFound()); | 1618 ASSERT(lookup->IsFound()); |
| 1606 | 1619 |
| 1607 // These are not cacheable, so we never see such LookupResults here. | 1620 // These are not cacheable, so we never see such LookupResults here. |
| 1608 ASSERT(!lookup->IsHandler()); | 1621 ASSERT(!lookup->IsHandler()); |
| 1609 | 1622 |
| 1610 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); | 1623 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); |
| 1611 | 1624 |
| 1612 PatchCache(handle(Type::CurrentOf(receiver), isolate()), name, code); | 1625 PatchCache(CurrentTypeOf(receiver, isolate()), name, code); |
| 1613 TRACE_IC("StoreIC", name); | 1626 TRACE_IC("StoreIC", name); |
| 1614 } | 1627 } |
| 1615 | 1628 |
| 1616 | 1629 |
| 1617 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, | 1630 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, |
| 1618 Handle<Object> object, | 1631 Handle<Object> object, |
| 1619 Handle<String> name, | 1632 Handle<String> name, |
| 1620 Handle<Object> value, | 1633 Handle<Object> value, |
| 1621 InlineCacheHolderFlag cache_holder) { | 1634 InlineCacheHolderFlag cache_holder) { |
| 1622 ASSERT(cache_holder == OWN_MAP); | 1635 ASSERT(cache_holder == OWN_MAP); |
| (...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 #undef ADDR | 2778 #undef ADDR |
| 2766 }; | 2779 }; |
| 2767 | 2780 |
| 2768 | 2781 |
| 2769 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2782 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2770 return IC_utilities[id]; | 2783 return IC_utilities[id]; |
| 2771 } | 2784 } |
| 2772 | 2785 |
| 2773 | 2786 |
| 2774 } } // namespace v8::internal | 2787 } } // namespace v8::internal |
| OLD | NEW |