stub-cache.h revision 59151504615d929945dc59db37bf1166937748c6
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 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
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "macro-assembler.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stub cache is used for megamorphic calls and property accesses.
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// It maps (map, name, type)->Code*
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The design of the table uses the inline cache stubs used for
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// mono-morphic calls. The beauty of this, we do not have to
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// invalidate the cache whenever a prototype map is changed.  The stub
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// validates the map chain as in the mono-morphic case.
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference;
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StubCache : public AllStatic {
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  struct Entry {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    String* key;
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Code* value;
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void Initialize(bool create_heap_objects);
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computes the right stub matching. Inserts the result in the
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // cache before returning.  This might compile a stub if needed.
5980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadNonexistent(String* name,
6080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        JSObject* receiver);
616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadField(String* name,
6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  JSObject* receiver,
6480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  JSObject* holder,
6580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  int field_index);
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadCallback(String* name,
6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSObject* receiver,
6980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSObject* holder,
7080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     AccessorInfo* callback);
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadConstant(String* name,
7380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSObject* receiver,
7480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSObject* holder,
7580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     Object* value);
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadInterceptor(String* name,
7880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        JSObject* receiver,
7980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        JSObject* holder);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadNormal();
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeLoadGlobal(String* name,
8580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSObject* receiver,
8680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   GlobalObject* holder,
8780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSGlobalPropertyCell* cell,
8880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   bool is_dont_delete);
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadField(String* name,
9480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       JSObject* receiver,
9580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       JSObject* holder,
9680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       int field_index);
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadCallback(
9980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      String* name,
10080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      JSObject* receiver,
10180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      JSObject* holder,
10280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      AccessorInfo* callback);
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadConstant(String* name,
10580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                          JSObject* receiver,
10680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                          JSObject* holder,
10780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                          Object* value);
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadInterceptor(String* name,
11080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                             JSObject* receiver,
11180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                             JSObject* holder);
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadArrayLength(String* name,
11480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                             JSArray* receiver);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadStringLength(String* name,
11780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                              String* receiver);
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedLoadFunctionPrototype(
12080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      String* name,
12180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      JSFunction* receiver);
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeStoreField(String* name,
12680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSObject* receiver,
12780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   int field_index,
12880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   Map* transition = NULL);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeStoreNormal();
1318defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeStoreGlobal(String* name,
13380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                    GlobalObject* receiver,
13480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                    JSGlobalPropertyCell* cell);
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeStoreCallback(String* name,
13780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                      JSObject* receiver,
13880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                      AccessorInfo* callback);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeStoreInterceptor(String* name,
14180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                         JSObject* receiver);
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeKeyedStoreField(String* name,
14680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        JSObject* receiver,
14780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        int field_index,
14880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        Map* transition = NULL);
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallField(int argc,
15380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  InLoopFlag in_loop,
15480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  Code::Kind,
15580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  String* name,
15680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  Object* object,
15780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  JSObject* holder,
15880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  int index);
15980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
16080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallConstant(int argc,
16180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     InLoopFlag in_loop,
16280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     Code::Kind,
16380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     String* name,
16480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     Object* object,
16580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSObject* holder,
16680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                     JSFunction* function);
16780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
16880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallNormal(int argc,
16980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   InLoopFlag in_loop,
17080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   Code::Kind,
17180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   String* name,
17280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSObject* receiver);
17380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
17480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallInterceptor(int argc,
17580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        Code::Kind,
17680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        String* name,
17780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        Object* object,
17880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        JSObject* holder);
17980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
18080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallGlobal(int argc,
18180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   InLoopFlag in_loop,
18280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   Code::Kind,
18380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   String* name,
18480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSObject* receiver,
18580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   GlobalObject* holder,
18680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSGlobalPropertyCell* cell,
18780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   JSFunction* function);
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallInitialize(int argc,
19280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       InLoopFlag in_loop,
19380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       Code::Kind kind);
1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
19580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallPreMonomorphic(int argc,
19680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                           InLoopFlag in_loop,
19780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                           Code::Kind kind);
1987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
19980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallNormal(int argc,
20080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   InLoopFlag in_loop,
20180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                   Code::Kind kind);
2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
20380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallMegamorphic(int argc,
20480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        InLoopFlag in_loop,
20580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                        Code::Kind kind);
2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
20780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallMiss(int argc, Code::Kind kind);
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Finds the Code object stored in the Heap::non_monomorphic_cache().
21080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Code* FindCallInitialize(int argc,
21180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  InLoopFlag in_loop,
21280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                  Code::Kind kind);
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
21580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallDebugBreak(int argc,
21680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                       Code::Kind kind);
2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
21880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  MUST_USE_RESULT static Object* ComputeCallDebugPrepareStepIn(int argc,
21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                                               Code::Kind kind);
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update cache for entry hash(name, map).
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Code* Set(String* name, Map* map, Code* code);
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear the lookup table (@ mark compact collection).
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void Clear();
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for probing the stub cache table.
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If extra != no_reg it might be used as am extra scratch register.
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateProbe(MacroAssembler* masm,
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Code::Flags flags,
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register receiver,
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register name,
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch,
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register extra);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum Table {
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kPrimary,
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    kSecondary
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class SCTableReference;
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kPrimaryTableSize = 2048;
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSecondaryTableSize = 512;
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Entry primary_[];
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Entry secondary_[];
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Computes the hashed offsets for primary and secondary caches.
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int PrimaryOffset(String* name, Code::Flags flags, Map* map) {
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // This works well because the heap object tag size and the hash
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // shift are equal.  Shifting down the length field to get the
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // hash code would effectively throw away two bits of the hash
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // code.
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(kHeapObjectTagSize == String::kHashShift);
256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Compute the hash of the name (use entire hash field).
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(name->HasHashCode());
258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    uint32_t field = name->hash_field();
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Using only the low bits in 64-bit mode is unlikely to increase the
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // risk of collision even if the heap is spread over an area larger than
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // 4Gb (and not at all if it isn't).
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t map_low32bits =
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // We always set the in_loop bit to zero when generating the lookup code
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // so do it here too so the hash codes match.
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t iflags =
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Base the offset on a simple combination of name, flags, and map.
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t key = (map_low32bits + field) ^ iflags;
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int SecondaryOffset(String* name, Code::Flags flags, int seed) {
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Use the seed from the primary cache in the secondary cache.
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t string_low32bits =
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // We always set the in_loop bit to zero when generating the lookup code
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // so do it here too so the hash codes match.
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t iflags =
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask);
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t key = seed - string_low32bits + iflags;
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute the entry for a given offset in exactly the same way as
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // we do in generated code.  We generate an hash code that already
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ends in String::kHashShift 0s.  Then we shift it so it is a multiple
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of sizeof(Entry).  This makes it easier to avoid making mistakes
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in the hashed offset computations.
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static Entry* entry(Entry* table, int offset) {
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const int shift_amount = kPointerSizeLog2 + 1 - String::kHashShift;
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return reinterpret_cast<Entry*>(
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<Address>(table) + (offset << shift_amount));
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SCTableReference {
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static SCTableReference keyReference(StubCache::Table table) {
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return SCTableReference(
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<Address>(&first_entry(table)->key));
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static SCTableReference valueReference(StubCache::Table table) {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return SCTableReference(
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<Address>(&first_entry(table)->value));
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address address() const { return address_; }
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit SCTableReference(Address address) : address_(address) {}
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static StubCache::Entry* first_entry(StubCache::Table table) {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    switch (table) {
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case StubCache::kPrimary: return StubCache::primary_;
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      case StubCache::kSecondary: return StubCache::secondary_;
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    UNREACHABLE();
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address address_;
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for callbacks.
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadCallbackProperty(Arguments args);
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* StoreCallbackProperty(Arguments args);
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support functions for IC stubs for interceptors.
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorOnly(Arguments args);
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorForLoad(Arguments args);
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* LoadPropertyWithInterceptorForCall(Arguments args);
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* StoreInterceptorProperty(Arguments args);
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* CallInterceptorProperty(Arguments args);
342402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuObject* KeyedLoadPropertyWithInterceptor(Arguments args);
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The stub compiler compiles stubs for the stub cache.
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StubCompiler BASE_EMBEDDED {
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum CheckType {
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RECEIVER_MAP_CHECK,
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    STRING_CHECK,
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    NUMBER_CHECK,
3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    BOOLEAN_CHECK
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StubCompiler() : scope_(), masm_(NULL, 256), failure_(NULL) { }
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallInitialize(Code::Flags flags);
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallPreMonomorphic(Code::Flags flags);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallNormal(Code::Flags flags);
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallMegamorphic(Code::Flags flags);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallMiss(Code::Flags flags);
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallDebugBreak(Code::Flags flags);
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallDebugPrepareStepIn(Code::Flags flags);
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Static functions for generating parts of stubs.
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  int index,
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                  Register prototype);
371402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
3727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Generates prototype loading code that uses the objects from the
3737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // context we were in when this function was called.  This ties the
3747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // generated code to a particular context and so must not be used in
3757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // cases where the generated code is not allowed to have references
3767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // to objects from a context.
3777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
3787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                                        int index,
3797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                                        Register prototype);
3807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateFastPropertyLoad(MacroAssembler* masm,
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Register dst, Register src,
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       JSObject* holder, int index);
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadArrayLength(MacroAssembler* masm,
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register receiver,
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register scratch,
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Label* miss_label);
389402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadStringLength(MacroAssembler* masm,
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Register receiver,
392402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                       Register scratch1,
393402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                       Register scratch2,
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Label* miss_label);
395402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register receiver,
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register scratch1,
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register scratch2,
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Label* miss_label);
401402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateStoreField(MacroAssembler* masm,
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSObject* object,
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 int index,
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Map* transition,
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register receiver_reg,
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register name_reg,
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Register scratch,
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 Label* miss_label);
410402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4138defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Generates code that verifies that the property holder has not changed
4148defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // (checking maps of objects in the prototype chain for fast and global
4158defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // objects or doing negative lookup for slow objects, ensures that the
4168defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // property cells for global objects are still empty) and checks that the map
4178defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // of the holder has not changed. If necessary the function also generates
4188defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // code for security check in case of global object holders. Helps to make
4198defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // sure that the current IC is still valid.
4208defd9ff6930b4e24729971a61cf7469daf119beSteve Block  //
4218defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // The scratch and holder registers are always clobbered, but the object
4228defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // register is only clobbered if it the same as the holder register. The
4238defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // function returns a register containing the holder - either object_reg or
4248defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // holder_reg.
4258defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // The function can optionally (when save_at_depth !=
4268defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // kInvalidProtoDepth) save the object at the given depth by moving
4278defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // it to [esp + kPointerSize].
428402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
429402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Register CheckPrototypes(JSObject* object,
430402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           Register object_reg,
431402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           JSObject* holder,
432402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           Register holder_reg,
4333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch1,
4343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch2,
435402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           String* name,
4363bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Label* miss) {
4373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
4383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           scratch2, name, kInvalidProtoDepth, miss);
439402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
440402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Register CheckPrototypes(JSObject* object,
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Register object_reg,
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           JSObject* holder,
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Register holder_reg,
4453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch1,
4463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Register scratch2,
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           String* name,
448402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                           int save_at_depth,
4493bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                           Label* miss);
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCodeWithFlags(Code::Flags flags, const char* name);
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCodeWithFlags(Code::Flags flags, String* name);
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_failure(Failure* failure) { failure_ = failure; }
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GenerateLoadField(JSObject* object,
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         JSObject* holder,
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register receiver,
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register scratch1,
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register scratch2,
4633bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                         Register scratch3,
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         int index,
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         String* name,
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Label* miss);
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
468e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  bool GenerateLoadCallback(JSObject* object,
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            JSObject* holder,
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register receiver,
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register name_reg,
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch1,
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch2,
4743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                            Register scratch3,
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            AccessorInfo* callback,
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name,
477e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                            Label* miss,
478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                            Failure** failure);
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GenerateLoadConstant(JSObject* object,
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            JSObject* holder,
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register receiver,
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch1,
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register scratch2,
4853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                            Register scratch3,
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Object* value,
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name,
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Label* miss);
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GenerateLoadInterceptor(JSObject* object,
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               JSObject* holder,
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               LookupResult* lookup,
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register receiver,
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register name_reg,
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch1,
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch2,
4973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                               Register scratch3,
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               String* name,
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Label* miss);
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  static void LookupPostInterceptor(JSObject* holder,
5024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                                    String* name,
5034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                                    LookupResult* lookup);
5044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope_;
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Failure* failure_;
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LoadStubCompiler: public StubCompiler {
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
5146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* CompileLoadNonexistent(String* name,
5156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 JSObject* object,
5166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 JSObject* last);
5176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadField(JSObject* object,
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           JSObject* holder,
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           int index,
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           String* name);
5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
523e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Object* CompileLoadCallback(String* name,
524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                              JSObject* object,
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* holder,
526e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                              AccessorInfo* callback);
5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadConstant(JSObject* object,
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* holder,
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Object* value,
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              String* name);
5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadInterceptor(JSObject* object,
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSObject* holder,
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 String* name);
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadGlobal(JSObject* object,
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            GlobalObject* holder,
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            JSGlobalPropertyCell* cell,
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name,
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            bool is_dont_delete);
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode(PropertyType type, String* name);
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedLoadStubCompiler: public StubCompiler {
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadField(String* name,
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           JSObject* object,
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           JSObject* holder,
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           int index);
5546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadCallback(String* name,
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* object,
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* holder,
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              AccessorInfo* callback);
5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadConstant(String* name,
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* object,
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* holder,
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Object* value);
5646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadInterceptor(JSObject* object,
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSObject* holder,
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 String* name);
5686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadArrayLength(String* name);
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadStringLength(String* name);
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileLoadFunctionPrototype(String* name);
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode(PropertyType type, String* name);
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StoreStubCompiler: public StubCompiler {
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileStoreField(JSObject* object,
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            int index,
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Map* transition,
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name);
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileStoreCallback(JSObject* object,
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               AccessorInfo* callbacks,
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               String* name);
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileStoreInterceptor(JSObject* object, String* name);
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileStoreGlobal(GlobalObject* object,
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             JSGlobalPropertyCell* holder,
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             String* name);
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode(PropertyType type, String* name);
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass KeyedStoreStubCompiler: public StubCompiler {
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileStoreField(JSObject* object,
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            int index,
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Map* transition,
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name);
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode(PropertyType type, String* name);
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// List of functions with custom constant call IC stubs.
61125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen//
61225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Installation of custom call generators for the selected builtins is
61325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// handled by the bootstrapper.
61425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen//
61559151504615d929945dc59db37bf1166937748c6Steve Block// Each entry has a name of a global function (lowercased), a flag
61659151504615d929945dc59db37bf1166937748c6Steve Block// controlling whether the generator is set on the function itself or
61759151504615d929945dc59db37bf1166937748c6Steve Block// on its instance prototype, a name of a builtin function on the
61859151504615d929945dc59db37bf1166937748c6Steve Block// function or its instance prototype (the one the generator is set
61959151504615d929945dc59db37bf1166937748c6Steve Block// for), and a name of a generator itself (used to build ids and
62059151504615d929945dc59db37bf1166937748c6Steve Block// generator function names).
62159151504615d929945dc59db37bf1166937748c6Steve Block#define CUSTOM_CALL_IC_GENERATORS(V)                          \
62259151504615d929945dc59db37bf1166937748c6Steve Block  V(array, INSTANCE_PROTOTYPE, push, ArrayPush)               \
62359151504615d929945dc59db37bf1166937748c6Steve Block  V(array, INSTANCE_PROTOTYPE, pop, ArrayPop)                 \
62459151504615d929945dc59db37bf1166937748c6Steve Block  V(string, INSTANCE_PROTOTYPE, charCodeAt, StringCharCodeAt) \
62559151504615d929945dc59db37bf1166937748c6Steve Block  V(string, INSTANCE_PROTOTYPE, charAt, StringCharAt)         \
62659151504615d929945dc59db37bf1166937748c6Steve Block  V(string, FUNCTION, fromCharCode, StringFromCharCode)
62725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
62825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CallStubCompiler: public StubCompiler {
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
63159151504615d929945dc59db37bf1166937748c6Steve Block  enum CustomGeneratorOwner {
63259151504615d929945dc59db37bf1166937748c6Steve Block    FUNCTION,
63359151504615d929945dc59db37bf1166937748c6Steve Block    INSTANCE_PROTOTYPE
63459151504615d929945dc59db37bf1166937748c6Steve Block  };
63559151504615d929945dc59db37bf1166937748c6Steve Block
63625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  enum {
63759151504615d929945dc59db37bf1166937748c6Steve Block#define DECLARE_CALL_GENERATOR_ID(ignored1, ignore2, ignored3, name) \
63825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen    k##name##CallGenerator,
63925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen    CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR_ID)
64025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef DECLARE_CALL_GENERATOR_ID
64125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen    kNumCallGenerators
64225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  };
64325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
6448defd9ff6930b4e24729971a61cf7469daf119beSteve Block  CallStubCompiler(int argc,
6458defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   InLoopFlag in_loop,
6468defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   Code::Kind kind,
6478defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   InlineCacheHolderFlag cache_holder);
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
649402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* CompileCallField(JSObject* object,
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           JSObject* holder,
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           int index,
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           String* name);
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallConstant(Object* object,
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSObject* holder,
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              JSFunction* function,
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              String* name,
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              CheckType check);
658402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* CompileCallInterceptor(JSObject* object,
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 JSObject* holder,
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 String* name);
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileCallGlobal(JSObject* object,
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            GlobalObject* holder,
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            JSGlobalPropertyCell* cell,
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            JSFunction* function,
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            String* name);
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66759151504615d929945dc59db37bf1166937748c6Steve Block  // Compiles a custom call constant/global IC using the generator
66859151504615d929945dc59db37bf1166937748c6Steve Block  // with given id. For constant calls cell is NULL.
66925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  Object* CompileCustomCall(int generator_id,
67025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                            Object* object,
67125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                            JSObject* holder,
67259151504615d929945dc59db37bf1166937748c6Steve Block                            JSGlobalPropertyCell* cell,
67325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                            JSFunction* function,
67459151504615d929945dc59db37bf1166937748c6Steve Block                            String* name);
6756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
67659151504615d929945dc59db37bf1166937748c6Steve Block#define DECLARE_CALL_GENERATOR(ignored1, ignored2, ignored3, name) \
67759151504615d929945dc59db37bf1166937748c6Steve Block  Object* Compile##name##Call(Object* object,                      \
67859151504615d929945dc59db37bf1166937748c6Steve Block                              JSObject* holder,                    \
67959151504615d929945dc59db37bf1166937748c6Steve Block                              JSGlobalPropertyCell* cell,          \
68059151504615d929945dc59db37bf1166937748c6Steve Block                              JSFunction* function,                \
68159151504615d929945dc59db37bf1166937748c6Steve Block                              String* fname);
68225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
68325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef DECLARE_CALL_GENERATOR
6846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const ParameterCount arguments_;
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const InLoopFlag in_loop_;
6887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  const Code::Kind kind_;
6898defd9ff6930b4e24729971a61cf7469daf119beSteve Block  const InlineCacheHolderFlag cache_holder_;
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const ParameterCount& arguments() { return arguments_; }
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode(PropertyType type, String* name);
69425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
69525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Convenience function. Calls GetCode above passing
69625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // CONSTANT_FUNCTION type and the name of the given function.
69725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  Object* GetCode(JSFunction* function);
6987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
6997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void GenerateNameCheck(String* name, Label* miss);
7007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
70159151504615d929945dc59db37bf1166937748c6Steve Block  void GenerateGlobalReceiverCheck(JSObject* object,
70259151504615d929945dc59db37bf1166937748c6Steve Block                                   JSObject* holder,
70359151504615d929945dc59db37bf1166937748c6Steve Block                                   String* name,
70459151504615d929945dc59db37bf1166937748c6Steve Block                                   Label* miss);
70559151504615d929945dc59db37bf1166937748c6Steve Block
70659151504615d929945dc59db37bf1166937748c6Steve Block  // Generates code to load the function from the cell checking that
70759151504615d929945dc59db37bf1166937748c6Steve Block  // it still contains the same function.
70859151504615d929945dc59db37bf1166937748c6Steve Block  void GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
70959151504615d929945dc59db37bf1166937748c6Steve Block                                    JSFunction* function,
71059151504615d929945dc59db37bf1166937748c6Steve Block                                    Label* miss);
71159151504615d929945dc59db37bf1166937748c6Steve Block
712bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Generates a jump to CallIC miss stub. Returns Failure if the jump cannot
713bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // be generated.
714bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  Object* GenerateMissBranch();
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ConstructStubCompiler: public StubCompiler {
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  explicit ConstructStubCompiler() {}
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* CompileConstructStub(SharedFunctionInfo* shared);
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* GetCode();
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Holds information about possible function call optimizations.
7306ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockclass CallOptimization BASE_EMBEDDED {
7316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block public:
7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  explicit CallOptimization(LookupResult* lookup);
7336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  explicit CallOptimization(JSFunction* function);
7356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_constant_call() const {
7376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return constant_function_ != NULL;
7386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSFunction* constant_function() const {
7416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(constant_function_ != NULL);
7426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return constant_function_;
7436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_simple_api_call() const {
7466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return is_simple_api_call_;
7476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* expected_receiver_type() const {
7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(is_simple_api_call_);
7516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return expected_receiver_type_;
7526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CallHandlerInfo* api_call_info() const {
7556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(is_simple_api_call_);
7566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return api_call_info_;
7576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Returns the depth of the object having the expected type in the
7606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // prototype chain between the two arguments.
7616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int GetPrototypeDepthOfExpectedType(JSObject* object,
7626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      JSObject* holder) const;
7636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
7656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Initialize(JSFunction* function);
7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Determines whether the given function can be called using the
7686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // fast api call builtin.
7696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AnalyzePossibleApiFunction(JSFunction* function);
7706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSFunction* constant_function_;
7726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool is_simple_api_call_;
7736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* expected_receiver_type_;
7746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CallHandlerInfo* api_call_info_;
7756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block};
7766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_STUB_CACHE_H_
780