1a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 76474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h" 8a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic-inl.h" 9a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic-compiler.h" 10a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 16eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::Find(Handle<Name> name, 17eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Map> stub_holder, Code::Kind kind, 18eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org ExtraICState extra_state, 19eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org CacheHolderFlag cache_holder) { 20a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Code::Flags flags = 21a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Code::ComputeMonomorphicFlags(kind, extra_state, cache_holder); 22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Object* probe = stub_holder->FindInCodeCache(*name, flags); 23e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (probe->IsCode()) return handle(Code::cast(probe)); 244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return Handle<Code>::null(); 254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgbool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) { 296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org for (int i = 0; i < types->length(); ++i) { 306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (types->at(i)->Is(HeapType::Number())) return true; 316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return false; 336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type, 376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<Code> handler, 386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<Name> name, 396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org IcCheckType check) { 406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org TypeHandleList types(1); 416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org CodeHandleList handlers(1); 426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org types.Add(type); 436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org handlers.Add(handler); 446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Code::StubType stub_type = handler->type(); 456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return CompilePolymorphic(&types, &handlers, name, stub_type, check); 46bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 47bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 48bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 49dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeMonomorphic( 50dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Code::Kind kind, Handle<Name> name, Handle<HeapType> type, 51dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Code> handler, ExtraICState extra_ic_state) { 52dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = name->GetIsolate(); 53dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org if (handler.is_identical_to(isolate->builtins()->LoadIC_Normal()) || 54dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org handler.is_identical_to(isolate->builtins()->StoreIC_Normal())) { 55dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org name = isolate->factory()->normal_ic_symbol(); 56dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org } 57dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 58474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org CacheHolderFlag flag; 59dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); 60af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 61af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Code> ic; 62af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // There are multiple string maps that all use the same prototype. That 63af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // prototype cannot hold multiple handlers, one for each of the string maps, 64af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // for a single name. Hence, turn off caching of the IC. 656d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bool can_be_cached = !type->Is(HeapType::String()); 66af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (can_be_cached) { 67dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ic = Find(name, stub_holder, kind, extra_ic_state, flag); 68af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (!ic.is_null()) return ic; 69af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 71eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org#ifdef DEBUG 72eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (kind == Code::KEYED_STORE_IC) { 73e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(STANDARD_STORE == 74ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); 75fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } 76eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org#endif 77eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org 78dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); 79eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); 80bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 81af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); 82bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org return ic; 83bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 84bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 85bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 86dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( 87dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Map> receiver_map) { 88dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = receiver_map->GetIsolate(); 898432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 90dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); 91003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 92dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 93003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (probe->IsCode()) return Handle<Code>::cast(probe); 94003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 95eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org ElementsKind elements_kind = receiver_map->elements_kind(); 96eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Code> stub; 97a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (receiver_map->has_indexed_interceptor()) { 98a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org stub = LoadIndexedInterceptorStub(isolate).GetCode(); 9906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else if (receiver_map->has_sloppy_arguments_elements()) { 10006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode(); 101a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } else if (receiver_map->has_fast_elements() || 102a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org receiver_map->has_external_array_elements() || 103a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org receiver_map->has_fixed_typed_array_elements()) { 104dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org stub = LoadFastElementStub(isolate, 105dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org receiver_map->instance_type() == JS_ARRAY_TYPE, 106dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org elements_kind).GetCode(); 107eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } else { 1089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org stub = LoadDictionaryElementStub(isolate).GetCode(); 109eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } 110dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC); 111eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Code> code = 112dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, 113dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->factory()->empty_string(), ELEMENT); 114003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 115003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Map::UpdateCodeCache(receiver_map, name, code); 116003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return code; 117003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 118003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 119003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 120dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeKeyedStoreMonomorphic( 121dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Map> receiver_map, StrictMode strict_mode, 122750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org KeyedAccessStoreMode store_mode) { 123dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = receiver_map->GetIsolate(); 124cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_state = 125cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); 126474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Code::Flags flags = 127474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, extra_state); 128003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(store_mode == STANDARD_STORE || 1307bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_AND_GROW_NO_TRANSITION || 1317bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_NO_TRANSITION_HANDLE_COW); 133003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 134dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<String> name = isolate->factory()->KeyedStoreMonomorphic_string(); 135dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate); 136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (probe->IsCode()) return Handle<Code>::cast(probe); 137ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 138dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 139eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Code> code = 140dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org compiler.CompileKeyedStoreMonomorphic(receiver_map, store_mode); 141b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Map::UpdateCodeCache(receiver_map, name, code); 143a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) == 144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org store_mode); 1450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return code; 1460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 1470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 149dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgCode* PropertyICCompiler::FindPreMonomorphic(Isolate* isolate, Code::Kind kind, 150dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ExtraICState state) { 1519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 1529cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org UnseededNumberDictionary* dictionary = 153dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->heap()->non_monomorphic_cache(); 154dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org int entry = dictionary->FindEntry(isolate, flags); 155e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(entry != -1); 1569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Object* code = dictionary->ValueAt(entry); 1579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org // This might be called during the marking phase of the collector 1589cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org // hence the unchecked cast. 1599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return reinterpret_cast<Code*>(code); 1609cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 1619cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 1629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 163a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgstatic void FillCache(Isolate* isolate, Handle<Code> code) { 164a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<UnseededNumberDictionary> dictionary = UnseededNumberDictionary::Set( 165a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate->factory()->non_monomorphic_cache(), code->flags(), code); 166a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 167a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 168a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 169a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 170dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeLoad(Isolate* isolate, 171dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org InlineCacheState ic_state, 172dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ExtraICState extra_state) { 1739cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); 1749cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<UnseededNumberDictionary> cache = 175dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->factory()->non_monomorphic_cache(); 176dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org int entry = cache->FindEntry(isolate, flags); 1779cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 1789cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 179dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler compiler(isolate, Code::LOAD_IC); 1809cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code; 1819cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if (ic_state == UNINITIALIZED) { 1829cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileLoadInitialize(flags); 1839cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else if (ic_state == PREMONOMORPHIC) { 1849cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileLoadPreMonomorphic(flags); 1859cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else { 1869cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org UNREACHABLE(); 1879cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } 188dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org FillCache(isolate, code); 1899cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 1909cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 1919cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 1929cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 193dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeStore(Isolate* isolate, 194dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org InlineCacheState ic_state, 195dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ExtraICState extra_state) { 1969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state); 1979cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<UnseededNumberDictionary> cache = 198dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->factory()->non_monomorphic_cache(); 199dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org int entry = cache->FindEntry(isolate, flags); 2009cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 2019cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 202dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler compiler(isolate, Code::STORE_IC); 2039cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code; 2049cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if (ic_state == UNINITIALIZED) { 2059cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileStoreInitialize(flags); 2069cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else if (ic_state == PREMONOMORPHIC) { 2079cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileStorePreMonomorphic(flags); 2089cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else if (ic_state == GENERIC) { 2099cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileStoreGeneric(flags); 2109cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else if (ic_state == MEGAMORPHIC) { 2119cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org code = compiler.CompileStoreMegamorphic(flags); 2129cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else { 2139cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org UNREACHABLE(); 2149cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } 2159cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 216dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org FillCache(isolate, code); 2179cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 2189cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 2199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 2209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 221dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeCompareNil(Handle<Map> receiver_map, 222dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org CompareNilICStub* stub) { 223dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = receiver_map->GetIsolate(); 224dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<String> name(isolate->heap()->empty_string()); 22531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org if (!receiver_map->is_dictionary_map()) { 226dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Code> cached_ic = 227dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Find(name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState()); 228ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (!cached_ic.is_null()) return cached_ic; 229ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 230ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2319801e3c558f3df82f01ac626b6171032afa33819machenbach@chromium.org Code::FindAndReplacePattern pattern; 232dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org pattern.Add(isolate->factory()->meta_map(), receiver_map); 233196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Handle<Code> ic = stub->GetCodeCopy(pattern); 234ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 23531c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org if (!receiver_map->is_dictionary_map()) { 236ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Map::UpdateCodeCache(receiver_map, name, ic); 237ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 238ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 239ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return ic; 240ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 241ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 242ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 243af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// TODO(verwaest): Change this method so it takes in a TypeHandleList. 244dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic( 245003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org MapHandleList* receiver_maps) { 246dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = receiver_maps->at(0)->GetIsolate(); 247003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); 248003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<PolymorphicCodeCache> cache = 249dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->factory()->polymorphic_code_cache(); 250003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Object> probe = cache->Lookup(receiver_maps, flags); 251003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (probe->IsCode()) return Handle<Code>::cast(probe); 252003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 253af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList types(receiver_maps->length()); 254af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org for (int i = 0; i < receiver_maps->length(); i++) { 255dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org types.Add(HeapType::Class(receiver_maps->at(i), isolate)); 256af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org } 2574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org CodeHandleList handlers(receiver_maps->length()); 258dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ElementHandlerCompiler compiler(isolate); 2594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org compiler.CompileElementHandlers(receiver_maps, &handlers); 260dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); 261eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Code> code = ic_compiler.CompilePolymorphic( 262dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, 263dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ELEMENT); 2644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 265dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); 2664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 267003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 268003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return code; 269003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 270003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 271003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 272dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputePolymorphic( 273dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, 274dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org int valid_types, Handle<Name> name, ExtraICState extra_ic_state) { 275fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> handler = handlers->at(0); 276dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL; 277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kind == Code::LOAD_IC || kind == Code::STORE_IC); 278dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state); 279eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY); 280bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 281bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 282bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 283dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::ComputeKeyedStorePolymorphic( 284dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, 285486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode) { 286dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Isolate* isolate = receiver_maps->at(0)->GetIsolate(); 287e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(store_mode == STANDARD_STORE || 2887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_AND_GROW_NO_TRANSITION || 2897bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 2907bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org store_mode == STORE_NO_TRANSITION_HANDLE_COW); 291003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<PolymorphicCodeCache> cache = 292dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate->factory()->polymorphic_code_cache(); 293a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ExtraICState extra_state = 294a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); 295003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Code::Flags flags = 296003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); 297003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Object> probe = cache->Lookup(receiver_maps, flags); 298003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (probe->IsCode()) return Handle<Code>::cast(probe); 299003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 300dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); 301eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Code> code = 302dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org compiler.CompileKeyedStorePolymorphic(receiver_maps, store_mode); 303003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 304003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return code; 305003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 306003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 307003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 308eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileLoadInitialize(Code::Flags flags) { 3099cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org LoadIC::GenerateInitialize(masm()); 3109cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize"); 311a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0)); 3129cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3139cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3149cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3159cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 316eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileLoadPreMonomorphic(Code::Flags flags) { 3179cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org LoadIC::GeneratePreMonomorphic(masm()); 3189cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadPreMonomorphic"); 3199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org PROFILE(isolate(), 3209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CodeCreateEvent(Logger::LOAD_PREMONOMORPHIC_TAG, *code, 0)); 3219cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3229cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3239cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3249cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 325eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileStoreInitialize(Code::Flags flags) { 3269cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org StoreIC::GenerateInitialize(masm()); 3279cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreInitialize"); 328a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PROFILE(isolate(), CodeCreateEvent(Logger::STORE_INITIALIZE_TAG, *code, 0)); 3299cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3319cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3329cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 333eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileStorePreMonomorphic(Code::Flags flags) { 3349cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org StoreIC::GeneratePreMonomorphic(masm()); 3359cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileStorePreMonomorphic"); 3369cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org PROFILE(isolate(), 3379cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org CodeCreateEvent(Logger::STORE_PREMONOMORPHIC_TAG, *code, 0)); 3389cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3399cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3409cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3419cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 342eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileStoreGeneric(Code::Flags flags) { 3439cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 344486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode = StoreIC::GetStrictMode(extra_state); 345a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org GenerateRuntimeSetProperty(masm(), strict_mode); 3469cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreGeneric"); 347a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PROFILE(isolate(), CodeCreateEvent(Logger::STORE_GENERIC_TAG, *code, 0)); 3489cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3499cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3509cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 352eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileStoreMegamorphic(Code::Flags flags) { 353f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org StoreIC::GenerateMegamorphic(masm()); 3549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 355a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PROFILE(isolate(), CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); 3569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return code; 3579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 3589cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 3599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 360eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type, 361eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<Name> name, 362eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org InlineCacheState state) { 363eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Code::Flags flags = 3642b995c4171e67960088466af11110c6f6aeea4fcmachenbach@chromium.org Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder()); 365750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Code> code = GetCodeWithFlags(flags, name); 3662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org IC::RegisterWeakMapDependency(code); 367750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); 368750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return code; 369750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 370750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 371750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 372dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic( 373eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) { 374003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Collect MONOMORPHIC stubs for all |receiver_maps|. 3754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org CodeHandleList handlers(receiver_maps->length()); 376003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org MapHandleList transitioned_maps(receiver_maps->length()); 377003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org for (int i = 0; i < receiver_maps->length(); ++i) { 378003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Map> receiver_map(receiver_maps->at(i)); 379003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Code> cached_stub; 380003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Map> transitioned_map = 381003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org receiver_map->FindTransitionedMap(receiver_maps); 382003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 383003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // TODO(mvstanton): The code below is doing pessimistic elements 384003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // transitions. I would like to stop doing that and rely on Allocation Site 385003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Tracking to do a better job of ensuring the data types are what they need 386003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // to be. Not all the elements are in place yet, pessimistic elements 387003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // transitions are still important for performance. 388003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 389003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ElementsKind elements_kind = receiver_map->elements_kind(); 390003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!transitioned_map.is_null()) { 391eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org cached_stub = 392eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org ElementsTransitionAndStoreStub(isolate(), elements_kind, 393eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org transitioned_map->elements_kind(), 394eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org is_js_array, store_mode).GetCode(); 3959cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 3969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org cached_stub = isolate()->builtins()->KeyedStoreIC_Slow(); 397003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else { 39832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org if (receiver_map->has_fast_elements() || 3995c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org receiver_map->has_external_array_elements() || 4005c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org receiver_map->has_fixed_typed_array_elements()) { 401dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org cached_stub = StoreFastElementStub(isolate(), is_js_array, 402dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org elements_kind, store_mode).GetCode(); 4037bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } else { 404fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org cached_stub = StoreElementStub(isolate(), elements_kind).GetCode(); 4057bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 406003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 407e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!cached_stub.is_null()); 4084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org handlers.Add(cached_stub); 409003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org transitioned_maps.Add(transitioned_map); 410003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 411eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org 412dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Code> code = CompileKeyedStorePolymorphic(receiver_maps, &handlers, 413dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org &transitioned_maps); 414003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 415eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, 0)); 416003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return code; 417003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 418003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 419003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 4206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#define __ ACCESS_MASM(masm()) 4216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgHandle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic( 4246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { 4256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ElementsKind elements_kind = receiver_map->elements_kind(); 4266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 4276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org Handle<Code> stub; 4286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org if (receiver_map->has_fast_elements() || 4296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org receiver_map->has_external_array_elements() || 4306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org receiver_map->has_fixed_typed_array_elements()) { 4316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org stub = StoreFastElementStub(isolate(), is_jsarray, elements_kind, 4326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org store_mode).GetCode(); 4336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } else { 434fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org stub = StoreElementStub(isolate(), elements_kind).GetCode(); 4356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org } 4366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); 4386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); 4406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org return GetCode(kind(), Code::NORMAL, factory()->empty_string()); 4426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org} 4436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org 4446d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org 4456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#undef __ 4464111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org} 447a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} // namespace v8::internal 448