13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arguments.h"
3269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "ast.h"
333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "code-stubs.h"
34b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "stub-cache.h"
37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h"
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StubCache implementation.
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStubCache::StubCache(Isolate* isolate) : isolate_(isolate) {
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(isolate == Isolate::Current());
4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StubCache::Initialize() {
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsPowerOf2(kPrimaryTableSize));
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsPowerOf2(kSecondaryTableSize));
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Clear();
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCode* StubCache::Set(String* name, Map* map, Code* code) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the flags from the code.
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::RemoveTypeFromFlags(code->flags());
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Validate that the name does not move on scavenge, and that we
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can use identity checks instead of string equality checks.
6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!heap()->InNewSpace(name));
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(name->IsSymbol());
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The state bits are not important to the hash function because
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the stub cache only contains monomorphic stubs. Make sure that
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the bits are the least significant so they will be the ones
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // masked out.
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC);
72589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1);
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure that the code type is not included in the hash.
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the primary entry.
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int primary_offset = PrimaryOffset(name, flags, map);
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Entry* primary = entry(primary_, primary_offset);
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code* old_code = primary->value;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the primary entry has useful data in it, we retire it to the
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // secondary cache before overwriting it.
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) {
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* old_map = primary->map;
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Code::Flags old_flags = Code::RemoveTypeFromFlags(old_code->flags());
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int seed = PrimaryOffset(primary->key, old_flags, old_map);
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int secondary_offset = SecondaryOffset(primary->key, old_flags, seed);
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Entry* secondary = entry(secondary_, secondary_offset);
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *secondary = *primary;
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update primary cache.
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  primary->key = name;
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  primary->value = code;
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  primary->map = map;
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  isolate()->counters()->megamorphic_stub_cache_updates()->Increment();
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name,
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<JSObject> receiver) {
1048defd9ff6930b4e24729971a61cf7469daf119beSteve Block  ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // If no global objects are present in the prototype chain, the load
1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // nonexistent IC stub can be shared for all names for a given map
1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and we use the empty string for the map cache in that case.  If
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // there are global objects involved, we need to check global
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // property cells in the stub and therefore the stub will be
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // specific to the name.
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<String> cache_name = factory()->empty_string();
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (receiver->IsGlobalObject()) cache_name = name;
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSObject> last = receiver;
11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  while (last->GetPrototype() != heap()->null_value()) {
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    last = Handle<JSObject>(JSObject::cast(last->GetPrototype()));
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (last->IsGlobalObject()) cache_name = name;
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Compile the stub that is either shared for all names or
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // name specific if there are global objects involved.
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Code::Flags flags =
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags));
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadNonexistent(cache_name, receiver, last);
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name));
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code));
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, cache_name, code);
1319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadField(Handle<String> name,
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<JSObject> receiver,
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<JSObject> holder,
1385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                         int field_index) {
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadField(receiver, holder, field_index, name);
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
1509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadCallback(Handle<String> name,
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSObject> receiver,
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSObject> holder,
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<AccessorInfo> callback) {
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadCallback(name, receiver, holder, callback);
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
1709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadConstant(Handle<String> name,
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSObject> receiver,
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSObject> holder,
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSFunction> value) {
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        compiler.CompileLoadConstant(receiver, holder, value, name);
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
1909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name,
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<JSObject> receiver,
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<JSObject> holder) {
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        compiler.CompileLoadInterceptor(receiver, holder, name);
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
2089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadNormal() {
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return isolate_->builtins()->LoadIC_Normal();
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadGlobal(Handle<String> name,
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSObject> receiver,
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<GlobalObject> holder,
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSGlobalPropertyCell> cell,
2215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                          bool is_dont_delete) {
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadStubCompiler compiler(isolate_);
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete);
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
2339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name,
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<JSObject> receiver,
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Handle<JSObject> holder,
2405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              int field_index) {
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadField(name, receiver, holder, field_index);
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name,
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Handle<JSObject> receiver,
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Handle<JSObject> holder,
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Handle<JSFunction> value) {
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadConstant(name, receiver, holder, value);
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name,
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                    Handle<JSObject> receiver,
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                    Handle<JSObject> holder) {
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name);
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadCallback(
2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> name,
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> receiver,
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> holder,
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<AccessorInfo> callback) {
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP);
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileLoadCallback(name, receiver, holder, callback);
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name,
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                    Handle<JSArray> receiver) {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileLoadArrayLength(name);
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name,
3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                     Handle<String> receiver) {
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Map> map(receiver->map());
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(map->FindInCodeCache(*name, flags));
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileLoadStringLength(name);
3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map::UpdateCodeCache(map, name, code);
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadFunctionPrototype(
3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> name,
3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSFunction> receiver) {
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags =
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedLoadStubCompiler compiler(isolate_);
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileLoadFunctionPrototype(name);
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code));
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreField(Handle<String> name,
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSObject> receiver,
3675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                          int field_index,
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<Map> transition,
369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                          StrictModeFlag strict_mode) {
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
3711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(
372e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Code::STORE_IC, type, strict_mode);
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StoreStubCompiler compiler(isolate_, strict_mode);
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileStoreField(receiver, field_index, transition, name);
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
3829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadOrStoreElement(
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> receiver,
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    KeyedIC::StubKind stub_kind,
389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    StrictModeFlag strict_mode) {
3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedAccessGrowMode grow_mode =
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      KeyedIC::GetGrowModeFromStubKind(stub_kind);
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state =
3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeExtraICState(grow_mode, strict_mode);
394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Code::Flags flags =
395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Code::ComputeMonomorphicFlags(
3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC
3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     : Code::KEYED_STORE_IC,
398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          NORMAL,
3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          extra_state);
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<String> name;
4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  switch (stub_kind) {
4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::LOAD:
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol();
4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::STORE_NO_TRANSITION:
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol();
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::STORE_AND_GROW_NO_TRANSITION:
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      name = isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol();
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    default:
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      UNREACHABLE();
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Map> receiver_map(receiver->map());
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags));
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code;
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  switch (stub_kind) {
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::LOAD: {
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      KeyedLoadStubCompiler compiler(isolate_);
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      code = compiler.CompileLoadElement(receiver_map);
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::STORE_AND_GROW_NO_TRANSITION: {
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      KeyedStoreStubCompiler compiler(isolate_, strict_mode,
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      ALLOW_JSARRAY_GROWTH);
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      code = compiler.CompileStoreElement(receiver_map);
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case KeyedIC::STORE_NO_TRANSITION: {
4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      KeyedStoreStubCompiler compiler(isolate_, strict_mode,
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      DO_NOT_ALLOW_JSARRAY_GROWTH);
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      code = compiler.CompileStoreElement(receiver_map);
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    default:
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      UNREACHABLE();
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(!code.is_null());
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (stub_kind == KeyedIC::LOAD) {
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0));
447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0));
4491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
4511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return code;
4521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
4531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (strict_mode == kStrictMode)
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict()
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : isolate_->builtins()->Builtins::StoreIC_Normal();
4598defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
4608defd9ff6930b4e24729971a61cf7469daf119beSteve Block
4618defd9ff6930b4e24729971a61cf7469daf119beSteve Block
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreGlobal(Handle<String> name,
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Handle<GlobalObject> receiver,
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Handle<JSGlobalPropertyCell> cell,
465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                           StrictModeFlag strict_mode) {
4661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(
467e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Code::STORE_IC, NORMAL, strict_mode);
4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StoreStubCompiler compiler(isolate_, strict_mode);
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
4769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreCallback(Handle<String> name,
4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Handle<JSObject> receiver,
4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Handle<AccessorInfo> callback,
4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             StrictModeFlag strict_mode) {
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
4851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(
486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Code::STORE_IC, CALLBACKS, strict_mode);
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StoreStubCompiler compiler(isolate_, strict_mode);
4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name);
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
4959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name,
5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Handle<JSObject> receiver,
5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                StrictModeFlag strict_mode) {
5021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(
503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Code::STORE_IC, INTERCEPTOR, strict_mode);
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StoreStubCompiler compiler(isolate_, strict_mode);
5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
5129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name,
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<JSObject> receiver,
5175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                               int field_index,
5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<Map> transition,
519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                               StrictModeFlag strict_mode) {
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION;
521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Code::Flags flags = Code::ComputeMonomorphicFlags(
522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Code::KEYED_STORE_IC, type, strict_mode);
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags));
5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedStoreStubCompiler compiler(isolate(), strict_mode,
5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  DO_NOT_ALLOW_JSARRAY_GROWTH);
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileStoreField(receiver, field_index, transition, name);
5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(receiver, name, code);
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return code;
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define CALL_LOGGER_TAG(kind, type) \
5387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallConstant(int argc,
5415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                            Code::Kind kind,
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Code::ExtraICState extra_state,
5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<String> name,
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<Object> object,
5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSObject> holder,
5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<JSFunction> function) {
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the check type and the map.
5488defd9ff6930b4e24729971a61cf7469daf119beSteve Block  InlineCacheHolderFlag cache_holder =
5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      IC::GetCodeCacheForObject(*object, *holder);
5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute check type based on receiver/holder.
553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CheckType check = RECEIVER_MAP_CHECK;
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->IsString()) {
555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    check = STRING_CHECK;
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (object->IsNumber()) {
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    check = NUMBER_CHECK;
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (object->IsBoolean()) {
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    check = BOOLEAN_CHECK;
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state,
5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    cache_holder, argc);
5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileCallConstant(object, holder, function, name, check);
5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  code->set_check_type(check);
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(flags, code->flags());
5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_,
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(map_holder, name, code);
5779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallField(int argc,
5825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                         Code::Kind kind,
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Code::ExtraICState extra_state,
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<String> name,
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<Object> object,
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<JSObject> holder,
5875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                         int index) {
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the check type and the map.
5898defd9ff6930b4e24729971a61cf7469daf119beSteve Block  InlineCacheHolderFlag cache_holder =
5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      IC::GetCodeCacheForObject(*object, *holder);
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // TODO(1233596): We cannot do receiver map check for non-JS objects
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // because they may be represented as immediates without a
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // map. Instead, we check against the map in the holder.
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    object = holder;
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeMonomorphicFlags(kind, FIELD, extra_state,
6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    cache_holder, argc);
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileCallField(Handle<JSObject>::cast(object),
6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                holder, index, name);
6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(flags, code->flags());
6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate_,
6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(map_holder, name, code);
6159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInterceptor(int argc,
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Code::Kind kind,
6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Code::ExtraICState extra_state,
6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<String> name,
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<Object> object,
6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                               Handle<JSObject> holder) {
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the check type and the map.
6268defd9ff6930b4e24729971a61cf7469daf119beSteve Block  InlineCacheHolderFlag cache_holder =
6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      IC::GetCodeCacheForObject(*object, *holder);
6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder));
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // TODO(1233596): We cannot do receiver map check for non-JS objects
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // because they may be represented as immediates without a
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // map. Instead, we check against the map in the holder.
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    object = holder;
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state,
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    cache_holder, argc);
6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      holder, name);
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(flags, code->flags());
6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(),
6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(map_holder, name, code);
6529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallGlobal(int argc,
6575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                          Code::Kind kind,
6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Code::ExtraICState extra_state,
6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<String> name,
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSObject> receiver,
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<GlobalObject> holder,
6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSGlobalPropertyCell> cell,
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Handle<JSFunction> function) {
6648defd9ff6930b4e24729971a61cf7469daf119beSteve Block  InlineCacheHolderFlag cache_holder =
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      IC::GetCodeCacheForObject(*receiver, *holder);
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder));
6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state,
6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    cache_holder, argc);
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags));
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (probe->IsCode()) return Handle<Code>::cast(probe);
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code =
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      compiler.CompileCallGlobal(receiver, holder, cell, function, name);
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT_EQ(flags, code->flags());
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(),
6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSObject::UpdateMapCodeCache(map_holder, name, code);
6819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return code;
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void FillCache(Isolate* isolate, Handle<Code> code) {
6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> dictionary =
6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
6883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    code->flags(),
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    code);
6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochCode* StubCache::FindCallInitialize(int argc,
695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    RelocInfo::Mode mode,
6967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                    Code::Kind kind) {
697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Code::ExtraICState extra_state =
698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Use raw_unchecked... so we don't get assert failures during GC.
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnseededNumberDictionary* dictionary =
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate()->heap()->raw_unchecked_non_monomorphic_cache();
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = dictionary->FindEntry(isolate(), flags);
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(entry != -1);
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Object* code = dictionary->ValueAt(entry);
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This might be called during the marking phase of the collector
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // hence the unchecked cast.
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return reinterpret_cast<Code*>(code);
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInitialize(int argc,
716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                              RelocInfo::Mode mode,
7175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              Code::Kind kind) {
718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Code::ExtraICState extra_state =
719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc);
7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallInitialize(flags);
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) {
7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ComputeCallInitialize(argc, mode, Code::CALL_IC);
7378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
740589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochHandle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET,
7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Code::KEYED_CALL_IC);
7438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallPreMonomorphic(
747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int argc,
748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Code::Kind kind,
7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Code::ExtraICState extra_state) {
7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc);
7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallNormal(int argc,
765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          Code::Kind kind,
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Code::ExtraICState extra_state) {
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc);
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallNormal(flags);
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
7823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ASSERT(kind == Code::KEYED_CALL_IC);
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState,
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         NORMAL, argc);
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallArguments(flags);
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
7953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
7963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallMegamorphic(
799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int argc,
800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Code::Kind kind,
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Code::ExtraICState extra_state) {
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         NORMAL, argc);
8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallMegamorphic(flags);
8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallMiss(int argc,
818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                        Code::Kind kind,
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Code::ExtraICState extra_state) {
8207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
8217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // and monomorphic stubs are not mixed up together in the stub cache.
8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         NORMAL, argc, OWN_MAP);
8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallMiss(flags);
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallDebugBreak(int argc,
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Code::Kind kind) {
840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Extra IC state is irrelevant for debug break ICs. They jump to
841257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the actual call ic to carry out the work.
8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState,
8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         NORMAL, argc);
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallDebugBreak(flags);
8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                      Code::Kind kind) {
859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Extra IC state is irrelevant for debug break ICs. They jump to
860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // the actual call ic to carry out the work.
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::Flags flags =
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState,
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         NORMAL, argc);
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<UnseededNumberDictionary> cache =
8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate_->factory()->non_monomorphic_cache();
8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int entry = cache->FindEntry(isolate_, flags);
8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StubCompiler compiler(isolate_);
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FillCache(isolate_, code);
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StubCache::Clear() {
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < kPrimaryTableSize; i++) {
88044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    primary_[i].key = heap()->empty_string();
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    primary_[i].value = empty;
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int j = 0; j < kSecondaryTableSize; j++) {
88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    secondary_[j].key = heap()->empty_string();
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    secondary_[j].value = empty;
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid StubCache::CollectMatchingMaps(SmallMapList* types,
891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    String* name,
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Code::Flags flags,
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<Context> global_context) {
894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < kPrimaryTableSize; i++) {
895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (primary_[i].key == name) {
896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Map* map = primary_[i].value->FindFirstMap();
897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Map can be NULL, if the stub is constant function call
898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // with a primitive receiver.
899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (map == NULL) continue;
900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int offset = PrimaryOffset(name, flags, map);
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (entry(primary_, offset) == &primary_[i] &&
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        types->Add(Handle<Map>(map));
905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < kSecondaryTableSize; i++) {
910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (secondary_[i].key == name) {
911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Map* map = secondary_[i].value->FindFirstMap();
912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Map can be NULL, if the stub is constant function call
913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // with a primitive receiver.
914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (map == NULL) continue;
915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Lookup in primary table and skip duplicates.
917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int primary_offset = PrimaryOffset(name, flags, map);
918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      Entry* primary_entry = entry(primary_, primary_offset);
919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (primary_entry->key == name) {
920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        Map* primary_map = primary_entry->value->FindFirstMap();
921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if (map == primary_map) continue;
922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Lookup in secondary table and add matches.
925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      int offset = SecondaryOffset(name, flags, primary_offset);
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (entry(secondary_, offset) == &secondary_[i] &&
9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) {
928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        types->Add(Handle<Map>(map));
929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StubCompiler implementation.
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9398b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
940d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT(args[0]->IsJSObject());
941d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT(args[1]->IsJSObject());
9428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  AccessorInfo* callback = AccessorInfo::cast(args[3]);
943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address getter_address = v8::ToCData<Address>(callback->getter());
944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(fun != NULL);
9468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  v8::AccessorInfo info(&args[0]);
94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Handle<v8::Value> result;
949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Leaving JavaScript.
95144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    VMState state(isolate, EXTERNAL);
95244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalCallbackScope call_scope(isolate, getter_address);
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
95544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
95644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (result.IsEmpty()) return HEAP->undefined_value();
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *v8::Utils::OpenHandle(*result);
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9618b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSObject* recv = JSObject::cast(args[0]);
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AccessorInfo* callback = AccessorInfo::cast(args[1]);
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address setter_address = v8::ToCData<Address>(callback->setter());
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(fun != NULL);
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name = args.at<String>(2);
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> value = args.at<Object>(3);
96944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
97044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG(isolate, ApiNamedPropertyAccess("store", recv, *name));
97144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CustomArguments custom_args(isolate, callback->data(), recv, recv);
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorInfo info(custom_args.end());
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Leaving JavaScript.
97544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    VMState state(isolate, EXTERNAL);
97644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalCallbackScope call_scope(isolate, setter_address);
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
97944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *value;
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9846ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic const int kAccessorInfoOffsetInInterceptorArgs = 2;
9856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Attempts to load a property with an interceptor (which must be present),
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * but doesn't search the prototype chain.
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * provide any value for the given name.
993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
9948b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
9956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<String> name_handle = args.at<String>(0);
9966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
9976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
9986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(args[2]->IsJSObject());  // Receiver.
9996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(args[3]->IsJSObject());  // Holder.
10006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(args.length() == 5);  // Last arg is data object.
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::NamedPropertyGetter getter =
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(getter != NULL);
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Use the interceptor getter.
10096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    v8::AccessorInfo info(args.arguments() -
10106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          kAccessorInfoOffsetInInterceptorArgs);
101144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HandleScope scope(isolate);
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> r;
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
101544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      r = getter(v8::Utils::ToLocal(name_handle), info);
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
101844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!r.IsEmpty()) {
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return *v8::Utils::OpenHandle(*r);
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->no_interceptor_result_sentinel();
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic MaybeObject* ThrowReferenceError(String* name) {
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the load is non-contextual, just return the undefined result.
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note that both keyed and non-keyed loads may end up here, so we
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can't use either LoadIC or KeyedLoadIC constructors.
103244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IC ic(IC::NO_EXTRA_FRAME, Isolate::Current());
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
103444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!ic.SlowIsContextual()) return HEAP->undefined_value();
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Throw a reference error.
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name_handle(name);
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> error =
104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FACTORY->NewReferenceError("not_defined",
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  HandleVector(&name_handle, 1));
104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Isolate::Current()->Throw(*error);
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic MaybeObject* LoadWithInterceptor(Arguments* args,
10475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                        PropertyAttributes* attrs) {
10486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<String> name_handle = args->at<String>(0);
10496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
10506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
10516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<JSObject> receiver_handle = args->at<JSObject>(2);
10526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<JSObject> holder_handle = args->at<JSObject>(3);
10536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(args->length() == 5);  // Last arg is data object.
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = receiver_handle->GetIsolate();
105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::NamedPropertyGetter getter =
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(getter != NULL);
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Use the interceptor getter.
10646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    v8::AccessorInfo info(args->arguments() -
10656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          kAccessorInfoOffsetInInterceptorArgs);
106644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HandleScope scope(isolate);
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> r;
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      r = getter(v8::Utils::ToLocal(name_handle), info);
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!r.IsEmpty()) {
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *attrs = NONE;
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return *v8::Utils::OpenHandle(*r);
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *receiver_handle,
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *name_handle,
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      attrs);
108444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Loads a property with an interceptor performing post interceptor
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * lookup if interceptor failed.
1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
10938b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PropertyAttributes attr = NONE;
10955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* result;
10965913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr);
10975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
10985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the property is present, return it.
1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (attr != ABSENT) return result;
11026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return ThrowReferenceError(String::cast(args[0]));
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11068b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PropertyAttributes attr;
11085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* result = LoadWithInterceptor(&args, &attr);
110944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This is call IC. In this case, we simply return the undefined result which
1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // will lead to an exception when trying to invoke the result as a
1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function.
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11178b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
1118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  ASSERT(args.length() == 4);
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSObject* recv = JSObject::cast(args[0]);
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  String* name = String::cast(args[1]);
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* value = args[2];
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode);
11233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(recv->HasNamedInterceptor());
1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PropertyAttributes attr = NONE;
1126e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  MaybeObject* result = recv->SetPropertyWithInterceptor(
1127e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      name, value, attr, strict_mode);
1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11328b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
1133402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  JSObject* receiver = JSObject::cast(args[0]);
11343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ASSERT(args.smi_at(1) >= 0);
11353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  uint32_t index = args.smi_at(1);
1136402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return receiver->GetElementWithInterceptor(receiver, index);
1137402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1138402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1139402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
11427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
11447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CallIC::GenerateInitialize(masm(), argc, extra_state);
11467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
11477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateInitialize(masm(), argc);
11487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize");
115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate()->counters()->call_initialize_stubs()->Increment();
115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
115244f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
11533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
11543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
11553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11593ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The code of the PreMonomorphic stub is the same as the code
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of the Initialized stub.  They just differ on the code object flags.
11637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
11657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CallIC::GenerateInitialize(masm(), argc, extra_state);
11677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
11687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateInitialize(masm(), argc);
11697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
11703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate()->counters()->call_premonomorphic_stubs()->Increment();
117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
11743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
11753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
11763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
11827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
11837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
1184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Call normal is always with a explict receiver.
1185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ASSERT(!CallIC::Contextual::decode(
1186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Code::ExtractExtraICStateFromFlags(flags)));
11877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    CallIC::GenerateNormal(masm(), argc);
11887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
11897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateNormal(masm(), argc);
11907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
119244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate()->counters()->call_normal_stubs()->Increment();
119344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
12037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
12057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CallIC::GenerateMegamorphic(masm(), argc, extra_state);
12077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
12087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateMegamorphic(masm(), argc);
12097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
121144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate()->counters()->call_megamorphic_stubs()->Increment();
121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
121344f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
12213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int argc = Code::ExtractArgumentsCountFromFlags(flags);
12223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  PROFILE(isolate(),
12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          CALL_MEGAMORPHIC_TAG),
12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12333ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
12357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
12377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CallIC::GenerateMiss(masm(), argc, extra_state);
12397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
12407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateMiss(masm(), argc);
12417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
12423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss");
124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate()->counters()->call_megamorphic_stubs()->Increment();
124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateCallICDebugBreak(masm());
12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
125644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          CALL_DEBUG_BREAK_TAG),
12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          *code, code->arguments_count()));
12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Use the same code for the the step in preparations as we do for the
12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // miss case.
1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = Code::ExtractArgumentsCountFromFlags(flags);
12687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Kind kind = Code::ExtractKindFromFlags(flags);
12697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (kind == Code::CALL_IC) {
1270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // For the debugger extra ic state is irrelevant.
1271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState);
12727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
12737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    KeyedCallIC::GenerateMiss(masm(), argc);
12747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
127644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PROFILE(isolate(),
127744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          CodeCreateEvent(
127844f0eee88ff00398ff7f715fab053374d808c90dSteve Block              CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              *code,
128044f0eee88ff00398ff7f715fab053374d808c90dSteve Block              code->arguments_count()));
12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif  // ENABLE_DEBUGGER_SUPPORT
1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#undef CALL_LOGGER_TAG
1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            const char* name) {
1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create code object in the heap.
1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodeDesc desc;
1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  masm_.GetCode(&desc);
12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER
12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_print_code_stubs) code->Disassemble(name);
1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<String> name) {
13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (FLAG_print_code_stubs && !name.is_null())
13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? GetCodeWithFlags(flags, *name->ToCString())
13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1308402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StubCompiler::LookupPostInterceptor(Handle<JSObject> holder,
13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Handle<String> name,
13114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                                         LookupResult* lookup) {
13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  holder->LocalLookupRealNamedProperty(*name, lookup);
13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (lookup->IsProperty()) return;
13144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  lookup->NotFound();
13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (holder->GetPrototype()->IsNull()) return;
1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  holder->GetPrototype()->Lookup(*name, lookup);
13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
132085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) {
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, name);
13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name));
13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type,
13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<String> name,
1333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                            InlineCacheState state) {
1334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Code::Flags flags = Code::ComputeFlags(
1335589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, name);
13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name));
13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StoreStubCompiler::GetCode(PropertyType type,
13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<String> name) {
1345589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Code::Flags flags =
1346589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, name);
13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
13503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13543ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type,
13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Handle<String> name,
1356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                             InlineCacheState state) {
13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code::ExtraICState extra_state =
13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeExtraICState(grow_mode_, strict_mode_);
1359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Code::Flags flags =
13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, name);
13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
13693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    MacroAssembler* masm) {
13703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  KeyedStoreIC::GenerateSlow(masm);
13713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
13723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCallStubCompiler::CallStubCompiler(Isolate* isolate,
13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   int argc,
13768defd9ff6930b4e24729971a61cf7469daf119beSteve Block                                   Code::Kind kind,
13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Code::ExtraICState extra_state,
13788defd9ff6930b4e24729971a61cf7469daf119beSteve Block                                   InlineCacheHolderFlag cache_holder)
13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : StubCompiler(isolate),
13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      arguments_(argc),
1381b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      kind_(kind),
13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      extra_state_(extra_state),
1383b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      cache_holder_(cache_holder) {
13848defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
13858defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13868defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) {
13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (function->shared()->HasBuiltinFunctionId()) {
13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    BuiltinFunctionId id = function->shared()->builtin_function_id();
1390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef CALL_GENERATOR_CASE
139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
139544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CallOptimization optimization(function);
13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return optimization.is_simple_api_call();
1397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
1398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::CompileCustomCall(
14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<Object> object,
14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> holder,
14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSGlobalPropertyCell> cell,
14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSFunction> function,
14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<String> fname) {
140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(HasCustomCallGenerator(function));
140744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (function->shared()->HasBuiltinFunctionId()) {
14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    BuiltinFunctionId id = function->shared()->builtin_function_id();
14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define CALL_GENERATOR_CASE(name)                               \
14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (id == k##name) {                                        \
14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return CallStubCompiler::Compile##name##Call(object,      \
14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                   holder,      \
14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                   cell,        \
14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                   function,    \
14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                   fname);      \
141744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
141844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
141925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef CALL_GENERATOR_CASE
142044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
142144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CallOptimization optimization(function);
142244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(optimization.is_simple_api_call());
142344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return CompileFastApiCall(optimization,
142444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            object,
142544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            holder,
142644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            cell,
142744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            function,
142844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            fname);
142925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
143025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
143125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) {
1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int argc = arguments_.immediate();
14347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    type,
14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                    extra_state_,
14378defd9ff6930b4e24729971a61cf7469daf119beSteve Block                                                    cache_holder_,
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    argc);
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return GetCodeWithFlags(flags, name);
1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<String> function_name;
144525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  if (function->shared()->name()->IsString()) {
14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    function_name = Handle<String>(String::cast(function->shared()->name()));
144725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  }
144825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  return GetCode(CONSTANT_FUNCTION, function_name);
144925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
145025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
145125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> ConstructStubCompiler::GetCode() {
1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Code::Flags flags = Code::ComputeFlags(Code::STUB);
14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = GetCodeWithFlags(flags, "ConstructStub");
14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, "ConstructStub"));
14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", *code));
14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return code;
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14616ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockCallOptimization::CallOptimization(LookupResult* lookup) {
14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (lookup->IsFound() &&
14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      lookup->IsCacheable() &&
14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      lookup->type() == CONSTANT_FUNCTION) {
146585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch    // We only optimize constant function calls.
14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Initialize(Handle<JSFunction>::null());
14696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
14706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
14716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCallOptimization::CallOptimization(Handle<JSFunction> function) {
14736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Initialize(function);
14746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
14756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint CallOptimization::GetPrototypeDepthOfExpectedType(
14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> object,
14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<JSObject> holder) const {
14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(is_simple_api_call());
14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (expected_receiver_type_.is_null()) return 0;
14826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int depth = 0;
14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  while (!object.is_identical_to(holder)) {
14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (object->IsInstanceOf(*expected_receiver_type_)) return depth;
14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    object = Handle<JSObject>(JSObject::cast(object->GetPrototype()));
14866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ++depth;
14876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (holder->IsInstanceOf(*expected_receiver_type_)) return depth;
14896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return kInvalidProtoDepth;
14906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
14916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallOptimization::Initialize(Handle<JSFunction> function) {
14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  constant_function_ = Handle<JSFunction>::null();
14956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  is_simple_api_call_ = false;
14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  expected_receiver_type_ = Handle<FunctionTemplateInfo>::null();
14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  api_call_info_ = Handle<CallHandlerInfo>::null();
14986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (function.is_null() || !function->is_compiled()) return;
15006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  constant_function_ = function;
15026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  AnalyzePossibleApiFunction(function);
15036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
15046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) {
15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!function->shared()->IsApiFunction()) return;
15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data());
15096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Require a C++ callback.
15116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (info->call_code()->IsUndefined()) return;
15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  api_call_info_ =
15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code()));
15146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Accept signatures that either have no restrictions at all or
15166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // only have restrictions on the receiver.
15176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!info->signature()->IsUndefined()) {
15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<SignatureInfo> signature =
15193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Handle<SignatureInfo>(SignatureInfo::cast(info->signature()));
15206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (!signature->args()->IsUndefined()) return;
15216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (!signature->receiver()->IsUndefined()) {
15226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      expected_receiver_type_ =
15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Handle<FunctionTemplateInfo>(
15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              FunctionTemplateInfo::cast(signature->receiver()));
15256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
15266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
15276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  is_simple_api_call_ = true;
15296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
15306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1533