165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h"
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h"
3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "arguments.h"
32ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org#include "ast.h"
336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org#include "code-stubs.h"
34c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h"
350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "gdb-jit.h"
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ic-inl.h"
3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "stub-cache.h"
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "vm-state-inl.h"
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// StubCache implementation.
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgStubCache::StubCache(Isolate* isolate)
482c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org    : isolate_(isolate) { }
49ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.orgvoid StubCache::Initialize() {
5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(IsPowerOf2(kPrimaryTableSize));
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(IsPowerOf2(kSecondaryTableSize));
54812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Clear();
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCode* StubCache::Set(Name* name, Map* map, Code* code) {
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the flags from the code.
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Code::Flags flags = Code::RemoveTypeFromFlags(code->flags());
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Validate that the name does not move on scavenge, and that we
63750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // can use identity checks instead of structural equality checks.
647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  ASSERT(!heap()->InNewSpace(name));
65750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(name->IsUniqueName());
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The state bits are not important to the hash function because
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the stub cache only contains monomorphic stubs. Make sure that
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the bits are the least significant so they will be the ones
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // masked out.
717276f14ca716596e0a0d17539516370c1f453847kasper.lund  ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC);
7283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org  STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Make sure that the code type is not included in the hash.
7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the primary entry.
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int primary_offset = PrimaryOffset(name, flags, map);
7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Entry* primary = entry(primary_, primary_offset);
80812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Code* old_code = primary->value;
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the primary entry has useful data in it, we retire it to the
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // secondary cache before overwriting it.
84812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
85812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Map* old_map = primary->map;
86812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Code::Flags old_flags = Code::RemoveTypeFromFlags(old_code->flags());
87812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    int seed = PrimaryOffset(primary->key, old_flags, old_map);
88812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Entry* secondary = entry(secondary_, secondary_offset);
9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    *secondary = *primary;
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update primary cache.
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  primary->key = name;
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  primary->value = code;
96812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  primary->map = map;
97812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return code;
9943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
102750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHandle<Code> StubCache::FindIC(Handle<Name> name,
103f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                               Handle<Map> stub_holder,
104750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                               Code::Kind kind,
105cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                               ExtraICState extra_state,
106b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                               InlineCacheHolderFlag cache_holder) {
107b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
108b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      kind, extra_state, cache_holder);
109f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
1104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (probe->IsCode()) return Handle<Code>::cast(probe);
1114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return Handle<Code>::null();
1124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
1134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
1144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
1152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> StubCache::FindHandler(Handle<Name> name,
116f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                    Handle<Map> stub_holder,
1172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                    Code::Kind kind,
118cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                    InlineCacheHolderFlag cache_holder) {
119bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
120cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind);
121b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
122f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_);
123bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (probe->IsCode()) return Handle<Code>::cast(probe);
124bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return Handle<Code>::null();
125bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
126bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
127bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
128cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgHandle<Code> StubCache::ComputeMonomorphicIC(
129cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    Handle<Name> name,
130cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    Handle<Type> type,
131cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    Handle<Code> handler,
132cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ExtraICState extra_ic_state) {
133fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Code::Kind kind = handler->handler_kind();
134af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
135af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
136af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Handle<Map> stub_holder;
137af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Handle<Code> ic;
138af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // There are multiple string maps that all use the same prototype. That
139af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // prototype cannot hold multiple handlers, one for each of the string maps,
140af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // for a single name. Hence, turn off caching of the IC.
141af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  bool can_be_cached = !type->Is(Type::String());
142af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  if (can_be_cached) {
143af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
144cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ic = FindIC(name, stub_holder, kind, extra_ic_state, flag);
145af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (!ic.is_null()) return ic;
146af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
148fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  if (kind == Code::LOAD_IC) {
149af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    LoadStubCompiler ic_compiler(isolate(), flag);
150af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
151fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  } else if (kind == Code::KEYED_LOAD_IC) {
152af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    KeyedLoadStubCompiler ic_compiler(isolate(), flag);
153af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
154fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  } else if (kind == Code::STORE_IC) {
155ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    StoreStubCompiler ic_compiler(isolate(), extra_ic_state);
156af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
157fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  } else {
158fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    ASSERT(kind == Code::KEYED_STORE_IC);
159ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    ASSERT(STANDARD_STORE ==
160ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org           KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
161ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state);
162af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    ic = ic_compiler.CompileMonomorphicIC(type, handler, name);
163fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
164bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
165af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic);
166bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  return ic;
167bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
168bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
169bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
170750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHandle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name,
171f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                               Handle<Type> type) {
172f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type);
173f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate());
174f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // If no dictionary mode objects are present in the prototype chain, the load
175f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // nonexistent IC stub can be shared for all names for a given map and we use
176f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // the empty string for the map cache in that case. If there are dictionary
177f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // mode objects involved, we need to do negative lookups in the stub and
178f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // therefore the stub will be specific to the name.
179f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Map> current_map = stub_holder;
180f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Name> cache_name = current_map->is_dictionary_map()
181f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      ? name : Handle<Name>::cast(isolate()->factory()->empty_string());
182f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Object> next(current_map->prototype(), isolate());
183f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<JSObject> last = Handle<JSObject>::null();
184f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  while (!next->IsNull()) {
185f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    last = Handle<JSObject>::cast(next);
186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    next = handle(current_map->prototype(), isolate());
187f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    current_map = handle(Handle<HeapObject>::cast(next)->map());
188f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if (current_map->is_dictionary_map()) cache_name = name;
189f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
190e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org
191c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Compile the stub that is either shared for all names or
192c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // name specific if there are global objects involved.
193b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<Code> handler = FindHandler(
194f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      cache_name, stub_holder, Code::LOAD_IC, flag);
1954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (!handler.is_null()) return handler;
196394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
197f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  LoadStubCompiler compiler(isolate_, flag);
198f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  handler = compiler.CompileLoadNonexistent(type, last, cache_name);
199f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Map::UpdateCodeCache(stub_holder, cache_name, handler);
2004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  return handler;
201c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org}
202c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
203c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
204003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
2058432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
206750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name =
2074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate()->factory()->KeyedLoadElementMonomorphic_string();
208003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
209003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
210003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (probe->IsCode()) return Handle<Code>::cast(probe);
211003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
212003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  KeyedLoadStubCompiler compiler(isolate());
213003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> code = compiler.CompileLoadElement(receiver_map);
214003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
215003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Map::UpdateCodeCache(receiver_map, name, code);
216003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return code;
217003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
218003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
219003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
220003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> StubCache::ComputeKeyedStoreElement(
2217028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    Handle<Map> receiver_map,
222003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    StrictModeFlag strict_mode,
223750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    KeyedAccessStoreMode store_mode) {
224cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state =
225cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode);
226003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
2278432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org      Code::KEYED_STORE_IC, extra_state);
228003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
229750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(store_mode == STANDARD_STORE ||
2307bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_AND_GROW_NO_TRANSITION ||
2317bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
2327bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_NO_TRANSITION_HANDLE_COW);
233003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
234750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<String> name =
235750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      isolate()->factory()->KeyedStoreElementMonomorphic_string();
236fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_);
237394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (probe->IsCode()) return Handle<Code>::cast(probe);
238ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
239ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  KeyedStoreStubCompiler compiler(isolate(), extra_state);
240003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> code = compiler.CompileStoreElement(receiver_map);
241b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
2427028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Map::UpdateCodeCache(receiver_map, name, code);
243cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
244cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org         == store_mode);
2450a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  return code;
2460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
2470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
2480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
2491af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#define CALL_LOGGER_TAG(kind, type) \
2501af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
252394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallConstant(int argc,
253303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            Code::Kind kind,
254cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                            ExtraICState extra_state,
255750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                            Handle<Name> name,
256394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            Handle<Object> object,
257394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            Handle<JSObject> holder,
258394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            Handle<JSFunction> function) {
25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the check type and the map.
260b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
261b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
2624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_, *object, cache_holder));
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute check type based on receiver/holder.
265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckType check = RECEIVER_MAP_CHECK;
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (object->IsString()) {
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    check = STRING_CHECK;
2684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  } else if (object->IsSymbol()) {
2694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    check = SYMBOL_CHECK;
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (object->IsNumber()) {
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    check = NUMBER_CHECK;
27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else if (object->IsBoolean()) {
273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    check = BOOLEAN_CHECK;
27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2762f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  if (check != RECEIVER_MAP_CHECK &&
2772f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      !function->IsBuiltin() &&
2782f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      function->shared()->is_classic_mode()) {
2792f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    // Calling non-strict non-builtins with a value as the receiver
2802f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    // requires boxing.
2812f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org    return Handle<Code>::null();
2822f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org  }
2832f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org
2848432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
2859af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      kind, extra_state, cache_holder, Code::FAST, argc);
2864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
287fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                       isolate_);
288394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (probe->IsCode()) return Handle<Code>::cast(probe);
289394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
290394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code =
2922f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org      compiler.CompileCallConstant(object, holder, name, check, function);
293394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  code->set_check_type(check);
294876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  ASSERT(flags == code->flags());
295394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PROFILE(isolate_,
296394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
2981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
2991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (CallStubCompiler::CanBeCached(function)) {
3004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    HeapObject::UpdateMapCodeCache(stub_holder, name, code);
3011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
3022c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  return code;
30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallField(int argc,
307303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                         Code::Kind kind,
308cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                         ExtraICState extra_state,
309750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                         Handle<Name> name,
310394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                         Handle<Object> object,
311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                         Handle<JSObject> holder,
312eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org                                         PropertyIndex index) {
31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the check type and the map.
314b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
315b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
3164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_, *object, cache_holder));
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1233596): We cannot do receiver map check for non-JS objects
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // because they may be represented as immediates without a
32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // map. Instead, we check against the map in the holder.
3214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (object->IsNumber() || object->IsSymbol() ||
3224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      object->IsBoolean() || object->IsString()) {
32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    object = holder;
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3268432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
3279af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      kind, extra_state, cache_holder, Code::FAST, argc);
3284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
329fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                       isolate_);
330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (probe->IsCode()) return Handle<Code>::cast(probe);
331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code =
334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      compiler.CompileCallField(Handle<JSObject>::cast(object),
335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                holder, index, name);
336876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  ASSERT(flags == code->flags());
337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PROFILE(isolate_,
338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
339394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
3404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  HeapObject::UpdateMapCodeCache(stub_holder, name, code);
3412c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  return code;
34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallInterceptor(int argc,
346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                               Code::Kind kind,
347cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                               ExtraICState extra_state,
348750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                               Handle<Name> name,
349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                               Handle<Object> object,
350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                               Handle<JSObject> holder) {
35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Compute the check type and the map.
352b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
353b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
3544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      isolate_, *object, cache_holder));
35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // TODO(1233596): We cannot do receiver map check for non-JS objects
35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // because they may be represented as immediates without a
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // map. Instead, we check against the map in the holder.
3594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (object->IsNumber() || object->IsSymbol() ||
3604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      object->IsBoolean() || object->IsString()) {
36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    object = holder;
36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3648432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
3659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org      kind, extra_state, cache_holder, Code::FAST, argc);
3664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
367fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                       isolate_);
368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (probe->IsCode()) return Handle<Code>::cast(probe);
369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code =
372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
373394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                      holder, name);
374876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  ASSERT(flags == code->flags());
375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PROFILE(isolate(),
376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
3784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  HeapObject::UpdateMapCodeCache(stub_holder, name, code);
3792c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  return code;
38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
383394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallGlobal(int argc,
384303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                          Code::Kind kind,
385cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                          ExtraICState extra_state,
386750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                          Handle<Name> name,
387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                          Handle<JSObject> receiver,
388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                          Handle<GlobalObject> holder,
389b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                          Handle<PropertyCell> cell,
390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                          Handle<JSFunction> function) {
3918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
392b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      kind, extra_state, OWN_MAP, Code::NORMAL, argc);
393fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
394fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                       isolate_);
395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (probe->IsCode()) return Handle<Code>::cast(probe);
396394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
397fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  CallStubCompiler compiler(isolate(), argc, kind, extra_state);
398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code =
399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      compiler.CompileCallGlobal(receiver, holder, cell, function, name);
400876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  ASSERT(flags == code->flags());
401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PROFILE(isolate(),
402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
4041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (CallStubCompiler::CanBeCached(function)) {
405fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    HeapObject::UpdateMapCodeCache(receiver, name, code);
4061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4072c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  return code;
4082abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org}
4092abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
4102abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic void FillCache(Isolate* isolate, Handle<Code> code) {
412f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> dictionary =
413f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
414f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                    code->flags(),
415f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                                    code);
416394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4201af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgCode* StubCache::FindCallInitialize(int argc,
42140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                    RelocInfo::Mode mode,
4221af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org                                    Code::Kind kind) {
423cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state =
42440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
425cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT
426cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                         ? CONTEXTUAL : NOT_CONTEXTUAL);
427394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
4287a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
429f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  UnseededNumberDictionary* dictionary =
43072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org      isolate()->heap()->non_monomorphic_cache();
431394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = dictionary->FindEntry(isolate(), flags);
432394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  ASSERT(entry != -1);
433394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Object* code = dictionary->ValueAt(entry);
43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // This might be called during the marking phase of the collector
43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // hence the unchecked cast.
436394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return reinterpret_cast<Code*>(code);
43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
440394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallInitialize(int argc,
44140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                              RelocInfo::Mode mode,
442303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                              Code::Kind kind) {
443cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state =
44440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
445cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT
446cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                         ? CONTEXTUAL : NOT_CONTEXTUAL);
447394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
4487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc);
449f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
450f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
451394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
452394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
453394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
454394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
455394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallInitialize(flags);
456394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
457394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
461394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) {
462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return ComputeCallInitialize(argc, mode, Code::CALL_IC);
4634a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
4644a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4654a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
46634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgHandle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
467394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET,
468394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               Code::KEYED_CALL_IC);
4694a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
4704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
4714a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
472394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallPreMonomorphic(
47340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    int argc,
47440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    Code::Kind kind,
475cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ExtraICState extra_state) {
476394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
4777a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc);
478f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
479f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
480394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
484394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
486394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
490394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallNormal(int argc,
49140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                          Code::Kind kind,
492cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                          ExtraICState extra_state) {
493394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
4947a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org      Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc);
495f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
496f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
497394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
498394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
499394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
500394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
501394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallNormal(flags);
502394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
503394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
507d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgHandle<Code> StubCache::ComputeCallArguments(int argc) {
508394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
509d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org      Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC,
510cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                         kNoExtraICState, Code::NORMAL, argc);
511f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
512f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
513394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
514394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
515394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
516394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
517394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallArguments(flags);
518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
519394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
5207b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
5217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
5227b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
523394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallMegamorphic(
52440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    int argc,
52540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    Code::Kind kind,
526cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ExtraICState extra_state) {
527394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
528394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
5297a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org                         Code::NORMAL, argc);
530f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
531f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
532394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
533394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
534394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
535394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
536394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallMegamorphic(flags);
537394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
538394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
542394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallMiss(int argc,
54340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                        Code::Kind kind,
544cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                        ExtraICState extra_state) {
5451af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
5461af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // and monomorphic stubs are not mixed up together in the stub cache.
547394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
548394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
5497a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org                         Code::NORMAL, argc, OWN_MAP);
550f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
551f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallMiss(flags);
557394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
558394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
559394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
560394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
561394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
562ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgHandle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
5634e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org                                          CompareNilICStub& stub) {
564ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  Handle<String> name(isolate_->heap()->empty_string());
565ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (!receiver_map->is_shared()) {
566ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Handle<Code> cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC,
567d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                                    stub.GetExtraICState());
568ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    if (!cached_ic.is_null()) return cached_ic;
569ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
570ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
571e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  Handle<Code> ic = stub.GetCodeCopyFromTemplate(isolate_);
572e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  ic->ReplaceNthObject(1, isolate_->heap()->meta_map(), *receiver_map);
573ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
574ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  if (!receiver_map->is_shared()) {
575ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org    Map::UpdateCodeCache(receiver_map, name, ic);
576ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  }
577ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
578ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  return ic;
579ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org}
580ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
581ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
582af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// TODO(verwaest): Change this method so it takes in a TypeHandleList.
583003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> StubCache::ComputeLoadElementPolymorphic(
584003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    MapHandleList* receiver_maps) {
585003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
586003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<PolymorphicCodeCache> cache =
587003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      isolate_->factory()->polymorphic_code_cache();
588003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Object> probe = cache->Lookup(receiver_maps, flags);
589003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (probe->IsCode()) return Handle<Code>::cast(probe);
590003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
591af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  TypeHandleList types(receiver_maps->length());
592af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  for (int i = 0; i < receiver_maps->length(); i++) {
593af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    types.Add(handle(Type::Class(receiver_maps->at(i)), isolate()));
594af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
5954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  CodeHandleList handlers(receiver_maps->length());
596003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  KeyedLoadStubCompiler compiler(isolate_);
5974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  compiler.CompileElementHandlers(receiver_maps, &handlers);
5984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Handle<Code> code = compiler.CompilePolymorphicIC(
599af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT);
6004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
6014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
6024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
603003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
604003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return code;
605003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
606003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
607003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
608cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgHandle<Code> StubCache::ComputePolymorphicIC(
609cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    TypeHandleList* types,
610cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    CodeHandleList* handlers,
611cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    int number_of_valid_types,
612cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    Handle<Name> name,
613cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ExtraICState extra_ic_state) {
614cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
615fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Handle<Code> handler = handlers->at(0);
616fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Code::Kind kind = handler->handler_kind();
617af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Code::StubType type = number_of_valid_types == 1 ? handler->type()
618af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org                                                   : Code::NORMAL;
619fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  if (kind == Code::LOAD_IC) {
620fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    LoadStubCompiler ic_compiler(isolate_);
621fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    return ic_compiler.CompilePolymorphicIC(
622af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org        types, handlers, name, type, PROPERTY);
623fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  } else {
624fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    ASSERT(kind == Code::STORE_IC);
625cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_ic_state);
626fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    StoreStubCompiler ic_compiler(isolate_, strict_mode);
627fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    return ic_compiler.CompilePolymorphicIC(
628af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org        types, handlers, name, type, PROPERTY);
629fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
630bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
631bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
632bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
633003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> StubCache::ComputeStoreElementPolymorphic(
634003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    MapHandleList* receiver_maps,
635750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    KeyedAccessStoreMode store_mode,
636003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    StrictModeFlag strict_mode) {
637750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  ASSERT(store_mode == STANDARD_STORE ||
6387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_AND_GROW_NO_TRANSITION ||
6397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
6407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org         store_mode == STORE_NO_TRANSITION_HANDLE_COW);
641003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<PolymorphicCodeCache> cache =
642003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      isolate_->factory()->polymorphic_code_cache();
643cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(
644cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      strict_mode, store_mode);
645003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Code::Flags flags =
646003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state);
647003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Object> probe = cache->Lookup(receiver_maps, flags);
648003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  if (probe->IsCode()) return Handle<Code>::cast(probe);
649003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
650ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  KeyedStoreStubCompiler compiler(isolate_, extra_state);
651003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps);
652003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
653003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return code;
654003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
655003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
656003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
65765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallDebugBreak(int argc,
659394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                              Code::Kind kind) {
66040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Extra IC state is irrelevant for debug break ICs. They jump to
66140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // the actual call ic to carry out the work.
662394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
6639768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_BREAK,
6647a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org                         Code::NORMAL, argc);
665f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
666f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
667394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
668394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
669394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
671394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallDebugBreak(flags);
672394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
678394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                                      Code::Kind kind) {
67940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Extra IC state is irrelevant for debug break ICs. They jump to
68040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // the actual call ic to carry out the work.
681394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Flags flags =
6829768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org      Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_PREPARE_STEP_IN,
6837a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org                         Code::NORMAL, argc);
684f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Handle<UnseededNumberDictionary> cache =
685f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com      isolate_->factory()->non_monomorphic_cache();
686394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int entry = cache->FindEntry(isolate_, flags);
687394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
688394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
689394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  StubCompiler compiler(isolate_);
690394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
691394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  FillCache(isolate_, code);
692394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
69465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid StubCache::Clear() {
698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < kPrimaryTableSize; i++) {
7007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    primary_[i].key = heap()->empty_string();
701bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    primary_[i].map = NULL;
702c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    primary_[i].value = empty;
70343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int j = 0; j < kSecondaryTableSize; j++) {
7057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    secondary_[j].key = heap()->empty_string();
706bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    secondary_[j].map = NULL;
707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    secondary_[j].value = empty;
70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
71143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
712ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.orgvoid StubCache::CollectMatchingMaps(SmallMapList* types,
71357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                    Handle<Name> name,
7147ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org                                    Code::Flags flags,
71546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                    Handle<Context> native_context,
7165a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                                    Zone* zone) {
717a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < kPrimaryTableSize; i++) {
71857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (primary_[i].key == *name) {
719750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Map* map = primary_[i].map;
720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Map can be NULL, if the stub is constant function call
721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // with a primitive receiver.
722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (map == NULL) continue;
723a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
72457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      int offset = PrimaryOffset(*name, flags, map);
7257ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      if (entry(primary_, offset) == &primary_[i] &&
72646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
72757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        types->AddMapIfMissing(Handle<Map>(map), zone);
728a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
729a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
730a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  for (int i = 0; i < kSecondaryTableSize; i++) {
73357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    if (secondary_[i].key == *name) {
734750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Map* map = secondary_[i].map;
735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Map can be NULL, if the stub is constant function call
736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // with a primitive receiver.
737a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      if (map == NULL) continue;
738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
739a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Lookup in primary table and skip duplicates.
74057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      int primary_offset = PrimaryOffset(*name, flags, map);
741a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
742a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      // Lookup in secondary table and add matches.
74357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      int offset = SecondaryOffset(*name, flags, primary_offset);
7447ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org      if (entry(secondary_, offset) == &secondary_[i] &&
74546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org          !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) {
74657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org        types->AddMapIfMissing(Handle<Map>(map), zone);
747a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      }
748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
749a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
750a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org}
751a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
752a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
75343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ------------------------------------------------------------------------
75443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// StubCompiler implementation.
75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
75643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
757c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
758c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  JSObject* recv = JSObject::cast(args[0]);
7597c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[1]);
7603b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  Address setter_address = v8::ToCData<Address>(callback->setter());
761662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  v8::AccessorSetterCallback fun =
762662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ASSERT(fun != NULL);
7647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ASSERT(callback->IsCompatibleReceiver(recv));
765750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name = args.at<Name>(2);
76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Handle<Object> value = args.at<Object>(3);
767ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
768750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
769750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
770750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (name->IsSymbol()) return *value;
771750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<String> str = Handle<String>::cast(name);
772750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
773ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  LOG(isolate, ApiNamedPropertyAccess("store", recv, *name));
774bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  PropertyCallbackArguments
775bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org      custom_args(isolate, callback->data(), recv, recv);
7761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
777ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return *value;
77943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
78043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
781b26c50a70863498de657ad44be2cffa49ccdcbeaager@chromium.org
7820b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org/**
7830b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * Attempts to load a property with an interceptor (which must be present),
7840b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * but doesn't search the prototype chain.
7850b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org *
7860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
7870b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * provide any value for the given name.
7880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org */
789c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
7904a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  ASSERT(args.length() == StubCache::kInterceptorArgsLength);
7914a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Handle<Name> name_handle =
7924a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args.at<Name>(StubCache::kInterceptorArgsNameIndex);
7934a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Handle<InterceptorInfo> interceptor_info =
7944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args.at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex);
7950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
796750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
797750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  if (name_handle->IsSymbol())
798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    return isolate->heap()->no_interceptor_result_sentinel();
799750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<String> name = Handle<String>::cast(name_handle);
800750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
802662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  v8::NamedPropertyGetterCallback getter =
803662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
8040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(getter != NULL);
80543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
806bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  Handle<JSObject> receiver =
8074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args.at<JSObject>(StubCache::kInterceptorArgsThisIndex);
808bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  Handle<JSObject> holder =
8094a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args.at<JSObject>(StubCache::kInterceptorArgsHolderIndex);
8104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  PropertyCallbackArguments callback_args(
8114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      isolate, interceptor_info->data(), *receiver, *holder);
8120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  {
8130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    // Use the interceptor getter.
814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
8151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> r =
8161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        callback_args.Call(getter, v8::Utils::ToLocal(name));
817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
8180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    if (!r.IsEmpty()) {
819de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      Handle<Object> result = v8::Utils::OpenHandle(*r);
820de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      result->VerifyApiCallResultType();
8210b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      return *v8::Utils::OpenHandle(*r);
8220b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
8230b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  }
82443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->no_interceptor_result_sentinel();
8260b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}
82743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
829750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgstatic MaybeObject* ThrowReferenceError(Isolate* isolate, Name* name) {
83043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If the load is non-contextual, just return the undefined result.
83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Note that both keyed and non-keyed loads may end up here, so we
83243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // can't use either LoadIC or KeyedLoadIC constructors.
833fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  HandleScope scope(isolate);
834c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  IC ic(IC::NO_EXTRA_FRAME, isolate);
835b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  ASSERT(ic.IsLoadStub());
836c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  if (!ic.SlowIsUndeclaredGlobal()) return isolate->heap()->undefined_value();
83743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Throw a reference error.
839750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Name> name_handle(name);
8400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Handle<Object> error =
841d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      isolate->factory()->NewReferenceError("not_defined",
842d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org                                            HandleVector(&name_handle, 1));
843c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  return isolate->Throw(*error);
8440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}
8450b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
8460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
847dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.orgstatic Handle<Object> LoadWithInterceptor(Arguments* args,
848dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org                                          PropertyAttributes* attrs) {
8494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  ASSERT(args->length() == StubCache::kInterceptorArgsLength);
8504a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Handle<Name> name_handle =
8514a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args->at<Name>(StubCache::kInterceptorArgsNameIndex);
8524a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Handle<InterceptorInfo> interceptor_info =
8534a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args->at<InterceptorInfo>(StubCache::kInterceptorArgsInfoIndex);
854bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  Handle<JSObject> receiver_handle =
8554a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args->at<JSObject>(StubCache::kInterceptorArgsThisIndex);
856bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  Handle<JSObject> holder_handle =
8574a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org      args->at<JSObject>(StubCache::kInterceptorArgsHolderIndex);
8580b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
859ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate = receiver_handle->GetIsolate();
860ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
861750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // TODO(rossberg): Support symbols in the API.
862dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (name_handle->IsSymbol()) {
863dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    return JSObject::GetPropertyPostInterceptor(
864dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org        holder_handle, receiver_handle, name_handle, attrs);
865dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  }
866750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<String> name = Handle<String>::cast(name_handle);
867750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
8680b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
869662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  v8::NamedPropertyGetterCallback getter =
870662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
8710b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ASSERT(getter != NULL);
8720b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
873bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  PropertyCallbackArguments callback_args(isolate,
874bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                          interceptor_info->data(),
875bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                          *receiver_handle,
876bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                          *holder_handle);
8773b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  {
878ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
879dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    // Use the interceptor getter.
8801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> r =
8811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        callback_args.Call(getter, v8::Utils::ToLocal(name));
882dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org    RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
8830b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    if (!r.IsEmpty()) {
8840b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org      *attrs = NONE;
885de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      Handle<Object> result = v8::Utils::OpenHandle(*r);
886de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      result->VerifyApiCallResultType();
887dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      return scope.CloseAndEscape(result);
8880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org    }
8893b45ab59f57a3f7a11fdc5278839a881780cb9cbager@chromium.org  }
8900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
891dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<Object> result = JSObject::GetPropertyPostInterceptor(
892dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org      holder_handle, receiver_handle, name_handle, attrs);
8930b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  return result;
8940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}
8950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
8960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
8970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org/**
8980b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * Loads a property with an interceptor performing post interceptor
8990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * lookup if interceptor failed.
9000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org */
901c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
9020b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  PropertyAttributes attr = NONE;
903dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  HandleScope scope(isolate);
904dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<Object> result = LoadWithInterceptor(&args, &attr);
905dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
9060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
9070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // If the property is present, return it.
908dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  if (attr != ABSENT) return *result;
909750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return ThrowReferenceError(isolate, Name::cast(args[0]));
9100b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}
9110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
9120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org
913c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
9140b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  PropertyAttributes attr;
915dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  HandleScope scope(isolate);
916dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  Handle<Object> result = LoadWithInterceptor(&args, &attr);
917dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
9180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // This is call IC. In this case, we simply return the undefined result which
9190b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // will lead to an exception when trying to invoke the result as a
9200b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // function.
921dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org  return *result;
92243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
92443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
925c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
926528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HandleScope scope(isolate);
927cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ASSERT(args.length() == 3);
928cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
929cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  Handle<JSObject> receiver = args.at<JSObject>(0);
930cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  Handle<Name> name = args.at<Name>(1);
931cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  Handle<Object> value = args.at<Object>(2);
932cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ASSERT(receiver->HasNamedInterceptor());
93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  PropertyAttributes attr = NONE;
934528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Object> result = JSObject::SetPropertyWithInterceptor(
935cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      receiver, name, value, attr, ic.strict_mode());
936528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  RETURN_IF_EMPTY_HANDLE(isolate, result);
937528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  return *result;
93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
941c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
9425c838251403b0be9a882540f1922577abba4c872ager@chromium.org  JSObject* receiver = JSObject::cast(args[0]);
9436d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  ASSERT(args.smi_at(1) >= 0);
9446d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  uint32_t index = args.smi_at(1);
9455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return receiver->GetElementWithInterceptor(receiver, index);
9465c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
9475c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
949394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = Code::ExtractArgumentsCountFromFlags(flags);
9511af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
952cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
9531af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (kind == Code::CALL_IC) {
954394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallIC::GenerateInitialize(masm(), argc, extra_state);
9551af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  } else {
9561af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    KeyedCallIC::GenerateInitialize(masm(), argc);
9571af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
958394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize");
9597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->call_initialize_stubs()->Increment();
960ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
961ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
962394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
963394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
964394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
96743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
968394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = Code::ExtractArgumentsCountFromFlags(flags);
970e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // The code of the PreMonomorphic stub is the same as the code
971e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // of the Initialized stub.  They just differ on the code object flags.
9721af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
973cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
9741af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (kind == Code::CALL_IC) {
975394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallIC::GenerateInitialize(masm(), argc, extra_state);
9761af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  } else {
9771af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    KeyedCallIC::GenerateInitialize(masm(), argc);
9781af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
979394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
9807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->call_premonomorphic_stubs()->Increment();
981ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
982ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
983394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
984394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
985394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
98643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
98743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
98843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
989394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = Code::ExtractArgumentsCountFromFlags(flags);
9911af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
9921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (kind == Code::CALL_IC) {
99340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // Call normal is always with a explict receiver.
99440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    ASSERT(!CallIC::Contextual::decode(
99540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org        Code::ExtractExtraICStateFromFlags(flags)));
9961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    CallIC::GenerateNormal(masm(), argc);
9971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  } else {
9981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    KeyedCallIC::GenerateNormal(masm(), argc);
9991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
1000394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
10017979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->call_normal_stubs()->Increment();
1002ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
1003ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1004394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
1005394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
1006394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1010394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
101143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = Code::ExtractArgumentsCountFromFlags(flags);
10121af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1013cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
10141af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (kind == Code::CALL_IC) {
1015394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallIC::GenerateMegamorphic(masm(), argc, extra_state);
10161af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  } else {
10171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    KeyedCallIC::GenerateMegamorphic(masm(), argc);
10181af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
1019394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
10207979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  isolate()->counters()->call_megamorphic_stubs()->Increment();
1021ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
1022ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1023394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
1024394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1025394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
10267b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
10277b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
10287b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org
1029394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
10307b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  int argc = Code::ExtractArgumentsCountFromFlags(flags);
10317b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
1032394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
1033394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  PROFILE(isolate(),
1034394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1035394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                          CALL_MEGAMORPHIC_TAG),
1036394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
1037394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1038394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
1039394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1040394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1041394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1042394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1043394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int argc = Code::ExtractArgumentsCountFromFlags(flags);
10447b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
1045cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1046394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (kind == Code::CALL_IC) {
1047394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallIC::GenerateMiss(masm(), argc, extra_state);
1048394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  } else {
1049394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    KeyedCallIC::GenerateMiss(masm(), argc);
10507b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
1051394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss");
1052394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  isolate()->counters()->call_megamorphic_stubs()->Increment();
10537b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  PROFILE(isolate(),
1054394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1055394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
1056394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
1057394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
1062394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
10638bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  Debug::GenerateCallICDebugBreak(masm());
1064394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
1065ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
1066394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1067394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                          CALL_DEBUG_BREAK_TAG),
1068394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                          *code, code->arguments_count()));
1069394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1073394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1074394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Use the same code for the the step in preparations as we do for the
1075394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // miss case.
107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = Code::ExtractArgumentsCountFromFlags(flags);
10771af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  Code::Kind kind = Code::ExtractKindFromFlags(flags);
10781af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  if (kind == Code::CALL_IC) {
107940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // For the debugger extra ic state is irrelevant.
1080cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    CallIC::GenerateMiss(masm(), argc, kNoExtraICState);
10811af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  } else {
10821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    KeyedCallIC::GenerateMiss(masm(), argc);
10831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
1084394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1085ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  PROFILE(isolate(),
1086ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          CodeCreateEvent(
1087ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1088394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              *code,
1089ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org              code->arguments_count()));
1090394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
1092394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#endif  // ENABLE_DEBUGGER_SUPPORT
109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#undef CALL_LOGGER_TAG
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1096394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1097394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1098303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            const char* name) {
1099394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Create code object in the heap.
1100394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  CodeDesc desc;
1101394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  masm_.GetCode(&desc);
1102394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1103aafe5810a82411878a83bbf65e492fa19d152226jkummerow@chromium.org  if (code->has_major_key()) {
1104aafe5810a82411878a83bbf65e492fa19d152226jkummerow@chromium.org    code->set_major_key(CodeStub::NoCache);
1105aafe5810a82411878a83bbf65e492fa19d152226jkummerow@chromium.org  }
1106394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#ifdef ENABLE_DISASSEMBLER
1107b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  if (FLAG_print_code_stubs) code->Disassemble(name);
1108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#endif
1109394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return code;
1110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1111394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1112394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1113394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1114750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                            Handle<Name> name) {
1115750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
1116750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString())
1117ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org      : GetCodeWithFlags(flags, NULL);
1118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1121c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
1122750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                         Handle<Name> name,
1123c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                         LookupResult* lookup) {
1124c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  holder->LocalLookupRealNamedProperty(*name, lookup);
1125753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org  if (lookup->IsFound()) return;
1126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (holder->GetPrototype()->IsNull()) return;
1127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  holder->GetPrototype()->Lookup(*name, lookup);
1128b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1129b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1130b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
113194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#define __ ACCESS_MASM(masm())
113294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
113394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
11348a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgCallKind CallStubCompiler::call_kind() {
1135ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  return CallICBase::Contextual::decode(extra_state())
11368a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org      ? CALL_AS_FUNCTION
11378a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org      : CALL_AS_METHOD;
11388a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
11398a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11408a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
1141cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgvoid CallStubCompiler::HandlerFrontendFooter(Label* miss) {
1142cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  __ bind(miss);
1143cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  GenerateMissBranch();
1144cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org}
1145cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
1146cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
11478a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateJumpFunctionIgnoreReceiver(
11488a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<JSFunction> function) {
11498a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  ParameterCount expected(function);
11508a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  __ InvokeFunction(function, expected, arguments(),
11518a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                    JUMP_FUNCTION, NullCallWrapper(), call_kind());
11528a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
11538a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11548a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11558a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
11568a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                            Handle<JSFunction> function) {
11578a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  PatchGlobalProxy(object);
11588a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  GenerateJumpFunctionIgnoreReceiver(function);
11598a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
11608a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11618a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11628a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
11638a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                            Register actual_closure,
11648a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                            Handle<JSFunction> function) {
11658a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  PatchGlobalProxy(object);
11668a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  ParameterCount expected(function);
11678a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  __ InvokeFunction(actual_closure, expected, arguments(),
11688a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                    JUMP_FUNCTION, NullCallWrapper(), call_kind());
11698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
11708a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11718a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11728a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgHandle<Code> CallStubCompiler::CompileCallConstant(
11738a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<Object> object,
11748a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<JSObject> holder,
11758a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<Name> name,
11768a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    CheckType check,
11778a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<JSFunction> function) {
11788a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  if (HasCustomCallGenerator(function)) {
11798a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    Handle<Code> code = CompileCustomCall(object, holder,
11808a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                          Handle<Cell>::null(),
11818a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                          function, Handle<String>::cast(name),
11828a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                                          Code::FAST);
11838a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    // A null handle means bail out to the regular compiler code below.
11848a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org    if (!code.is_null()) return code;
11858a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  }
11868a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11878a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  Label miss;
11888a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  HandlerFrontendHeader(object, holder, name, check, &miss);
11898a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  GenerateJumpFunction(object, function);
11908a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  HandlerFrontendFooter(&miss);
11918a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11928a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  // Return the generated code.
11938a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  return GetCode(function);
11948a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org}
11958a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11968a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
11972efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgRegister LoadStubCompiler::HandlerFrontendHeader(
1198f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
1199bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Register object_reg,
1200bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<JSObject> holder,
1201bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Name> name,
1202bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Label* miss) {
1203b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  PrototypeCheckType check_type = CHECK_ALL_MAPS;
1204b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  int function_index = -1;
1205f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (type->Is(Type::String())) {
1206f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    function_index = Context::STRING_FUNCTION_INDEX;
1207f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  } else if (type->Is(Type::Symbol())) {
1208f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    function_index = Context::SYMBOL_FUNCTION_INDEX;
1209f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  } else if (type->Is(Type::Number())) {
1210f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    function_index = Context::NUMBER_FUNCTION_INDEX;
1211f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  } else if (type->Is(Type::Boolean())) {
1212f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Booleans use the generic oddball map, so an additional check is needed to
1213f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // ensure the receiver is really a boolean.
1214f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    GenerateBooleanCheck(object_reg, miss);
1215f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    function_index = Context::BOOLEAN_FUNCTION_INDEX;
1216b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  } else {
1217f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    check_type = SKIP_RECEIVER;
1218f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
1219b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1220f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (check_type == CHECK_ALL_MAPS) {
1221b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    GenerateDirectLoadGlobalFunctionPrototype(
1222b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org        masm(), function_index, scratch1(), miss);
1223f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Object* function = isolate()->native_context()->get(function_index);
1224f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Object* prototype = JSFunction::cast(function)->instance_prototype();
1225f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate());
1226b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    object_reg = scratch1();
1227b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
1228b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1229b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Check that the maps starting from the prototype haven't changed.
1230f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return CheckPrototypes(
1231f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      type, object_reg, holder, scratch1(), scratch2(), scratch3(),
1232f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      name, miss, check_type);
12338432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
12348432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
12358432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1236bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// HandlerFrontend for store uses the name register. It has to be restored
1237bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// before a miss.
12382efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgRegister StoreStubCompiler::HandlerFrontendHeader(
1239f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
1240bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Register object_reg,
1241bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<JSObject> holder,
1242bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Name> name,
1243bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Label* miss) {
1244f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return CheckPrototypes(type, object_reg, holder, this->name(),
1245f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                         scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
1246bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
1247bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
1248bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
1249af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgbool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) {
1250af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  for (int i = 0; i < types->length(); ++i) {
1251af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (types->at(i)->Is(Type::Number())) return true;
1252b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
1253b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  return false;
1254b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org}
1255b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1256b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
1257f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgRegister BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type,
1258bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                    Register object_reg,
1259bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                    Handle<JSObject> holder,
1260b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                                    Handle<Name> name) {
12618432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Label miss;
12628432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1263f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
12648432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1265b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HandlerFrontendFooter(name, &miss);
1266b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
12678432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  return reg;
12688432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
12698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
12708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1271f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type,
1272f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                                  Handle<JSObject> last,
1273f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                                  Handle<Name> name) {
1274057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Label miss;
1275057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1276f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Register holder;
1277f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Map> last_map;
1278f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (last.is_null()) {
1279f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    holder = receiver();
1280f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    last_map = IC::TypeToMap(*type, isolate());
1281f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // If |type| has null as its prototype, |last| is Handle<JSObject>::null().
1282f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    ASSERT(last_map->prototype() == isolate()->heap()->null_value());
1283f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  } else {
1284f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    holder = HandlerFrontendHeader(type, receiver(), last, name, &miss);
1285f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    last_map = handle(last->map());
1286f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
1287057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1288f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (last_map->is_dictionary_map() &&
1289f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      !last_map->IsJSGlobalObjectMap() &&
1290f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      !last_map->IsJSGlobalProxyMap()) {
1291057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    if (!name->IsUniqueName()) {
1292057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      ASSERT(name->IsString());
1293057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org      name = factory()->InternalizeString(Handle<String>::cast(name));
1294057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    }
1295f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    ASSERT(last.is_null() ||
1296f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org           last->property_dictionary()->FindEntry(*name) ==
1297f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org               NameDictionary::kNotFound);
1298057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    GenerateDictionaryNegativeLookup(masm(), &miss, holder, name,
1299057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org                                     scratch2(), scratch3());
1300057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
1301057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1302057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // If the last object in the prototype chain is a global object,
1303057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // check that the global property cell is empty.
1304f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (last_map->IsJSGlobalObjectMap()) {
1305f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<JSGlobalObject> global = last.is_null()
1306f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        ? Handle<JSGlobalObject>::cast(type->AsConstant())
1307f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        : Handle<JSGlobalObject>::cast(last);
1308057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1309057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  }
1310057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1311b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  HandlerFrontendFooter(name, &miss);
1312057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org}
1313057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
1314057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org
13152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadField(
1316f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
131757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Handle<JSObject> holder,
131857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Handle<Name> name,
131957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    PropertyIndex field,
132057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Representation representation) {
13214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  Label miss;
13224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
1323f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss);
13244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
132557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  GenerateLoadField(reg, holder, field, representation);
13264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
13274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ bind(&miss);
13282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  TailCallBuiltin(masm(), MissBuiltin(kind()));
132994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
133094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // Return the generated code.
13319af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
133294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
133394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
133494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
13352efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadConstant(
1336f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
133794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Handle<JSObject> holder,
1338750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name,
1339fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    Handle<Object> value) {
1340f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HandlerFrontend(type, receiver(), holder, name);
13418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  GenerateLoadConstant(value);
134294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
134394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // Return the generated code.
13449af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
134594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
134694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
134794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
13482efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadCallback(
1349f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
135094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Handle<JSObject> holder,
1351750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name,
13528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Handle<ExecutableAccessorInfo> callback) {
13538432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Register reg = CallbackHandlerFrontend(
1354f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      type, receiver(), holder, name, callback);
13558432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  GenerateLoadCallback(reg, callback);
135694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
135794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // Return the generated code.
13589af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
135994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
136094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
136194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
13622efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadCallback(
1363f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
13642c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org    Handle<JSObject> holder,
13652c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org    Handle<Name> name,
13662c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org    const CallOptimization& call_optimization) {
13672c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  ASSERT(call_optimization.is_simple_api_call());
13682c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  Handle<JSFunction> callback = call_optimization.constant_function();
1369f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  CallbackHandlerFrontend(type, receiver(), holder, name, callback);
13702c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  GenerateLoadCallback(call_optimization);
13712c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
13722c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org  // Return the generated code.
13739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
13742c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org}
13752c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
13762c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org
13772efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadInterceptor(
1378f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
137994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org    Handle<JSObject> holder,
1380750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name) {
138194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  LookupResult lookup(isolate());
138294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  LookupPostInterceptor(holder, name, &lookup);
138394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
1384f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Register reg = HandlerFrontend(type, receiver(), holder, name);
138594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // TODO(368): Compile in the whole chain: all the interceptors in
138694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // prototypes and ultimate answer.
1387f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  GenerateLoadInterceptor(reg, type, holder, &lookup, name);
138894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
138994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  // Return the generated code.
13909af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
139194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org}
139294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
139394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
13942efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadPostInterceptor(
13958432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Register interceptor_reg,
13968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Handle<JSObject> interceptor_holder,
1397750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name,
13988432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    LookupResult* lookup) {
13998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  Handle<JSObject> holder(lookup->holder());
14008432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  if (lookup->IsField()) {
14014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    PropertyIndex field = lookup->GetFieldIndex();
14024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    if (interceptor_holder.is_identical_to(holder)) {
140357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      GenerateLoadField(
140457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          interceptor_reg, holder, field, lookup->representation());
14054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    } else {
14064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // We found FIELD property in prototype chain of interceptor's holder.
14074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      // Retrieve a field from field's holder.
14084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      Register reg = HandlerFrontend(
1409f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org          IC::CurrentTypeOf(interceptor_holder, isolate()),
1410f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org          interceptor_reg, holder, name);
141157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      GenerateLoadField(
141257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org          reg, holder, field, lookup->representation());
14134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    }
14148432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  } else {
14158432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    // We found CALLBACKS property in prototype chain of interceptor's
14168432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    // holder.
14178432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    ASSERT(lookup->type() == CALLBACKS);
14188432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Handle<ExecutableAccessorInfo> callback(
14198432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org        ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
14208432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    ASSERT(callback->getter() != NULL);
14218432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
14228432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Register reg = CallbackHandlerFrontend(
1423f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        IC::CurrentTypeOf(interceptor_holder, isolate()),
1424f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        interceptor_reg, holder, name, callback);
14258432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    GenerateLoadCallback(reg, callback);
14268432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  }
14278432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
14288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
14298432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
1430bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC(
1431af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    Handle<Type> type,
14324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    Handle<Code> handler,
1433750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name) {
1434af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  TypeHandleList types(1);
14354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  CodeHandleList handlers(1);
1436af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  types.Add(type);
14374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  handlers.Add(handler);
1438af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  Code::StubType stub_type = handler->type();
1439af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY);
14404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
14414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
14438432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadViaGetter(
1444f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Handle<Type> type,
14458432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Handle<JSObject> holder,
1446750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org    Handle<Name> name,
14478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    Handle<JSFunction> getter) {
1448f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HandlerFrontend(type, receiver(), holder, name);
14492efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  GenerateLoadViaGetter(masm(), receiver(), getter);
14508432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
14518432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // Return the generated code.
14529af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
14538432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org}
14548432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
14558432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org
14562efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> StoreStubCompiler::CompileStoreTransition(
1457e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<JSObject> object,
1458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    LookupResult* lookup,
1459e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Map> transition,
1460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Handle<Name> name) {
1461bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Label miss, slow;
1462bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
1463bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Ensure no transitions to deprecated maps are followed.
1464bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  __ CheckMapDeprecated(transition, scratch1(), &miss);
1465bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
1466bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Check that we are allowed to write this.
1467bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (object->GetPrototype()->IsJSObject()) {
1468bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<JSObject> holder;
1469bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // holder == object indicates that no property was found.
1470bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    if (lookup->holder() != *object) {
1471bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      holder = Handle<JSObject>(lookup->holder());
1472bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    } else {
1473bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      // Find the top object.
1474bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      holder = object;
1475bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      do {
1476bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype()));
1477bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      } while (holder->GetPrototype()->IsJSObject());
1478bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    }
1479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1480f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Register holder_reg = HandlerFrontendHeader(
1481f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        IC::CurrentTypeOf(object, isolate()), receiver(), holder, name, &miss);
1482bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
1483bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // If no property was found, and the holder (the last object in the
1484bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // prototype chain) is in slow mode, we need to do a negative lookup on the
1485bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    // holder.
1486bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    if (lookup->holder() == *object) {
1487bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss);
1488bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    }
1489bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
1490e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1491e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  GenerateStoreTransition(masm(),
1492e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          object,
1493e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          lookup,
1494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          transition,
1495e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          name,
1496e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          receiver(), this->name(), value(),
149757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                          scratch1(), scratch2(), scratch3(),
1498e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                          &miss,
149957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                          &slow);
1500e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1501e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Handle store cache miss.
1502bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  GenerateRestoreName(masm(), &miss, name);
1503e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  TailCallBuiltin(masm(), MissBuiltin(kind()));
1504e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
150557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  GenerateRestoreName(masm(), &slow, name);
150657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  TailCallBuiltin(masm(), SlowBuiltin(kind()));
150757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
1508e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Return the generated code.
15099af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
1510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
1511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
15132efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
15142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                                  LookupResult* lookup,
15152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                                  Handle<Name> name) {
1516e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  Label miss;
15172bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
1518f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HandlerFrontendHeader(IC::CurrentTypeOf(object, isolate()),
1519f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                        receiver(), object, name, &miss);
15202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Generate store field code.
15222bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  GenerateStoreField(masm(),
15232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                     object,
1524f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                     lookup,
15252bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                     receiver(), this->name(), value(), scratch1(), scratch2(),
1526e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                     &miss);
15272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Handle store cache miss.
15292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  __ bind(&miss);
15302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  TailCallBuiltin(masm(), MissBuiltin(kind()));
15312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Return the generated code.
15339af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
15342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
15352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgHandle<Code> StoreStubCompiler::CompileStoreViaSetter(
15382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<JSObject> object,
15392bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<JSObject> holder,
1540bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Name> name,
15412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<JSFunction> setter) {
1542f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
1543f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                  receiver(), holder, name);
15442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  GenerateStoreViaSetter(masm(), setter);
15452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
15472bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
15482bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15492bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgHandle<Code> KeyedLoadStubCompiler::CompileLoadElement(
15512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<Map> receiver_map) {
15522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ElementsKind elements_kind = receiver_map->elements_kind();
15532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  if (receiver_map->has_fast_elements() ||
15542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org      receiver_map->has_external_array_elements()) {
15552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<Code> stub = KeyedLoadFastElementStub(
15562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org        receiver_map->instance_type() == JS_ARRAY_TYPE,
15572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org        elements_kind).GetCode(isolate());
15582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
15592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  } else {
1560ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    Handle<Code> stub = FLAG_compiled_keyed_dictionary_loads
1561ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        ? KeyedLoadDictionaryElementStub().GetCode(isolate())
1562ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org        : KeyedLoadDictionaryElementPlatformStub().GetCode(isolate());
15632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
15642bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  }
15652bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15662bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
15672bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Return the generated code.
15692bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
15702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
15712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15722bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15732bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgHandle<Code> KeyedStoreStubCompiler::CompileStoreElement(
15742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    Handle<Map> receiver_map) {
15752bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  ElementsKind elements_kind = receiver_map->elements_kind();
15762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
15777bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  Handle<Code> stub;
157832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  if (receiver_map->has_fast_elements() ||
157932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      receiver_map->has_external_array_elements()) {
15807bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    stub = KeyedStoreFastElementStub(
15817bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org        is_jsarray,
15827bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org        elements_kind,
1583ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        store_mode()).GetCode(isolate());
15847bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  } else {
15857bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org    stub = KeyedStoreElementStub(is_jsarray,
15867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org                                 elements_kind,
1587ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                                 store_mode()).GetCode(isolate());
15887bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  }
15892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15902bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
15912bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
15932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Return the generated code.
15952bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
15962bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
15972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
15982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
159994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org#undef __
160094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
160194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
16022bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) {
16032bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Handle<Code> code(masm->isolate()->builtins()->builtin(name));
16042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  GenerateTailCall(masm, code);
16052bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
16062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid BaseLoadStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
16092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#ifdef ENABLE_GDB_JIT_INTERFACE
16102efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  GDBJITInterface::CodeTag tag;
16112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  if (kind_ == Code::LOAD_IC) {
16122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    tag = GDBJITInterface::LOAD_IC;
16132efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else if (kind_ == Code::KEYED_LOAD_IC) {
16142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    tag = GDBJITInterface::KEYED_LOAD_IC;
16152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else if (kind_ == Code::STORE_IC) {
16162efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    tag = GDBJITInterface::STORE_IC;
16172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else {
16182efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    tag = GDBJITInterface::KEYED_STORE_IC;
16192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
16202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  GDBJIT(AddCode(tag, *name, *code));
16212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#endif
16222bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
16232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid BaseLoadStoreStubCompiler::InitializeRegisters() {
16262efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  if (kind_ == Code::LOAD_IC) {
16272efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    registers_ = LoadStubCompiler::registers();
16282efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else if (kind_ == Code::KEYED_LOAD_IC) {
16292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    registers_ = KeyedLoadStubCompiler::registers();
16302efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else if (kind_ == Code::STORE_IC) {
16312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    registers_ = StoreStubCompiler::registers();
16322efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  } else {
16332efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    registers_ = KeyedStoreStubCompiler::registers();
16342efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
16352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
16362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
1638bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind,
1639bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                  Code::StubType type,
1640bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                  Handle<Name> name,
1641bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org                                                  InlineCacheState state) {
1642fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Code::Flags flags = Code::ComputeFlags(kind, state, extra_state(), type);
1643750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Handle<Code> code = GetCodeWithFlags(flags, name);
1644750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
1645750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  JitEvent(name, code);
1646750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  return code;
1647750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org}
1648750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1649750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1650fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::GetCode(Code::Kind kind,
1651fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                                Code::StubType type,
1652fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                                Handle<Name> name) {
16532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Code::Flags flags = Code::ComputeFlags(
1654b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org      Code::HANDLER, MONOMORPHIC, extra_state(), type, kind, cache_holder_);
16552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  Handle<Code> code = GetCodeWithFlags(flags, name);
16562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
16572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  JitEvent(name, code);
16582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  return code;
16592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
16602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16612bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
16624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
16634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                                                   CodeHandleList* handlers) {
1664003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < receiver_maps->length(); ++i) {
1665003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    Handle<Map> receiver_map = receiver_maps->at(i);
1666003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    Handle<Code> cached_stub;
1667003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1668003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1669003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      cached_stub = isolate()->builtins()->KeyedLoadIC_String();
1670598f48de485c6cdf471e922b633e724e65d09af6ulan@chromium.org    } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1671598f48de485c6cdf471e922b633e724e65d09af6ulan@chromium.org      cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
1672003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    } else {
1673003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1674003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      ElementsKind elements_kind = receiver_map->elements_kind();
1675003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1676003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      if (IsFastElementsKind(elements_kind) ||
1677003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org          IsExternalArrayElementsKind(elements_kind)) {
1678003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        cached_stub =
16798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org            KeyedLoadFastElementStub(is_js_array,
16808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org                                     elements_kind).GetCode(isolate());
1681003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      } else {
1682003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        ASSERT(elements_kind == DICTIONARY_ELEMENTS);
16838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org        cached_stub = KeyedLoadDictionaryElementStub().GetCode(isolate());
1684003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      }
1685003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1686003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
16874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    handlers->Add(cached_stub);
1688003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1689003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1690003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1691003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1692003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
1693003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    MapHandleList* receiver_maps) {
1694003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Collect MONOMORPHIC stubs for all |receiver_maps|.
16954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  CodeHandleList handlers(receiver_maps->length());
1696003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  MapHandleList transitioned_maps(receiver_maps->length());
1697003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  for (int i = 0; i < receiver_maps->length(); ++i) {
1698003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    Handle<Map> receiver_map(receiver_maps->at(i));
1699003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    Handle<Code> cached_stub;
1700003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    Handle<Map> transitioned_map =
1701003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org        receiver_map->FindTransitionedMap(receiver_maps);
1702003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1703003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // TODO(mvstanton): The code below is doing pessimistic elements
1704003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // transitions. I would like to stop doing that and rely on Allocation Site
1705003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // Tracking to do a better job of ensuring the data types are what they need
1706003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // to be. Not all the elements are in place yet, pessimistic elements
1707003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    // transitions are still important for performance.
1708003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1709003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    ElementsKind elements_kind = receiver_map->elements_kind();
1710003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    if (!transitioned_map.is_null()) {
1711d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      cached_stub = ElementsTransitionAndStoreStub(
1712d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          elements_kind,
1713d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          transitioned_map->elements_kind(),
1714d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org          is_js_array,
1715ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org          store_mode()).GetCode(isolate());
1716598f48de485c6cdf471e922b633e724e65d09af6ulan@chromium.org    } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
1717598f48de485c6cdf471e922b633e724e65d09af6ulan@chromium.org      cached_stub = isolate()->builtins()->KeyedStoreIC_Slow();
1718003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    } else {
171932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org      if (receiver_map->has_fast_elements() ||
172032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org          receiver_map->has_external_array_elements()) {
17217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org        cached_stub = KeyedStoreFastElementStub(
17227bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org            is_js_array,
17237bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org            elements_kind,
1724ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org            store_mode()).GetCode(isolate());
17257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      } else {
17267bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org        cached_stub = KeyedStoreElementStub(
17277bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org            is_js_array,
17287bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org            elements_kind,
1729ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org            store_mode()).GetCode(isolate());
17307bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      }
1731003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    }
1732003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    ASSERT(!cached_stub.is_null());
17334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    handlers.Add(cached_stub);
1734003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    transitioned_maps.Add(transitioned_map);
1735003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
1736003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> code =
17374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps);
1738003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1739003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  PROFILE(isolate(),
1740003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org          CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0));
1741003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  return code;
1742003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org}
1743003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
1744003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
17456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
17466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org    MacroAssembler* masm) {
17476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  KeyedStoreIC::GenerateSlow(masm);
17486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org}
17496d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
17506d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comCallStubCompiler::CallStubCompiler(Isolate* isolate,
1752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   int argc,
175369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                                   Code::Kind kind,
1754cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                   ExtraICState extra_state,
175569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org                                   InlineCacheHolderFlag cache_holder)
1756ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    : StubCompiler(isolate, extra_state),
1757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      arguments_(argc),
17580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      kind_(kind),
17590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com      cache_holder_(cache_holder) {
176069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
176169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
176269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
1763c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgbool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) {
1764c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (function->shared()->HasBuiltinFunctionId()) {
1765c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    BuiltinFunctionId id = function->shared()->builtin_function_id();
17665f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1767ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
17685f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org#undef CALL_GENERATOR_CASE
1769ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
1770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1771ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CallOptimization optimization(function);
1772c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  return optimization.is_simple_api_call();
17735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org}
17745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
17755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
17761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgbool CallStubCompiler::CanBeCached(Handle<JSFunction> function) {
17771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (function->shared()->HasBuiltinFunctionId()) {
17781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    BuiltinFunctionId id = function->shared()->builtin_function_id();
17791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#define CALL_GENERATOR_CASE(name) if (id == k##name) return false;
17801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    SITE_SPECIFIC_CALL_GENERATORS(CALL_GENERATOR_CASE)
17811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#undef CALL_GENERATOR_CASE
17821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
17831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
17841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return true;
17851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
17861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
17871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
1788c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileCustomCall(
1789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<Object> object,
1790c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<JSObject> holder,
179141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Cell> cell,
1792c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<JSFunction> function,
17931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<String> fname,
17941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Code::StubType type) {
1795ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(HasCustomCallGenerator(function));
1796ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1797c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (function->shared()->HasBuiltinFunctionId()) {
1798c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    BuiltinFunctionId id = function->shared()->builtin_function_id();
1799c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#define CALL_GENERATOR_CASE(name)                               \
1800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    if (id == k##name) {                                        \
1801c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      return CallStubCompiler::Compile##name##Call(object,      \
1802c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                   holder,      \
1803c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                   cell,        \
1804c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                                   function,    \
18051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                   fname,       \
18061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                                   type);       \
1807ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
1808ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1809720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org#undef CALL_GENERATOR_CASE
1810ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
1811ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CallOptimization optimization(function);
1812ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ASSERT(optimization.is_simple_api_call());
1813ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return CompileFastApiCall(optimization,
1814ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            object,
1815ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            holder,
1816ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            cell,
1817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            function,
1818ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                            fname);
1819720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org}
1820720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
1821720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
18227a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgHandle<Code> CallStubCompiler::GetCode(Code::StubType type,
1823750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                       Handle<Name> name) {
182443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int argc = arguments_.immediate();
1825b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Code::Flags flags = Code::ComputeMonomorphicFlags(
1826ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      kind_, extra_state(), cache_holder_, type, argc);
18277be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org  return GetCodeWithFlags(flags, name);
182843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
182943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
183043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1831394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
1832394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<String> function_name;
1833394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  if (function->shared()->name()->IsString()) {
1834394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    function_name = Handle<String>(String::cast(function->shared()->name()));
1835394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
18369af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(Code::FAST, function_name);
1837394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
1838394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1839394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
18404111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.orgCallOptimization::CallOptimization(LookupResult* lookup) {
184105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  if (lookup->IsFound() &&
184205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org      lookup->IsCacheable() &&
1843fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org      lookup->IsConstantFunction()) {
18444111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    // We only optimize constant function calls.
1845c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
184605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  } else {
184705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    Initialize(Handle<JSFunction>::null());
18484111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
18494111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
18504111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
1851e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1852c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgCallOptimization::CallOptimization(Handle<JSFunction> function) {
18534111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  Initialize(function);
18544111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
18554111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18564111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
1857c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgint CallOptimization::GetPrototypeDepthOfExpectedType(
1858c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<JSObject> object,
1859c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<JSObject> holder) const {
1860c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ASSERT(is_simple_api_call());
1861c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (expected_receiver_type_.is_null()) return 0;
18624111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  int depth = 0;
1863c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  while (!object.is_identical_to(holder)) {
18649af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org    if (expected_receiver_type_->IsTemplateFor(object->map())) return depth;
1865c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
186649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (!object->map()->is_hidden_prototype()) return kInvalidProtoDepth;
18674111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    ++depth;
18684111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
18699af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  if (expected_receiver_type_->IsTemplateFor(holder->map())) return depth;
18704111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  return kInvalidProtoDepth;
18714111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
18724111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18734111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
1874c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid CallOptimization::Initialize(Handle<JSFunction> function) {
1875c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  constant_function_ = Handle<JSFunction>::null();
18764111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  is_simple_api_call_ = false;
1877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
1878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  api_call_info_ = Handle<CallHandlerInfo>::null();
18794111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
1880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (function.is_null() || !function->is_compiled()) return;
18814111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18824111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  constant_function_ = function;
18834111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  AnalyzePossibleApiFunction(function);
18844111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
18854111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18864111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
1887c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
1888c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (!function->shared()->IsApiFunction()) return;
1889c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
18904111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18914111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // Require a C++ callback.
18924111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (info->call_code()->IsUndefined()) return;
1893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  api_call_info_ =
1894c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
18954111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
18964111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // Accept signatures that either have no restrictions at all or
18974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  // only have restrictions on the receiver.
18984111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  if (!info->signature()->IsUndefined()) {
1899c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    Handle<SignatureInfo> signature =
1900c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
19014111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    if (!signature->args()->IsUndefined()) return;
19024111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    if (!signature->receiver()->IsUndefined()) {
19034111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org      expected_receiver_type_ =
1904c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          Handle<FunctionTemplateInfo>(
1905c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org              FunctionTemplateInfo::cast(signature->receiver()));
19064111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org    }
19074111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  }
19084111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
19094111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org  is_simple_api_call_ = true;
19104111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org}
19114111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
19124111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
191343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
1914