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