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#ifndef V8_STUB_CACHE_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_STUB_CACHE_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "allocation.h"
3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "arguments.h"
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "ic-inl.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h"
35257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "objects.h"
36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "zone-inl.h"
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stub cache is used for megamorphic calls and property accesses.
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// It maps (map, name, type)->Code*
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The design of the table uses the inline cache stubs used for
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mono-morphic calls. The beauty of this, we do not have to
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// invalidate the cache whenever a prototype map is changed.  The stub
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// validates the map chain as in the mono-morphic case.
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass SmallMapList;
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StubCache;
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass SCTableReference {
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address address() const { return address_; }
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit SCTableReference(Address address) : address_(address) {}
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address address_;
6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class StubCache;
6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StubCache {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  struct Entry {
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    String* key;
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Code* value;
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Map* map;
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Initialize();
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computes the right stub matching. Inserts the result in the
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // cache before returning.  This might compile a stub if needed.
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadNonexistent(Handle<String> name,
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> receiver);
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadField(Handle<String> name,
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> receiver,
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> holder,
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int field_index);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadCallback(Handle<String> name,
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> receiver,
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<AccessorInfo> callback);
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadConstant(Handle<String> name,
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> receiver,
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> value);
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadInterceptor(Handle<String> name,
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> receiver,
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder);
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadNormal();
1035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeLoadGlobal(Handle<String> name,
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSObject> receiver,
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<GlobalObject> holder,
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSGlobalPropertyCell> cell,
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 bool is_dont_delete);
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // ---
1118defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadField(Handle<String> name,
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Handle<JSObject> receiver,
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Handle<JSObject> holder,
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     int field_index);
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadCallback(Handle<String> name,
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<JSObject> receiver,
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<JSObject> holder,
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<AccessorInfo> callback);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadConstant(Handle<String> name,
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<JSObject> receiver,
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<JSObject> holder,
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Handle<JSFunction> value);
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadInterceptor(Handle<String> name,
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Handle<JSObject> receiver,
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Handle<JSObject> holder);
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadArrayLength(Handle<String> name,
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Handle<JSArray> receiver);
1335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadStringLength(Handle<String> name,
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                            Handle<String> receiver);
136592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadFunctionPrototype(Handle<String> name,
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Handle<JSFunction> receiver);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // ---
1415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeStoreField(Handle<String> name,
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSObject> receiver,
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 int field_index,
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<Map> transition,
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 StrictModeFlag strict_mode);
147e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeStoreNormal(StrictModeFlag strict_mode);
1495913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeStoreGlobal(Handle<String> name,
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<GlobalObject> receiver,
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<JSGlobalPropertyCell> cell,
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  StrictModeFlag strict_mode);
154592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeStoreCallback(Handle<String> name,
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<JSObject> receiver,
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<AccessorInfo> callback,
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    StrictModeFlag strict_mode);
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeStoreInterceptor(Handle<String> name,
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Handle<JSObject> receiver,
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       StrictModeFlag strict_mode);
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // ---
1657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedStoreField(Handle<String> name,
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> receiver,
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      int field_index,
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<Map> transition,
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      StrictModeFlag strict_mode);
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeKeyedLoadOrStoreElement(Handle<JSObject> receiver,
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              KeyedIC::StubKind stub_kind,
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              StrictModeFlag strict_mode);
1757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
176592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  // ---
177592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallField(int argc,
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Code::Kind,
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Code::ExtraICState extra_state,
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<String> name,
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<Object> object,
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> holder,
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int index);
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallConstant(int argc,
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Code::Kind,
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Code::ExtraICState extra_state,
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<String> name,
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<Object> object,
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> function);
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallInterceptor(int argc,
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Code::Kind,
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Code::ExtraICState extra_state,
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String> name,
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<Object> object,
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder);
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallGlobal(int argc,
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Code::Kind,
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Code::ExtraICState extra_state,
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name,
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSObject> receiver,
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<GlobalObject> holder,
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSGlobalPropertyCell> cell,
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSFunction> function);
20985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ---
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallInitialize(int argc, RelocInfo::Mode mode);
2138a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Handle<Code> ComputeKeyedCallInitialize(int argc);
2158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallPreMonomorphic(int argc,
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Code::Kind kind,
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Code::ExtraICState extra_state);
2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallNormal(int argc,
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Code::Kind kind,
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Code::ExtraICState state);
2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallArguments(int argc, Code::Kind kind);
2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallMegamorphic(int argc,
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Code::Kind kind,
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Code::ExtraICState state);
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallMiss(int argc,
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Code::Kind kind,
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Code::ExtraICState state);
23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Finds the Code object stored in the Heap::non_monomorphic_cache().
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Code* FindCallInitialize(int argc, RelocInfo::Mode mode, Code::Kind kind);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind);
2397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind);
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update cache for entry hash(name, map).
24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code* Set(String* name, Map* map, Code* code);
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear the lookup table (@ mark compact collection).
24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Clear();
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Collect all maps that match the name and flags.
25069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void CollectMatchingMaps(SmallMapList* types,
25144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                           String* name,
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Code::Flags flags,
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Handle<Context> global_context);
254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for probing the stub cache table.
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Arguments extra, extra2 and extra3 may be used to pass additional scratch
2573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // registers. Set to no_reg if not needed.
25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void GenerateProbe(MacroAssembler* masm,
25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Code::Flags flags,
26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Register receiver,
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Register name,
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Register scratch,
26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Register extra,
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Register extra2 = no_reg,
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Register extra3 = no_reg);
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Table {
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kPrimary,
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kSecondary
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
27344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SCTableReference key_reference(StubCache::Table table) {
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return SCTableReference(
27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        reinterpret_cast<Address>(&first_entry(table)->key));
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SCTableReference map_reference(StubCache::Table table) {
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return SCTableReference(
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        reinterpret_cast<Address>(&first_entry(table)->map));
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  SCTableReference value_reference(StubCache::Table table) {
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return SCTableReference(
28744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        reinterpret_cast<Address>(&first_entry(table)->value));
28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StubCache::Entry* first_entry(StubCache::Table table) {
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    switch (table) {
29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      case StubCache::kPrimary: return StubCache::primary_;
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      case StubCache::kSecondary: return StubCache::secondary_;
29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    UNREACHABLE();
29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return NULL;
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate() { return isolate_; }
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap() { return isolate()->heap(); }
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Factory* factory() { return isolate()->factory(); }
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  explicit StubCache(Isolate* isolate);
30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> ComputeCallInitialize(int argc,
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     RelocInfo::Mode mode,
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Code::Kind kind);
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The stub cache has a primary and secondary level.  The two levels have
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // different hashing algorithms in order to avoid simultaneous collisions
3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in both caches.  Unlike a probing strategy (quadratic or otherwise) the
3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // update strategy on updates is fairly clear and simple:  Any existing entry
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in the primary cache is moved to the secondary cache, and secondary cache
3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // entries are overwritten.
3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Hash algorithm for the primary table.  This algorithm is replicated in
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // assembler for every architecture.  Returns an index into the table that
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is scaled by 1 << kHeapObjectTagSize.
321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static int PrimaryOffset(String* name, Code::Flags flags, Map* map) {
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // This works well because the heap object tag size and the hash
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // shift are equal.  Shifting down the length field to get the
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // hash code would effectively throw away two bits of the hash
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // code.
32669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    STATIC_ASSERT(kHeapObjectTagSize == String::kHashShift);
327d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Compute the hash of the name (use entire hash field).
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(name->HasHashCode());
329d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    uint32_t field = name->hash_field();
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Using only the low bits in 64-bit mode is unlikely to increase the
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // risk of collision even if the heap is spread over an area larger than
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // 4Gb (and not at all if it isn't).
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t map_low32bits =
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // We always set the in_loop bit to zero when generating the lookup code
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // so do it here too so the hash codes match.
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t iflags =
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Base the offset on a simple combination of name, flags, and map.
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t key = (map_low32bits + field) ^ iflags;
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Hash algorithm for the secondary table.  This algorithm is replicated in
3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // assembler for every architecture.  Returns an index into the table that
3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is scaled by 1 << kHeapObjectTagSize.
347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static int SecondaryOffset(String* name, Code::Flags flags, int seed) {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Use the seed from the primary cache in the secondary cache.
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t string_low32bits =
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // We always set the in_loop bit to zero when generating the lookup code
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // so do it here too so the hash codes match.
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t iflags =
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    uint32_t key = (seed - string_low32bits) + iflags;
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the entry for a given offset in exactly the same way as
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // we do in generated code.  We generate an hash code that already
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ends in String::kHashShift 0s.  Then we multiply it so it is a multiple
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of sizeof(Entry).  This makes it easier to avoid making mistakes
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in the hashed offset computations.
364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static Entry* entry(Entry* table, int offset) {
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const int multiplier = sizeof(*table) >> String::kHashShift;
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<Entry*>(
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        reinterpret_cast<Address>(table) + offset * multiplier);
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kPrimaryTableBits = 11;
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSecondaryTableBits = 9;
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSecondaryTableSize = (1 << kSecondaryTableBits);
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Entry primary_[kPrimaryTableSize];
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Entry secondary_[kSecondaryTableSize];
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate_;
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  friend class Isolate;
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  friend class SCTableReference;
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DISALLOW_COPY_AND_ASSIGN(StubCache);
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for callbacks.
3908b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty);
3918b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty);
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for interceptors.
3958b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly);
3968b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad);
3978b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall);
3988b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty);
3998b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, CallInterceptorProperty);
4008b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochDECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// The stub compilers compile stubs for the stub cache.
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StubCompiler BASE_EMBEDDED {
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit StubCompiler(Isolate* isolate)
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : isolate_(isolate), masm_(isolate, NULL, 256), failure_(NULL) { }
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Functions to compile either CallIC or KeyedCallIC.  The specific kind
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // is extracted from the code flags.
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallInitialize(Code::Flags flags);
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallPreMonomorphic(Code::Flags flags);
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallNormal(Code::Flags flags);
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallMegamorphic(Code::Flags flags);
4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallArguments(Code::Flags flags);
4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallMiss(Code::Flags flags);
4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallDebugBreak(Code::Flags flags);
4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags);
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Static functions for generating parts of stubs.
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  int index,
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  Register prototype);
427402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Generates prototype loading code that uses the objects from the
4290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // context we were in when this function was called. If the context
4300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // has changed, a jump to miss is performed. This ties the generated
4310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // code to a particular context and so must not be used in cases
4320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // where the generated code is not allowed to have references to
4330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // objects from a context.
4347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
4357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                                        int index,
4360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                                        Register prototype,
4370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                                        Label* miss);
4387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateFastPropertyLoad(MacroAssembler* masm,
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Register dst,
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Register src,
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Handle<JSObject> holder,
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       int index);
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadArrayLength(MacroAssembler* masm,
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register receiver,
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register scratch,
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Label* miss_label);
449402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadStringLength(MacroAssembler* masm,
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Register receiver,
452402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                       Register scratch1,
453402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                       Register scratch2,
4541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                       Label* miss_label,
4551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                       bool support_wrappers);
456402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register receiver,
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register scratch1,
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register scratch2,
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Label* miss_label);
462402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateStoreField(MacroAssembler* masm,
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSObject> object,
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 int index,
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<Map> transition,
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register receiver_reg,
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register name_reg,
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register scratch,
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Label* miss_label);
471402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateLoadMiss(MacroAssembler* masm,
473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               Code::Kind kind);
474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm);
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4778defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Generates code that verifies that the property holder has not changed
4788defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // (checking maps of objects in the prototype chain for fast and global
4798defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // objects or doing negative lookup for slow objects, ensures that the
4808defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // property cells for global objects are still empty) and checks that the map
4818defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // of the holder has not changed. If necessary the function also generates
4828defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // code for security check in case of global object holders. Helps to make
4838defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // sure that the current IC is still valid.
4848defd9ff6930b4e24729971a61cf7469daf119beSteve Block  //
4858defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // The scratch and holder registers are always clobbered, but the object
4868defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // register is only clobbered if it the same as the holder register. The
4878defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // function returns a register containing the holder - either object_reg or
4888defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // holder_reg.
4898defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // The function can optionally (when save_at_depth !=
4908defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // kInvalidProtoDepth) save the object at the given depth by moving
4918defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // it to [esp + kPointerSize].
4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Register CheckPrototypes(Handle<JSObject> object,
493402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           Register object_reg,
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Handle<JSObject> holder,
495402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           Register holder_reg,
4963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch1,
4973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch2,
4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Handle<String> name,
4993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Label* miss) {
5003bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
5013bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           scratch2, name, kInvalidProtoDepth, miss);
502402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
503402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Register CheckPrototypes(Handle<JSObject> object,
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Register object_reg,
5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Handle<JSObject> holder,
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Register holder_reg,
5083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch1,
5093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch2,
5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Handle<String> name,
511402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           int save_at_depth,
5123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Label* miss);
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<String> name);
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_failure(Failure* failure) { failure_ = failure; }
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateLoadField(Handle<JSObject> object,
5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Handle<JSObject> holder,
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register receiver,
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register scratch1,
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register scratch2,
5263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                         Register scratch3,
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         int index,
5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         Handle<String> name,
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Label* miss);
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateLoadCallback(Handle<JSObject> object,
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<JSObject> holder,
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register receiver,
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register name_reg,
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register scratch1,
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register scratch2,
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register scratch3,
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<AccessorInfo> callback,
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<String> name,
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Label* miss);
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateLoadConstant(Handle<JSObject> object,
5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<JSObject> holder,
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register receiver,
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch1,
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch2,
5473bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                            Register scratch3,
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<JSFunction> value,
5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Handle<String> name,
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Label* miss);
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateLoadInterceptor(Handle<JSObject> object,
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<JSObject> holder,
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               LookupResult* lookup,
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register receiver,
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register name_reg,
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch1,
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch2,
5593bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                               Register scratch3,
5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<String> name,
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Label* miss);
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static void LookupPostInterceptor(Handle<JSObject> holder,
5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<String> name,
5654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                                    LookupResult* lookup);
5664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Isolate* isolate() { return isolate_; }
56844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap() { return isolate()->heap(); }
56944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Factory* factory() { return isolate()->factory(); }
57044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Isolate* isolate_;
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Failure* failure_;
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LoadStubCompiler: public StubCompiler {
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit LoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadNonexistent(Handle<String> name,
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> object,
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> last);
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadField(Handle<JSObject> object,
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> holder,
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int index,
5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<String> name);
5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadCallback(Handle<String> name,
5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> object,
5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<AccessorInfo> callback);
5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadConstant(Handle<JSObject> object,
5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> value,
5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<String> name);
6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder,
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String> name);
6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadGlobal(Handle<JSObject> object,
6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<GlobalObject> holder,
6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSGlobalPropertyCell> cell,
6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name,
6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 bool is_dont_delete);
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(PropertyType type, Handle<String> name);
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedLoadStubCompiler: public StubCompiler {
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
619592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadField(Handle<String> name,
6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> object,
6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> holder,
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int index);
6246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadCallback(Handle<String> name,
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> object,
6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<AccessorInfo> callback);
6296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadConstant(Handle<String> name,
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> object,
6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> value);
6346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder,
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String> name);
6386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadArrayLength(Handle<String> name);
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadStringLength(Handle<String> name);
6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadFunctionPrototype(Handle<String> name);
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileLoadPolymorphic(MapHandleList* receiver_maps,
6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      CodeHandleList* handler_ics);
649257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
650257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateLoadExternalArray(MacroAssembler* masm,
651589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                        ElementsKind elements_kind);
652257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
653257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateLoadFastElement(MacroAssembler* masm);
654b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static void GenerateLoadFastDoubleElement(MacroAssembler* masm);
6563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static void GenerateLoadDictionaryElement(MacroAssembler* masm);
6583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(PropertyType type,
6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Handle<String> name,
662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                       InlineCacheState state = MONOMORPHIC);
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StoreStubCompiler: public StubCompiler {
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : StubCompiler(isolate), strict_mode_(strict_mode) { }
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreField(Handle<JSObject> object,
6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 int index,
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<Map> transition,
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name);
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreCallback(Handle<JSObject> object,
6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<AccessorInfo> callback,
6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<String> name);
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       Handle<String> name);
683592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object,
6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<JSGlobalPropertyCell> holder,
6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<String> name);
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(PropertyType type, Handle<String> name);
6901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
691e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StrictModeFlag strict_mode_;
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedStoreStubCompiler: public StubCompiler {
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedStoreStubCompiler(Isolate* isolate,
6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         StrictModeFlag strict_mode,
6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         KeyedAccessGrowMode grow_mode)
7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : StubCompiler(isolate),
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      strict_mode_(strict_mode),
7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      grow_mode_(grow_mode) { }
7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreField(Handle<JSObject> object,
7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 int index,
7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<Map> transition,
7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name);
708257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
71085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps,
7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       CodeHandleList* handler_stubs,
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       MapHandleList* transitioned_maps);
714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateStoreFastElement(MacroAssembler* masm,
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       bool is_js_array,
7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       ElementsKind element_kind,
7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       KeyedAccessGrowMode grow_mode);
719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static void GenerateStoreFastDoubleElement(MacroAssembler* masm,
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             bool is_js_array,
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             KeyedAccessGrowMode grow_mode);
7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static void GenerateStoreExternalArray(MacroAssembler* masm,
725589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                         ElementsKind elements_kind);
7263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  static void GenerateStoreDictionaryElement(MacroAssembler* masm);
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(PropertyType type,
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Handle<String> name,
732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                       InlineCacheState state = MONOMORPHIC);
733e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
734e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StrictModeFlag strict_mode_;
7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedAccessGrowMode grow_mode_;
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call
740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// IC stubs.
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CUSTOM_CALL_IC_GENERATORS(V)            \
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(ArrayPush)                                  \
743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(ArrayPop)                                   \
744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(StringCharCodeAt)                           \
745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(StringCharAt)                               \
746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(StringFromCharCode)                         \
747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(MathFloor)                                  \
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V(MathAbs)
74925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
75025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
75144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass CallOptimization;
75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CallStubCompiler: public StubCompiler {
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStubCompiler(Isolate* isolate,
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   int argc,
7578defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   Code::Kind kind,
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Code::ExtraICState extra_state,
7598defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   InlineCacheHolderFlag cache_holder);
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallField(Handle<JSObject> object,
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<JSObject> holder,
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int index,
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Handle<String> name);
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallConstant(Handle<Object> object,
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> function,
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<String> name,
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   CheckType check);
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallInterceptor(Handle<JSObject> object,
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder,
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<String> name);
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCallGlobal(Handle<JSObject> object,
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<GlobalObject> holder,
7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSGlobalPropertyCell> cell,
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSFunction> function,
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name);
7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static bool HasCustomCallGenerator(Handle<JSFunction> function);
783b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Compiles a custom call constant/global IC.  For constant calls cell is
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // NULL.  Returns an empty handle if there is no custom call code for the
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // given function.
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileCustomCall(Handle<Object> object,
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSObject> holder,
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSGlobalPropertyCell> cell,
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<JSFunction> function,
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Handle<String> name);
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define DECLARE_CALL_GENERATOR(name)                                    \
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> Compile##name##Call(Handle<Object> object,               \
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,             \
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSGlobalPropertyCell> cell,   \
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSFunction> function,         \
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<String> fname);
80025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
80125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef DECLARE_CALL_GENERATOR
8026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<Object> object,
8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<JSObject> holder,
8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<JSGlobalPropertyCell> cell,
8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<JSFunction> function,
8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<String> name);
80944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(PropertyType type, Handle<String> name);
8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode(Handle<JSFunction> function);
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const ParameterCount& arguments() { return arguments_; }
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateNameCheck(Handle<String> name, Label* miss);
8167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateGlobalReceiverCheck(Handle<JSObject> object,
8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<JSObject> holder,
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Handle<String> name,
82059151504615d929945dc59db37bf1166937748c6Steve Block                                   Label* miss);
82159151504615d929945dc59db37bf1166937748c6Steve Block
82259151504615d929945dc59db37bf1166937748c6Steve Block  // Generates code to load the function from the cell checking that
82359151504615d929945dc59db37bf1166937748c6Steve Block  // it still contains the same function.
8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateLoadFunctionFromCell(Handle<JSGlobalPropertyCell> cell,
8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Handle<JSFunction> function,
82659151504615d929945dc59db37bf1166937748c6Steve Block                                    Label* miss);
82759151504615d929945dc59db37bf1166937748c6Steve Block
8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Generates a jump to CallIC miss stub.
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void GenerateMissBranch();
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const ParameterCount arguments_;
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const Code::Kind kind_;
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const Code::ExtraICState extra_state_;
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const InlineCacheHolderFlag cache_holder_;
835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructStubCompiler: public StubCompiler {
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit ConstructStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> CompileConstructStub(Handle<JSFunction> function);
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> GetCode();
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Holds information about possible function call optimizations.
8506ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CallOptimization BASE_EMBEDDED {
8516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
8526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  explicit CallOptimization(LookupResult* lookup);
8536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  explicit CallOptimization(Handle<JSFunction> function);
8556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_constant_call() const {
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return !constant_function_.is_null();
8586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
8596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSFunction> constant_function() const {
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(is_constant_call());
8626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return constant_function_;
8636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
8646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_simple_api_call() const {
8666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return is_simple_api_call_;
8676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
8686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FunctionTemplateInfo> expected_receiver_type() const {
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(is_simple_api_call());
8716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return expected_receiver_type_;
8726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
8736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<CallHandlerInfo> api_call_info() const {
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(is_simple_api_call());
8766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return api_call_info_;
8776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
8786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Returns the depth of the object having the expected type in the
8806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // prototype chain between the two arguments.
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int GetPrototypeDepthOfExpectedType(Handle<JSObject> object,
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Handle<JSObject> holder) const;
8836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Initialize(Handle<JSFunction> function);
8866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Determines whether the given function can be called using the
8886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // fast api call builtin.
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AnalyzePossibleApiFunction(Handle<JSFunction> function);
8906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSFunction> constant_function_;
8926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_simple_api_call_;
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FunctionTemplateInfo> expected_receiver_type_;
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<CallHandlerInfo> api_call_info_;
8956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
8966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
897257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_STUB_CACHE_H_
901