Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/ic/handler-compiler.h" | 7 #include "src/ic/handler-compiler.h" |
| 8 #include "src/ic/ic-inl.h" | 8 #include "src/ic/ic-inl.h" |
| 9 #include "src/ic/ic-compiler.h" | 9 #include "src/ic/ic-compiler.h" |
| 10 | 10 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 } | 56 } |
| 57 | 57 |
| 58 CacheHolderFlag flag; | 58 CacheHolderFlag flag; |
| 59 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); | 59 Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); |
| 60 if (kind == Code::KEYED_STORE_IC) { | 60 if (kind == Code::KEYED_STORE_IC) { |
| 61 // Always set the "property" bit. | 61 // Always set the "property" bit. |
| 62 extra_ic_state = | 62 extra_ic_state = |
| 63 KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY); | 63 KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY); |
| 64 DCHECK(STANDARD_STORE == | 64 DCHECK(STANDARD_STORE == |
| 65 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); | 65 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); |
| 66 } else if (kind == Code::KEYED_LOAD_IC) { | |
| 67 extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state, | |
| 68 PROPERTY); | |
| 66 } | 69 } |
| 67 | 70 |
| 68 Handle<Code> ic; | 71 Handle<Code> ic; |
| 69 // There are multiple string maps that all use the same prototype. That | 72 // There are multiple string maps that all use the same prototype. That |
| 70 // prototype cannot hold multiple handlers, one for each of the string maps, | 73 // prototype cannot hold multiple handlers, one for each of the string maps, |
| 71 // for a single name. Hence, turn off caching of the IC. | 74 // for a single name. Hence, turn off caching of the IC. |
| 72 bool can_be_cached = !type->Is(HeapType::String()); | 75 bool can_be_cached = !type->Is(HeapType::String()); |
| 73 if (can_be_cached) { | 76 if (can_be_cached) { |
| 74 ic = Find(name, stub_holder, kind, extra_ic_state, flag); | 77 ic = Find(name, stub_holder, kind, extra_ic_state, flag); |
| 75 if (!ic.is_null()) return ic; | 78 if (!ic.is_null()) return ic; |
| 76 } | 79 } |
| 77 | 80 |
| 78 PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); | 81 PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); |
| 79 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); | 82 ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); |
| 80 | 83 |
| 81 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); | 84 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); |
| 82 return ic; | 85 return ic; |
| 83 } | 86 } |
| 84 | 87 |
| 85 | 88 |
| 86 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( | 89 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( |
| 87 Handle<Map> receiver_map) { | 90 Handle<Map> receiver_map, |
| 91 ExtraICState extra_ic_state, | |
| 92 IcCheckType key_type) { | |
| 88 Isolate* isolate = receiver_map->GetIsolate(); | 93 Isolate* isolate = receiver_map->GetIsolate(); |
| 89 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 94 extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state, |
| 95 key_type); | |
| 96 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, | |
| 97 extra_ic_state); | |
| 90 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); | 98 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); |
| 91 | 99 |
| 92 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); | 100 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); |
| 93 if (probe->IsCode()) return Handle<Code>::cast(probe); | 101 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 94 | 102 |
| 95 Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map); | 103 Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map); |
| 96 PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC); | 104 PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC, extra_ic_state); |
| 97 Handle<Code> code = | 105 Handle<Code> code = |
| 98 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, | 106 compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, |
| 99 isolate->factory()->empty_string(), ELEMENT); | 107 isolate->factory()->empty_string(), ELEMENT); |
|
Jakob Kummerow
2014/12/11 09:52:42
See how it says ELEMENT here? This method is only
| |
| 100 | 108 |
| 101 Map::UpdateCodeCache(receiver_map, name, code); | 109 Map::UpdateCodeCache(receiver_map, name, code); |
| 102 return code; | 110 return code; |
| 103 } | 111 } |
| 104 | 112 |
| 105 | 113 |
| 106 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler( | 114 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler( |
| 107 Handle<Map> receiver_map) { | 115 Handle<Map> receiver_map) { |
| 108 Isolate* isolate = receiver_map->GetIsolate(); | 116 Isolate* isolate = receiver_map->GetIsolate(); |
| 109 ElementsKind elements_kind = receiver_map->elements_kind(); | 117 ElementsKind elements_kind = receiver_map->elements_kind(); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 if (!receiver_map->is_dictionary_map()) { | 254 if (!receiver_map->is_dictionary_map()) { |
| 247 Map::UpdateCodeCache(receiver_map, name, ic); | 255 Map::UpdateCodeCache(receiver_map, name, ic); |
| 248 } | 256 } |
| 249 | 257 |
| 250 return ic; | 258 return ic; |
| 251 } | 259 } |
| 252 | 260 |
| 253 | 261 |
| 254 // TODO(verwaest): Change this method so it takes in a TypeHandleList. | 262 // TODO(verwaest): Change this method so it takes in a TypeHandleList. |
| 255 Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic( | 263 Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic( |
| 256 MapHandleList* receiver_maps) { | 264 MapHandleList* receiver_maps, |
| 265 ExtraICState extra_ic_state, | |
| 266 IcCheckType key_type) { | |
| 257 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); | 267 Isolate* isolate = receiver_maps->at(0)->GetIsolate(); |
| 258 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); | 268 extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state, |
| 269 key_type); | |
| 270 Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, | |
| 271 POLYMORPHIC, | |
| 272 extra_ic_state); | |
| 259 Handle<PolymorphicCodeCache> cache = | 273 Handle<PolymorphicCodeCache> cache = |
| 260 isolate->factory()->polymorphic_code_cache(); | 274 isolate->factory()->polymorphic_code_cache(); |
| 261 Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 275 Handle<Object> probe = cache->Lookup(receiver_maps, flags); |
| 262 if (probe->IsCode()) return Handle<Code>::cast(probe); | 276 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 263 | 277 |
| 264 TypeHandleList types(receiver_maps->length()); | 278 TypeHandleList types(receiver_maps->length()); |
| 265 for (int i = 0; i < receiver_maps->length(); i++) { | 279 for (int i = 0; i < receiver_maps->length(); i++) { |
| 266 types.Add(HeapType::Class(receiver_maps->at(i), isolate)); | 280 types.Add(HeapType::Class(receiver_maps->at(i), isolate)); |
| 267 } | 281 } |
| 268 CodeHandleList handlers(receiver_maps->length()); | 282 CodeHandleList handlers(receiver_maps->length()); |
| 269 ElementHandlerCompiler compiler(isolate); | 283 ElementHandlerCompiler compiler(isolate); |
| 270 compiler.CompileElementHandlers(receiver_maps, &handlers); | 284 compiler.CompileElementHandlers(receiver_maps, &handlers); |
| 271 PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); | 285 PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC, extra_ic_state); |
| 272 Handle<Code> code = ic_compiler.CompilePolymorphic( | 286 Handle<Code> code = ic_compiler.CompilePolymorphic( |
| 273 &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, | 287 &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, |
| 274 ELEMENT); | 288 key_type); |
|
Jakob Kummerow
2014/12/11 09:52:41
So here you're replacing the hard-coded ELEMENT wi
| |
| 275 | 289 |
| 276 isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); | 290 isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); |
| 277 | 291 |
| 278 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 292 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 279 return code; | 293 return code; |
| 280 } | 294 } |
| 281 | 295 |
| 282 | 296 |
| 283 Handle<Code> PropertyICCompiler::ComputePolymorphic( | 297 Handle<Code> PropertyICCompiler::ComputePolymorphic( |
| 284 Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, | 298 Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 | 463 |
| 450 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); | 464 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); |
| 451 | 465 |
| 452 return GetCode(kind(), Code::NORMAL, factory()->empty_string()); | 466 return GetCode(kind(), Code::NORMAL, factory()->empty_string()); |
| 453 } | 467 } |
| 454 | 468 |
| 455 | 469 |
| 456 #undef __ | 470 #undef __ |
| 457 } | 471 } |
| 458 } // namespace v8::internal | 472 } // namespace v8::internal |
| OLD | NEW |