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 |