| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 127       Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); | 127       Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); | 
| 128 | 128 | 
| 129   Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 129   Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 
| 130                        isolate_); | 130                        isolate_); | 
| 131   if (probe->IsCode()) return Handle<Code>::cast(probe); | 131   if (probe->IsCode()) return Handle<Code>::cast(probe); | 
| 132   return Handle<Code>::null(); | 132   return Handle<Code>::null(); | 
| 133 } | 133 } | 
| 134 | 134 | 
| 135 | 135 | 
| 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, | 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, | 
| 137                                              Handle<Object> object, | 137                                              Handle<Type> type, | 
| 138                                              Handle<Code> handler, | 138                                              Handle<Code> handler, | 
| 139                                              StrictModeFlag strict_mode) { | 139                                              StrictModeFlag strict_mode) { | 
| 140   Code::Kind kind = handler->handler_kind(); | 140   Code::Kind kind = handler->handler_kind(); | 
| 141   // Use the same cache holder for the IC as for the handler. | 141   InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); | 
| 142   InlineCacheHolderFlag cache_holder = |  | 
| 143       Code::ExtractCacheHolderFromFlags(handler->flags()); |  | 
| 144   Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |  | 
| 145       isolate(), *object, cache_holder)); |  | 
| 146   Handle<Map> stub_holder_map(stub_holder->map()); |  | 
| 147   Handle<Code> ic = FindIC( |  | 
| 148       name, stub_holder_map, kind, strict_mode, cache_holder); |  | 
| 149   if (!ic.is_null()) return ic; |  | 
| 150 | 142 | 
| 151   Handle<Map> map(object->GetMarkerMap(isolate())); | 143   Handle<Map> stub_holder; | 
|  | 144   Handle<Code> ic; | 
|  | 145   // There are multiple string maps that all use the same prototype. That | 
|  | 146   // prototype cannot hold multiple handlers, one for each of the string maps, | 
|  | 147   // for a single name. Hence, turn off caching of the IC. | 
|  | 148   bool can_be_cached = !type->Is(Type::String()); | 
|  | 149   if (can_be_cached) { | 
|  | 150     stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); | 
|  | 151     ic = FindIC(name, stub_holder, kind, strict_mode, flag); | 
|  | 152     if (!ic.is_null()) return ic; | 
|  | 153   } | 
|  | 154 | 
| 152   if (kind == Code::LOAD_IC) { | 155   if (kind == Code::LOAD_IC) { | 
| 153     LoadStubCompiler ic_compiler(isolate(), cache_holder); | 156     LoadStubCompiler ic_compiler(isolate(), flag); | 
| 154     ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 157     ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 
| 155   } else if (kind == Code::KEYED_LOAD_IC) { | 158   } else if (kind == Code::KEYED_LOAD_IC) { | 
| 156     KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder); | 159     KeyedLoadStubCompiler ic_compiler(isolate(), flag); | 
| 157     ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 160     ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 
| 158   } else if (kind == Code::STORE_IC) { | 161   } else if (kind == Code::STORE_IC) { | 
| 159     StoreStubCompiler ic_compiler(isolate(), strict_mode); | 162     StoreStubCompiler ic_compiler(isolate(), strict_mode); | 
| 160     ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 163     ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 
| 161   } else { | 164   } else { | 
| 162     ASSERT(kind == Code::KEYED_STORE_IC); | 165     ASSERT(kind == Code::KEYED_STORE_IC); | 
| 163     KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); | 166     KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); | 
| 164     ic = ic_compiler.CompileMonomorphicIC(map, handler, name); | 167     ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 
| 165   } | 168   } | 
| 166 | 169 | 
| 167   HeapObject::UpdateMapCodeCache(stub_holder, name, ic); | 170   if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); | 
| 168   return ic; | 171   return ic; | 
| 169 } | 172 } | 
| 170 | 173 | 
| 171 | 174 | 
| 172 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 175 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 
| 173                                                Handle<Object> object) { | 176                                                Handle<Object> object) { | 
| 174   InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 177   InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 
| 175   Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 178   Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 
| 176       isolate(), *object, cache_holder)); | 179       isolate(), *object, cache_holder)); | 
| 177   // If no global objects are present in the prototype chain, the load | 180   // If no global objects are present in the prototype chain, the load | 
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 577   ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map); | 580   ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map); | 
| 578 | 581 | 
| 579   if (!receiver_map->is_shared()) { | 582   if (!receiver_map->is_shared()) { | 
| 580     Map::UpdateCodeCache(receiver_map, name, ic); | 583     Map::UpdateCodeCache(receiver_map, name, ic); | 
| 581   } | 584   } | 
| 582 | 585 | 
| 583   return ic; | 586   return ic; | 
| 584 } | 587 } | 
| 585 | 588 | 
| 586 | 589 | 
|  | 590 // TODO(verwaest): Change this method so it takes in a TypeHandleList. | 
| 587 Handle<Code> StubCache::ComputeLoadElementPolymorphic( | 591 Handle<Code> StubCache::ComputeLoadElementPolymorphic( | 
| 588     MapHandleList* receiver_maps) { | 592     MapHandleList* receiver_maps) { | 
| 589   Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); | 593   Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); | 
| 590   Handle<PolymorphicCodeCache> cache = | 594   Handle<PolymorphicCodeCache> cache = | 
| 591       isolate_->factory()->polymorphic_code_cache(); | 595       isolate_->factory()->polymorphic_code_cache(); | 
| 592   Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 596   Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 
| 593   if (probe->IsCode()) return Handle<Code>::cast(probe); | 597   if (probe->IsCode()) return Handle<Code>::cast(probe); | 
| 594 | 598 | 
|  | 599   TypeHandleList types(receiver_maps->length()); | 
|  | 600   for (int i = 0; i < receiver_maps->length(); i++) { | 
|  | 601     types.Add(handle(Type::Class(receiver_maps->at(i)), isolate())); | 
|  | 602   } | 
| 595   CodeHandleList handlers(receiver_maps->length()); | 603   CodeHandleList handlers(receiver_maps->length()); | 
| 596   KeyedLoadStubCompiler compiler(isolate_); | 604   KeyedLoadStubCompiler compiler(isolate_); | 
| 597   compiler.CompileElementHandlers(receiver_maps, &handlers); | 605   compiler.CompileElementHandlers(receiver_maps, &handlers); | 
| 598   Handle<Code> code = compiler.CompilePolymorphicIC( | 606   Handle<Code> code = compiler.CompilePolymorphicIC( | 
| 599       receiver_maps, &handlers, factory()->empty_string(), | 607       &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); | 
| 600       Code::NORMAL, ELEMENT); |  | 
| 601 | 608 | 
| 602   isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 609   isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 
| 603 | 610 | 
| 604   PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 611   PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 
| 605   return code; | 612   return code; | 
| 606 } | 613 } | 
| 607 | 614 | 
| 608 | 615 | 
| 609 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, | 616 Handle<Code> StubCache::ComputePolymorphicIC(TypeHandleList* types, | 
| 610                                              CodeHandleList* handlers, | 617                                              CodeHandleList* handlers, | 
| 611                                              int number_of_valid_maps, | 618                                              int number_of_valid_types, | 
| 612                                              Handle<Name> name, | 619                                              Handle<Name> name, | 
| 613                                              StrictModeFlag strict_mode) { | 620                                              StrictModeFlag strict_mode) { | 
| 614   Handle<Code> handler = handlers->at(0); | 621   Handle<Code> handler = handlers->at(0); | 
| 615   Code::Kind kind = handler->handler_kind(); | 622   Code::Kind kind = handler->handler_kind(); | 
| 616   Code::StubType type = number_of_valid_maps == 1 ? handler->type() | 623   Code::StubType type = number_of_valid_types == 1 ? handler->type() | 
| 617                                                   : Code::NORMAL; | 624                                                    : Code::NORMAL; | 
| 618   if (kind == Code::LOAD_IC) { | 625   if (kind == Code::LOAD_IC) { | 
| 619     LoadStubCompiler ic_compiler(isolate_); | 626     LoadStubCompiler ic_compiler(isolate_); | 
| 620     return ic_compiler.CompilePolymorphicIC( | 627     return ic_compiler.CompilePolymorphicIC( | 
| 621         receiver_maps, handlers, name, type, PROPERTY); | 628         types, handlers, name, type, PROPERTY); | 
| 622   } else { | 629   } else { | 
| 623     ASSERT(kind == Code::STORE_IC); | 630     ASSERT(kind == Code::STORE_IC); | 
| 624     StoreStubCompiler ic_compiler(isolate_, strict_mode); | 631     StoreStubCompiler ic_compiler(isolate_, strict_mode); | 
| 625     return ic_compiler.CompilePolymorphicIC( | 632     return ic_compiler.CompilePolymorphicIC( | 
| 626         receiver_maps, handlers, name, type, PROPERTY); | 633         types, handlers, name, type, PROPERTY); | 
| 627   } | 634   } | 
| 628 } | 635 } | 
| 629 | 636 | 
| 630 | 637 | 
| 631 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 638 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 
| 632     MapHandleList* receiver_maps, | 639     MapHandleList* receiver_maps, | 
| 633     KeyedAccessStoreMode store_mode, | 640     KeyedAccessStoreMode store_mode, | 
| 634     StrictModeFlag strict_mode) { | 641     StrictModeFlag strict_mode) { | 
| 635   ASSERT(store_mode == STANDARD_STORE || | 642   ASSERT(store_mode == STANDARD_STORE || | 
| 636          store_mode == STORE_AND_GROW_NO_TRANSITION || | 643          store_mode == STORE_AND_GROW_NO_TRANSITION || | 
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1174     Register object_reg, | 1181     Register object_reg, | 
| 1175     Handle<JSObject> holder, | 1182     Handle<JSObject> holder, | 
| 1176     Handle<Name> name, | 1183     Handle<Name> name, | 
| 1177     Label* miss) { | 1184     Label* miss) { | 
| 1178   return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder, | 1185   return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder, | 
| 1179                          this->name(), scratch1(), scratch2(), | 1186                          this->name(), scratch1(), scratch2(), | 
| 1180                          name, miss, SKIP_RECEIVER); | 1187                          name, miss, SKIP_RECEIVER); | 
| 1181 } | 1188 } | 
| 1182 | 1189 | 
| 1183 | 1190 | 
| 1184 bool BaseLoadStoreStubCompiler::HasHeapNumberMap(MapHandleList* receiver_maps) { | 1191 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { | 
| 1185   for (int i = 0; i < receiver_maps->length(); ++i) { | 1192   for (int i = 0; i < types->length(); ++i) { | 
| 1186     Handle<Map> map = receiver_maps->at(i); | 1193     if (types->at(i)->Is(Type::Number())) return true; | 
| 1187     if (map.is_identical_to(isolate()->factory()->heap_number_map())) { |  | 
| 1188       return true; |  | 
| 1189     } |  | 
| 1190   } | 1194   } | 
| 1191   return false; | 1195   return false; | 
| 1192 } | 1196 } | 
| 1193 | 1197 | 
| 1194 | 1198 | 
| 1195 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object, | 1199 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object, | 
| 1196                                                     Register object_reg, | 1200                                                     Register object_reg, | 
| 1197                                                     Handle<JSObject> holder, | 1201                                                     Handle<JSObject> holder, | 
| 1198                                                     Handle<Name> name) { | 1202                                                     Handle<Name> name) { | 
| 1199   Label miss; | 1203   Label miss; | 
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1346     ASSERT(callback->getter() != NULL); | 1350     ASSERT(callback->getter() != NULL); | 
| 1347 | 1351 | 
| 1348     Register reg = CallbackHandlerFrontend( | 1352     Register reg = CallbackHandlerFrontend( | 
| 1349         interceptor_holder, interceptor_reg, holder, name, callback); | 1353         interceptor_holder, interceptor_reg, holder, name, callback); | 
| 1350     GenerateLoadCallback(reg, callback); | 1354     GenerateLoadCallback(reg, callback); | 
| 1351   } | 1355   } | 
| 1352 } | 1356 } | 
| 1353 | 1357 | 
| 1354 | 1358 | 
| 1355 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( | 1359 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( | 
| 1356     Handle<Map> receiver_map, | 1360     Handle<Type> type, | 
| 1357     Handle<Code> handler, | 1361     Handle<Code> handler, | 
| 1358     Handle<Name> name) { | 1362     Handle<Name> name) { | 
| 1359   MapHandleList receiver_maps(1); | 1363   TypeHandleList types(1); | 
| 1360   receiver_maps.Add(receiver_map); |  | 
| 1361   CodeHandleList handlers(1); | 1364   CodeHandleList handlers(1); | 
|  | 1365   types.Add(type); | 
| 1362   handlers.Add(handler); | 1366   handlers.Add(handler); | 
| 1363   Code::StubType type = handler->type(); | 1367   Code::StubType stub_type = handler->type(); | 
| 1364   return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); | 1368   return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); | 
| 1365 } | 1369 } | 
| 1366 | 1370 | 
| 1367 | 1371 | 
| 1368 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 
| 1369     Handle<Object> object, | 1373     Handle<Object> object, | 
| 1370     Handle<JSObject> holder, | 1374     Handle<JSObject> holder, | 
| 1371     Handle<Name> name, | 1375     Handle<Name> name, | 
| 1372     Handle<JSFunction> getter) { | 1376     Handle<JSFunction> getter) { | 
| 1373   HandlerFrontend(object, receiver(), holder, name); | 1377   HandlerFrontend(object, receiver(), holder, name); | 
| 1374   GenerateLoadViaGetter(masm(), receiver(), getter); | 1378   GenerateLoadViaGetter(masm(), receiver(), getter); | 
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1824           Handle<FunctionTemplateInfo>( | 1828           Handle<FunctionTemplateInfo>( | 
| 1825               FunctionTemplateInfo::cast(signature->receiver())); | 1829               FunctionTemplateInfo::cast(signature->receiver())); | 
| 1826     } | 1830     } | 
| 1827   } | 1831   } | 
| 1828 | 1832 | 
| 1829   is_simple_api_call_ = true; | 1833   is_simple_api_call_ = true; | 
| 1830 } | 1834 } | 
| 1831 | 1835 | 
| 1832 | 1836 | 
| 1833 } }  // namespace v8::internal | 1837 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|