blob: 6d70d3477d5e8586b4c06f610f79e685840d251e [file] [log] [blame]
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_STUB_CACHE_H_
29#define V8_STUB_CACHE_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000032#include "arguments.h"
danno@chromium.orgca29dd82013-04-26 11:59:48 +000033#include "code-stubs.h"
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +000034#include "ic-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035#include "macro-assembler.h"
ager@chromium.orgea91cc52011-05-23 06:06:11 +000036#include "objects.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038
kasperl@chromium.org71affb52009-05-26 05:44:31 +000039namespace v8 {
40namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041
42
43// The stub cache is used for megamorphic calls and property accesses.
44// It maps (map, name, type)->Code*
45
46// The design of the table uses the inline cache stubs used for
47// mono-morphic calls. The beauty of this, we do not have to
48// invalidate the cache whenever a prototype map is changed. The stub
49// validates the map chain as in the mono-morphic case.
50
ricow@chromium.orgddd545c2011-08-24 12:02:41 +000051class SmallMapList;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000052class StubCache;
53
ricow@chromium.orgddd545c2011-08-24 12:02:41 +000054
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000055class SCTableReference {
56 public:
57 Address address() const { return address_; }
58
59 private:
60 explicit SCTableReference(Address address) : address_(address) {}
61
62 Address address_;
63
64 friend class StubCache;
65};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066
kasperl@chromium.orga5551262010-12-07 12:49:48 +000067
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000068class StubCache {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000069 public:
70 struct Entry {
ulan@chromium.org750145a2013-03-07 15:14:13 +000071 Name* key;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072 Code* value;
ulan@chromium.org812308e2012-02-29 15:58:45 +000073 Map* map;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000074 };
75
ulan@chromium.org812308e2012-02-29 15:58:45 +000076 void Initialize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000078 Handle<JSObject> StubHolder(Handle<JSObject> receiver,
79 Handle<JSObject> holder);
80
ulan@chromium.org750145a2013-03-07 15:14:13 +000081 Handle<Code> FindIC(Handle<Name> name,
danno@chromium.orgca29dd82013-04-26 11:59:48 +000082 Handle<Map> stub_holder_map,
83 Code::Kind kind,
84 Code::StubType type,
85 Code::ExtraICState extra_state = Code::kNoExtraICState);
86
87 Handle<Code> FindIC(Handle<Name> name,
ulan@chromium.org750145a2013-03-07 15:14:13 +000088 Handle<JSObject> stub_holder,
89 Code::Kind kind,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +000090 Code::StubType type,
91 Code::ExtraICState extra_state = Code::kNoExtraICState);
ulan@chromium.org750145a2013-03-07 15:14:13 +000092
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +000093 Handle<Code> FindHandler(
94 Handle<Name> name,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +000095 Handle<JSObject> receiver,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +000096 Handle<JSObject> stub_holder,
97 Code::Kind kind,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +000098 Code::StubType type);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000099
100 Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver,
101 Handle<Code> handler,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000102 Handle<Name> name);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000103 Handle<Code> ComputeKeyedMonomorphicIC(Handle<JSObject> receiver,
104 Handle<Code> handler,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000105 Handle<Name> name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106
107 // Computes the right stub matching. Inserts the result in the
108 // cache before returning. This might compile a stub if needed.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000109 Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000110 Handle<JSObject> object);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000111
ulan@chromium.org750145a2013-03-07 15:14:13 +0000112 Handle<Code> ComputeLoadField(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000113 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000114 Handle<JSObject> holder,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000115 PropertyIndex field_index,
116 Representation representation);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117
ulan@chromium.org750145a2013-03-07 15:14:13 +0000118 Handle<Code> ComputeLoadCallback(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000119 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000120 Handle<JSObject> holder,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000121 Handle<ExecutableAccessorInfo> callback);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000122
ulan@chromium.org750145a2013-03-07 15:14:13 +0000123 Handle<Code> ComputeLoadViaGetter(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000124 Handle<JSObject> object,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000125 Handle<JSObject> holder,
126 Handle<JSFunction> getter);
127
ulan@chromium.org750145a2013-03-07 15:14:13 +0000128 Handle<Code> ComputeLoadConstant(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000129 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000130 Handle<JSObject> holder,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000131 Handle<JSFunction> value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000132
ulan@chromium.org750145a2013-03-07 15:14:13 +0000133 Handle<Code> ComputeLoadInterceptor(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000134 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000135 Handle<JSObject> holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000136
ulan@chromium.org750145a2013-03-07 15:14:13 +0000137 Handle<Code> ComputeLoadNormal(Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000138 Handle<JSObject> object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139
ulan@chromium.org750145a2013-03-07 15:14:13 +0000140 Handle<Code> ComputeLoadGlobal(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000141 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000142 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000143 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000144 bool is_dont_delete);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000145
146 // ---
147
ulan@chromium.org750145a2013-03-07 15:14:13 +0000148 Handle<Code> ComputeKeyedLoadField(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000149 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000150 Handle<JSObject> holder,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000151 PropertyIndex field_index,
152 Representation representation);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000153
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000154 Handle<Code> ComputeKeyedLoadCallback(
ulan@chromium.org750145a2013-03-07 15:14:13 +0000155 Handle<Name> name,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000156 Handle<JSObject> object,
157 Handle<JSObject> holder,
158 Handle<ExecutableAccessorInfo> callback);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000159
ulan@chromium.org750145a2013-03-07 15:14:13 +0000160 Handle<Code> ComputeKeyedLoadConstant(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000161 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000162 Handle<JSObject> holder,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000163 Handle<JSFunction> value);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000164
ulan@chromium.org750145a2013-03-07 15:14:13 +0000165 Handle<Code> ComputeKeyedLoadInterceptor(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000166 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000167 Handle<JSObject> holder);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169 // ---
170
ulan@chromium.org750145a2013-03-07 15:14:13 +0000171 Handle<Code> ComputeStoreField(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000172 Handle<JSObject> object,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000173 LookupResult* lookup,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174 StrictModeFlag strict_mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000176 Handle<Code> ComputeStoreTransition(Handle<Name> name,
177 Handle<JSObject> object,
178 LookupResult* lookup,
179 Handle<Map> transition,
180 StrictModeFlag strict_mode);
181
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000182 Handle<Code> ComputeStoreNormal(StrictModeFlag strict_mode);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000183
ulan@chromium.org750145a2013-03-07 15:14:13 +0000184 Handle<Code> ComputeStoreGlobal(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000185 Handle<GlobalObject> object,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000186 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000187 StrictModeFlag strict_mode);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000188
ulan@chromium.org750145a2013-03-07 15:14:13 +0000189 Handle<Code> ComputeStoreCallback(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000190 Handle<JSObject> object,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000191 Handle<JSObject> holder,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000192 Handle<ExecutableAccessorInfo> callback,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000193 StrictModeFlag strict_mode);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000194
ulan@chromium.org750145a2013-03-07 15:14:13 +0000195 Handle<Code> ComputeStoreViaSetter(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000196 Handle<JSObject> object,
svenpanne@chromium.org619781a2012-07-05 08:22:44 +0000197 Handle<JSObject> holder,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000198 Handle<JSFunction> setter,
199 StrictModeFlag strict_mode);
200
ulan@chromium.org750145a2013-03-07 15:14:13 +0000201 Handle<Code> ComputeStoreInterceptor(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000202 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000203 StrictModeFlag strict_mode);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000204
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205 // ---
206
ulan@chromium.org750145a2013-03-07 15:14:13 +0000207 Handle<Code> ComputeKeyedStoreField(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000208 Handle<JSObject> object,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000209 LookupResult* lookup,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000210 StrictModeFlag strict_mode);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000211 Handle<Code> ComputeKeyedStoreTransition(Handle<Name> name,
212 Handle<JSObject> object,
213 LookupResult* lookup,
214 Handle<Map> transition,
215 StrictModeFlag strict_mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000217 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map);
218
219 Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map,
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000220 StrictModeFlag strict_mode,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000221 KeyedAccessStoreMode store_mode);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000222
lrn@chromium.org303ada72010-10-27 09:33:13 +0000223 // ---
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000225 Handle<Code> ComputeCallField(int argc,
226 Code::Kind,
227 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000228 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000229 Handle<Object> object,
230 Handle<JSObject> holder,
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000231 PropertyIndex index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000233 Handle<Code> ComputeCallConstant(int argc,
234 Code::Kind,
235 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000236 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000237 Handle<Object> object,
238 Handle<JSObject> holder,
239 Handle<JSFunction> function);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000240
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000241 Handle<Code> ComputeCallInterceptor(int argc,
242 Code::Kind,
243 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000244 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000245 Handle<Object> object,
246 Handle<JSObject> holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000248 Handle<Code> ComputeCallGlobal(int argc,
249 Code::Kind,
250 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000251 Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000252 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000253 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000254 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000255 Handle<JSFunction> function);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000256
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257 // ---
258
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000259 Handle<Code> ComputeCallInitialize(int argc, RelocInfo::Mode mode);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000260
lrn@chromium.org34e60782011-09-15 07:25:40 +0000261 Handle<Code> ComputeKeyedCallInitialize(int argc);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000262
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000263 Handle<Code> ComputeCallPreMonomorphic(int argc,
264 Code::Kind kind,
265 Code::ExtraICState extra_state);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000266
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000267 Handle<Code> ComputeCallNormal(int argc,
268 Code::Kind kind,
269 Code::ExtraICState state);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000270
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000271 Handle<Code> ComputeCallArguments(int argc);
whesse@chromium.org7b260152011-06-20 15:33:18 +0000272
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000273 Handle<Code> ComputeCallMegamorphic(int argc,
274 Code::Kind kind,
275 Code::ExtraICState state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000276
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000277 Handle<Code> ComputeCallMiss(int argc,
278 Code::Kind kind,
279 Code::ExtraICState state);
280
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000281 // ---
282
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000283 Handle<Code> ComputeCompareNil(Handle<Map> receiver_map,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000284 CompareNilICStub& stub);
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000285
286 // ---
287
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000288 Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps);
289 Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000290 KeyedAccessStoreMode store_mode,
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000291 StrictModeFlag strict_mode);
292
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000293 Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps,
294 CodeHandleList* handlers,
danno@chromium.orgf005df62013-04-30 16:36:45 +0000295 int number_of_valid_maps,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000296 Handle<Name> name);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000298 // Finds the Code object stored in the Heap::non_monomorphic_cache().
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000299 Code* FindCallInitialize(int argc, RelocInfo::Mode mode, Code::Kind kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000300
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000301#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000302 Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000303
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000304 Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000305#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000307 // Update cache for entry hash(name, map).
ulan@chromium.org750145a2013-03-07 15:14:13 +0000308 Code* Set(Name* name, Map* map, Code* code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000309
310 // Clear the lookup table (@ mark compact collection).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000311 void Clear();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000312
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000313 // Collect all maps that match the name and flags.
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000314 void CollectMatchingMaps(SmallMapList* types,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000315 Handle<Name> name,
ricow@chromium.org7ad65222011-12-19 12:13:11 +0000316 Code::Flags flags,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000317 Handle<Context> native_context,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000318 Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000319
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000320 // Generate code for probing the stub cache table.
ulan@chromium.org812308e2012-02-29 15:58:45 +0000321 // Arguments extra, extra2 and extra3 may be used to pass additional scratch
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000322 // registers. Set to no_reg if not needed.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000323 void GenerateProbe(MacroAssembler* masm,
324 Code::Flags flags,
325 Register receiver,
326 Register name,
327 Register scratch,
328 Register extra,
ulan@chromium.org812308e2012-02-29 15:58:45 +0000329 Register extra2 = no_reg,
330 Register extra3 = no_reg);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000331
332 enum Table {
333 kPrimary,
334 kSecondary
335 };
336
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000337
338 SCTableReference key_reference(StubCache::Table table) {
339 return SCTableReference(
340 reinterpret_cast<Address>(&first_entry(table)->key));
341 }
342
343
ulan@chromium.org812308e2012-02-29 15:58:45 +0000344 SCTableReference map_reference(StubCache::Table table) {
345 return SCTableReference(
346 reinterpret_cast<Address>(&first_entry(table)->map));
347 }
348
349
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000350 SCTableReference value_reference(StubCache::Table table) {
351 return SCTableReference(
352 reinterpret_cast<Address>(&first_entry(table)->value));
353 }
354
355
356 StubCache::Entry* first_entry(StubCache::Table table) {
357 switch (table) {
358 case StubCache::kPrimary: return StubCache::primary_;
359 case StubCache::kSecondary: return StubCache::secondary_;
360 }
361 UNREACHABLE();
362 return NULL;
363 }
364
lrn@chromium.org7516f052011-03-30 08:52:27 +0000365 Isolate* isolate() { return isolate_; }
366 Heap* heap() { return isolate()->heap(); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000367 Factory* factory() { return isolate()->factory(); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000369 private:
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000370 explicit StubCache(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000371
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000372 Handle<Code> ComputeCallInitialize(int argc,
373 RelocInfo::Mode mode,
374 Code::Kind kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000375
ulan@chromium.org812308e2012-02-29 15:58:45 +0000376 // The stub cache has a primary and secondary level. The two levels have
377 // different hashing algorithms in order to avoid simultaneous collisions
378 // in both caches. Unlike a probing strategy (quadratic or otherwise) the
379 // update strategy on updates is fairly clear and simple: Any existing entry
380 // in the primary cache is moved to the secondary cache, and secondary cache
381 // entries are overwritten.
382
383 // Hash algorithm for the primary table. This algorithm is replicated in
384 // assembler for every architecture. Returns an index into the table that
385 // is scaled by 1 << kHeapObjectTagSize.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000386 static int PrimaryOffset(Name* name, Code::Flags flags, Map* map) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000387 // This works well because the heap object tag size and the hash
388 // shift are equal. Shifting down the length field to get the
389 // hash code would effectively throw away two bits of the hash
390 // code.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000391 STATIC_ASSERT(kHeapObjectTagSize == Name::kHashShift);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000392 // Compute the hash of the name (use entire hash field).
ager@chromium.org7c537e22008-10-16 08:43:32 +0000393 ASSERT(name->HasHashCode());
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000394 uint32_t field = name->hash_field();
ager@chromium.org9085a012009-05-11 19:22:57 +0000395 // Using only the low bits in 64-bit mode is unlikely to increase the
396 // risk of collision even if the heap is spread over an area larger than
397 // 4Gb (and not at all if it isn't).
398 uint32_t map_low32bits =
399 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000400 // We always set the in_loop bit to zero when generating the lookup code
401 // so do it here too so the hash codes match.
402 uint32_t iflags =
403 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000404 // Base the offset on a simple combination of name, flags, and map.
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000405 uint32_t key = (map_low32bits + field) ^ iflags;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000406 return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
407 }
408
ulan@chromium.org812308e2012-02-29 15:58:45 +0000409 // Hash algorithm for the secondary table. This algorithm is replicated in
410 // assembler for every architecture. Returns an index into the table that
411 // is scaled by 1 << kHeapObjectTagSize.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000412 static int SecondaryOffset(Name* name, Code::Flags flags, int seed) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000413 // Use the seed from the primary cache in the secondary cache.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000414 uint32_t name_low32bits =
ager@chromium.org9085a012009-05-11 19:22:57 +0000415 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
ulan@chromium.org812308e2012-02-29 15:58:45 +0000416 // We always set the in_loop bit to zero when generating the lookup code
417 // so do it here too so the hash codes match.
418 uint32_t iflags =
419 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000420 uint32_t key = (seed - name_low32bits) + iflags;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000421 return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
422 }
423
424 // Compute the entry for a given offset in exactly the same way as
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000425 // we do in generated code. We generate an hash code that already
ulan@chromium.org750145a2013-03-07 15:14:13 +0000426 // ends in Name::kHashShift 0s. Then we multiply it so it is a multiple
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000427 // of sizeof(Entry). This makes it easier to avoid making mistakes
428 // in the hashed offset computations.
danno@chromium.org40cb8782011-05-25 07:58:50 +0000429 static Entry* entry(Entry* table, int offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000430 const int multiplier = sizeof(*table) >> Name::kHashShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431 return reinterpret_cast<Entry*>(
ulan@chromium.org812308e2012-02-29 15:58:45 +0000432 reinterpret_cast<Address>(table) + offset * multiplier);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000434
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +0000435 static const int kPrimaryTableBits = 11;
436 static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
437 static const int kSecondaryTableBits = 9;
438 static const int kSecondaryTableSize = (1 << kSecondaryTableBits);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000439
440 Entry primary_[kPrimaryTableSize];
441 Entry secondary_[kSecondaryTableSize];
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000442 Isolate* isolate_;
443
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000444 friend class Isolate;
445 friend class SCTableReference;
446
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000447 DISALLOW_COPY_AND_ASSIGN(StubCache);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000448};
449
450
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000451// ------------------------------------------------------------------------
452
453
454// Support functions for IC stubs for callbacks.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000455DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000456
457
458// Support functions for IC stubs for interceptors.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000459DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly);
460DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad);
461DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall);
462DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty);
463DECLARE_RUNTIME_FUNCTION(MaybeObject*, CallInterceptorProperty);
464DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465
466
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000467enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
468enum IcCheckType { ELEMENT, PROPERTY };
469
470
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000471// The stub compilers compile stubs for the stub cache.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000472class StubCompiler BASE_EMBEDDED {
473 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000474 explicit StubCompiler(Isolate* isolate)
475 : isolate_(isolate), masm_(isolate, NULL, 256), failure_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000477 // Functions to compile either CallIC or KeyedCallIC. The specific kind
478 // is extracted from the code flags.
479 Handle<Code> CompileCallInitialize(Code::Flags flags);
480 Handle<Code> CompileCallPreMonomorphic(Code::Flags flags);
481 Handle<Code> CompileCallNormal(Code::Flags flags);
482 Handle<Code> CompileCallMegamorphic(Code::Flags flags);
483 Handle<Code> CompileCallArguments(Code::Flags flags);
484 Handle<Code> CompileCallMiss(Code::Flags flags);
485
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000486#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000487 Handle<Code> CompileCallDebugBreak(Code::Flags flags);
488 Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000489#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490
491 // Static functions for generating parts of stubs.
492 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
493 int index,
494 Register prototype);
ager@chromium.org5c838252010-02-19 08:53:10 +0000495
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000496 // Generates prototype loading code that uses the objects from the
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000497 // context we were in when this function was called. If the context
498 // has changed, a jump to miss is performed. This ties the generated
499 // code to a particular context and so must not be used in cases
500 // where the generated code is not allowed to have references to
501 // objects from a context.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000502 static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
503 int index,
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000504 Register prototype,
505 Label* miss);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000506
ager@chromium.org7c537e22008-10-16 08:43:32 +0000507 static void GenerateFastPropertyLoad(MacroAssembler* masm,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000508 Register dst,
509 Register src,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000510 bool inobject,
511 int index,
512 Representation representation);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514 static void GenerateLoadArrayLength(MacroAssembler* masm,
515 Register receiver,
516 Register scratch,
517 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000518
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000519 static void GenerateLoadStringLength(MacroAssembler* masm,
520 Register receiver,
ager@chromium.org5c838252010-02-19 08:53:10 +0000521 Register scratch1,
522 Register scratch2,
ager@chromium.org378b34e2011-01-28 08:04:38 +0000523 Label* miss_label,
524 bool support_wrappers);
ager@chromium.org5c838252010-02-19 08:53:10 +0000525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526 static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
527 Register receiver,
528 Register scratch1,
529 Register scratch2,
530 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000531
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000532 void GenerateStoreTransition(MacroAssembler* masm,
533 Handle<JSObject> object,
534 LookupResult* lookup,
535 Handle<Map> transition,
536 Handle<Name> name,
537 Register receiver_reg,
538 Register name_reg,
539 Register value_reg,
540 Register scratch1,
541 Register scratch2,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000542 Register scratch3,
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000543 Label* miss_label,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000544 Label* miss_restore_name,
545 Label* slow);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000546
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000547 void GenerateStoreField(MacroAssembler* masm,
548 Handle<JSObject> object,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000549 LookupResult* lookup,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000550 Register receiver_reg,
551 Register name_reg,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000552 Register value_reg,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000553 Register scratch1,
554 Register scratch2,
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000555 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000556
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000557 static Builtins::Name MissBuiltin(Code::Kind kind) {
558 switch (kind) {
559 case Code::LOAD_IC: return Builtins::kLoadIC_Miss;
560 case Code::STORE_IC: return Builtins::kStoreIC_Miss;
561 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss;
562 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss;
563 default: UNREACHABLE();
564 }
565 return Builtins::kLoadIC_Miss;
566 }
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000567 static Builtins::Name SlowBuiltin(Code::Kind kind) {
568 switch (kind) {
569 case Code::STORE_IC: return Builtins::kStoreIC_Slow;
570 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow;
571 default: UNREACHABLE();
572 }
573 return Builtins::kStoreIC_Slow;
574 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000575 static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +0000577 // Generates code that verifies that the property holder has not changed
578 // (checking maps of objects in the prototype chain for fast and global
579 // objects or doing negative lookup for slow objects, ensures that the
580 // property cells for global objects are still empty) and checks that the map
581 // of the holder has not changed. If necessary the function also generates
582 // code for security check in case of global object holders. Helps to make
583 // sure that the current IC is still valid.
584 //
585 // The scratch and holder registers are always clobbered, but the object
586 // register is only clobbered if it the same as the holder register. The
587 // function returns a register containing the holder - either object_reg or
588 // holder_reg.
589 // The function can optionally (when save_at_depth !=
590 // kInvalidProtoDepth) save the object at the given depth by moving
591 // it to [esp + kPointerSize].
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000592 Register CheckPrototypes(Handle<JSObject> object,
593 Register object_reg,
594 Handle<JSObject> holder,
595 Register holder_reg,
596 Register scratch1,
597 Register scratch2,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000598 Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000599 Label* miss,
600 PrototypeCheckType check = CHECK_ALL_MAPS) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000601 return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000602 scratch2, name, kInvalidProtoDepth, miss, check);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603 }
ager@chromium.org5c838252010-02-19 08:53:10 +0000604
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000605 Register CheckPrototypes(Handle<JSObject> object,
606 Register object_reg,
607 Handle<JSObject> holder,
608 Register holder_reg,
609 Register scratch1,
610 Register scratch2,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000611 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000612 int save_at_depth,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000613 Label* miss,
614 PrototypeCheckType check = CHECK_ALL_MAPS);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000616
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000617 protected:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000618 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000619 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000620
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000621 MacroAssembler* masm() { return &masm_; }
622 void set_failure(Failure* failure) { failure_ = failure; }
623
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000624 static void LookupPostInterceptor(Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000625 Handle<Name> name,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000626 LookupResult* lookup);
627
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000628 Isolate* isolate() { return isolate_; }
lrn@chromium.org7516f052011-03-30 08:52:27 +0000629 Heap* heap() { return isolate()->heap(); }
630 Factory* factory() { return isolate()->factory(); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000631
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000632 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000633
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634 private:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000635 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636 MacroAssembler masm_;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000637 Failure* failure_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638};
639
640
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000641enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS };
642
643
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000644class BaseLoadStubCompiler: public StubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645 public:
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000646 BaseLoadStubCompiler(Isolate* isolate, Register* registers)
647 : StubCompiler(isolate), registers_(registers) { }
648 virtual ~BaseLoadStubCompiler() { }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000649
650 Handle<Code> CompileLoadField(Handle<JSObject> object,
651 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000652 Handle<Name> name,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000653 PropertyIndex index,
654 Representation representation);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000655
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000656 Handle<Code> CompileLoadCallback(Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000657 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000658 Handle<Name> name,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000659 Handle<ExecutableAccessorInfo> callback);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000660
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000661 Handle<Code> CompileLoadConstant(Handle<JSObject> object,
662 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000663 Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000664 Handle<JSFunction> value);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000665
666 Handle<Code> CompileLoadInterceptor(Handle<JSObject> object,
667 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000668 Handle<Name> name);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000669
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000670 Handle<Code> CompileMonomorphicIC(Handle<Map> receiver_map,
671 Handle<Code> handler,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000672 Handle<Name> name);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000673 Handle<Code> CompilePolymorphicIC(MapHandleList* receiver_maps,
674 CodeHandleList* handlers,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000675 Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000676 Code::StubType type,
677 IcCheckType check);
678
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000679 protected:
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000680 Register HandlerFrontendHeader(Handle<JSObject> object,
681 Register object_reg,
682 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000683 Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000684 Label* success);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000685 void HandlerFrontendFooter(Label* success, Label* miss);
686
687 Register HandlerFrontend(Handle<JSObject> object,
688 Register object_reg,
689 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000690 Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000691 Label* success);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000692 Register CallbackHandlerFrontend(Handle<JSObject> object,
693 Register object_reg,
694 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000695 Handle<Name> name,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000696 Label* success,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000697 Handle<ExecutableAccessorInfo> callback);
698 void NonexistentHandlerFrontend(Handle<JSObject> object,
699 Handle<JSObject> last,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000700 Handle<Name> name,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000701 Label* success,
702 Handle<GlobalObject> global);
703
704 void GenerateLoadField(Register reg,
705 Handle<JSObject> holder,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000706 PropertyIndex field,
707 Representation representation);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000708 void GenerateLoadConstant(Handle<JSFunction> value);
709 void GenerateLoadCallback(Register reg,
710 Handle<ExecutableAccessorInfo> callback);
711 void GenerateLoadInterceptor(Register holder_reg,
712 Handle<JSObject> object,
713 Handle<JSObject> holder,
714 LookupResult* lookup,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000715 Handle<Name> name);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000716 void GenerateLoadPostInterceptor(Register reg,
717 Handle<JSObject> interceptor_holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000718 Handle<Name> name,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000719 LookupResult* lookup);
720
ulan@chromium.org750145a2013-03-07 15:14:13 +0000721 Handle<Code> GetICCode(Code::Kind kind,
722 Code::StubType type,
723 Handle<Name> name,
724 InlineCacheState state = MONOMORPHIC);
725
726 Handle<Code> GetCode(Code::Kind kind,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000727 Code::StubType type,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000728 Handle<Name> name);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000729
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000730 Register receiver() { return registers_[0]; }
731 Register name() { return registers_[1]; }
732 Register scratch1() { return registers_[2]; }
733 Register scratch2() { return registers_[3]; }
734 Register scratch3() { return registers_[4]; }
735 Register scratch4() { return registers_[5]; }
736
737 private:
738 virtual Code::Kind kind() = 0;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000739 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0;
ulan@chromium.org750145a2013-03-07 15:14:13 +0000740 virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0;
741 virtual void GenerateNameCheck(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000742 Register name_reg,
743 Label* miss) { }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000744 Register* registers_;
745};
746
747
748class LoadStubCompiler: public BaseLoadStubCompiler {
749 public:
750 explicit LoadStubCompiler(Isolate* isolate)
751 : BaseLoadStubCompiler(isolate, registers()) { }
752
753 Handle<Code> CompileLoadNonexistent(Handle<JSObject> object,
754 Handle<JSObject> last,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000755 Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000756 Handle<GlobalObject> global);
757
758 static void GenerateLoadViaGetter(MacroAssembler* masm,
759 Handle<JSFunction> getter);
760
761 Handle<Code> CompileLoadViaGetter(Handle<JSObject> object,
762 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000763 Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000764 Handle<JSFunction> getter);
765
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000766 Handle<Code> CompileLoadGlobal(Handle<JSObject> object,
767 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000768 Handle<PropertyCell> cell,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000769 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000770 bool is_dont_delete);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000771
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000772 static Register receiver() { return registers()[0]; }
773
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774 private:
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000775 static Register* registers();
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000776 virtual Code::Kind kind() { return Code::LOAD_IC; }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000777 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000778 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000779 return code->ic_state() == MONOMORPHIC
780 ? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
781 }
ulan@chromium.org750145a2013-03-07 15:14:13 +0000782 virtual void JitEvent(Handle<Name> name, Handle<Code> code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783};
784
785
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000786class KeyedLoadStubCompiler: public BaseLoadStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787 public:
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000788 explicit KeyedLoadStubCompiler(Isolate* isolate)
789 : BaseLoadStubCompiler(isolate, registers()) { }
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000790
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000791 Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
792
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000793 void CompileElementHandlers(MapHandleList* receiver_maps,
794 CodeHandleList* handlers);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000795
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000796 static void GenerateLoadDictionaryElement(MacroAssembler* masm);
797
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000798 static Register receiver() { return registers()[0]; }
799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800 private:
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000801 static Register* registers();
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000802 virtual Code::Kind kind() { return Code::KEYED_LOAD_IC; }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000803 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000804 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000805 return code->ic_state() == MONOMORPHIC
806 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
807 }
ulan@chromium.org750145a2013-03-07 15:14:13 +0000808 virtual void JitEvent(Handle<Name> name, Handle<Code> code);
809 virtual void GenerateNameCheck(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000810 Register name_reg,
811 Label* miss);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812};
813
814
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000815class BaseStoreStubCompiler: public StubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 public:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000817 BaseStoreStubCompiler(Isolate* isolate,
818 StrictModeFlag strict_mode,
819 Register* registers)
820 : StubCompiler(isolate),
821 strict_mode_(strict_mode),
822 registers_(registers) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000823
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000824 virtual ~BaseStoreStubCompiler() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000825
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000826 Handle<Code> CompileStoreTransition(Handle<JSObject> object,
827 LookupResult* lookup,
828 Handle<Map> transition,
829 Handle<Name> name);
830
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000831 Handle<Code> CompileStoreField(Handle<JSObject> object,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000832 LookupResult* lookup,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000833 Handle<Name> name);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000834
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000835 protected:
836 Handle<Code> GetICCode(Code::Kind kind,
837 Code::StubType type,
838 Handle<Name> name,
839 InlineCacheState state = MONOMORPHIC);
840
841 Handle<Code> GetCode(Code::Kind kind,
842 Code::StubType type,
843 Handle<Name> name);
844
845 void GenerateRestoreName(MacroAssembler* masm,
846 Label* label,
847 Handle<Name> name);
848
849 Register receiver() { return registers_[0]; }
850 Register name() { return registers_[1]; }
851 Register value() { return registers_[2]; }
852 Register scratch1() { return registers_[3]; }
853 Register scratch2() { return registers_[4]; }
854 Register scratch3() { return registers_[5]; }
855 StrictModeFlag strict_mode() { return strict_mode_; }
856 virtual Code::ExtraICState extra_state() { return strict_mode_; }
857
858 private:
859 virtual Code::Kind kind() = 0;
860 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0;
861 virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0;
862 virtual void GenerateNameCheck(Handle<Name> name,
863 Register name_reg,
864 Label* miss) { }
865 StrictModeFlag strict_mode_;
866 Register* registers_;
867};
868
869
870class StoreStubCompiler: public BaseStoreStubCompiler {
871 public:
872 StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
873 : BaseStoreStubCompiler(isolate, strict_mode, registers()) { }
874
875
ulan@chromium.org750145a2013-03-07 15:14:13 +0000876 Handle<Code> CompileStoreCallback(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000877 Handle<JSObject> object,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000878 Handle<JSObject> holder,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000879 Handle<ExecutableAccessorInfo> callback);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000880
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000881 static void GenerateStoreViaSetter(MacroAssembler* masm,
882 Handle<JSFunction> setter);
883
ulan@chromium.org750145a2013-03-07 15:14:13 +0000884 Handle<Code> CompileStoreViaSetter(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000885 Handle<JSObject> object,
svenpanne@chromium.org619781a2012-07-05 08:22:44 +0000886 Handle<JSObject> holder,
887 Handle<JSFunction> setter);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000888
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000889 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000890 Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000891
892 Handle<Code> CompileStoreGlobal(Handle<GlobalObject> object,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000893 Handle<PropertyCell> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000894 Handle<Name> name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000895
896 private:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000897 static Register* registers();
898 virtual Code::Kind kind() { return Code::STORE_IC; }
899 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
900 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
901 return code->ic_state() == MONOMORPHIC
902 ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
903 }
904 virtual void JitEvent(Handle<Name> name, Handle<Code> code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905};
906
907
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000908class KeyedStoreStubCompiler: public BaseStoreStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909 public:
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000910 KeyedStoreStubCompiler(Isolate* isolate,
911 StrictModeFlag strict_mode,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000912 KeyedAccessStoreMode store_mode)
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000913 : BaseStoreStubCompiler(isolate, strict_mode, registers()),
914 store_mode_(store_mode) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000915
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000916 Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000917
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000918 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps,
919 CodeHandleList* handler_stubs,
920 MapHandleList* transitioned_maps);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000921
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000922 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps);
923
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000924 static void GenerateStoreFastElement(MacroAssembler* masm,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000925 bool is_js_array,
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000926 ElementsKind element_kind,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000927 KeyedAccessStoreMode store_mode);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000928
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000929 static void GenerateStoreFastDoubleElement(MacroAssembler* masm,
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000930 bool is_js_array,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000931 KeyedAccessStoreMode store_mode);
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000932
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000933 static void GenerateStoreExternalArray(MacroAssembler* masm,
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000934 ElementsKind elements_kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000935
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000936 static void GenerateStoreDictionaryElement(MacroAssembler* masm);
937
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000938 protected:
939 virtual Code::ExtraICState extra_state() {
940 return Code::ComputeExtraICState(store_mode_, strict_mode());
941 }
ager@chromium.org9ee27ae2011-03-02 13:43:26 +0000942
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000943 private:
944 Register transition_map() {
945 return registers()[3];
946 }
947
948 static Register* registers();
949 virtual Code::Kind kind() { return Code::KEYED_STORE_IC; }
950 virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
951 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
952 return code->ic_state() == MONOMORPHIC
953 ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
954 }
955 virtual void JitEvent(Handle<Name> name, Handle<Code> code);
956 virtual void GenerateNameCheck(Handle<Name> name,
957 Register name_reg,
958 Label* miss);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000959 KeyedAccessStoreMode store_mode_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000960};
961
962
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000963// Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call
964// IC stubs.
965#define CUSTOM_CALL_IC_GENERATORS(V) \
966 V(ArrayPush) \
967 V(ArrayPop) \
968 V(StringCharCodeAt) \
969 V(StringCharAt) \
970 V(StringFromCharCode) \
971 V(MathFloor) \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000972 V(MathAbs) \
973 V(ArrayCode)
974
975
976#define SITE_SPECIFIC_CALL_GENERATORS(V) \
977 V(ArrayCode)
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000978
979
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000980class CallOptimization;
981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000982class CallStubCompiler: public StubCompiler {
983 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000984 CallStubCompiler(Isolate* isolate,
985 int argc,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +0000986 Code::Kind kind,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000987 Code::ExtraICState extra_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +0000988 InlineCacheHolderFlag cache_holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000989
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000990 Handle<Code> CompileCallField(Handle<JSObject> object,
991 Handle<JSObject> holder,
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000992 PropertyIndex index,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000993 Handle<Name> name);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000994
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +0000995 void CompileHandlerFrontend(Handle<Object> object,
996 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000997 Handle<Name> name,
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +0000998 CheckType check,
999 Label* success);
1000
1001 void CompileHandlerBackend(Handle<JSFunction> function);
1002
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001003 Handle<Code> CompileCallConstant(Handle<Object> object,
1004 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001005 Handle<Name> name,
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00001006 CheckType check,
1007 Handle<JSFunction> function);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001008
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001009 Handle<Code> CompileCallInterceptor(Handle<JSObject> object,
1010 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001011 Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001012
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001013 Handle<Code> CompileCallGlobal(Handle<JSObject> object,
1014 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00001015 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001016 Handle<JSFunction> function,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001017 Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001018
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001019 static bool HasCustomCallGenerator(Handle<JSFunction> function);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001020 static bool CanBeCached(Handle<JSFunction> function);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001021
1022 private:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001023 // Compiles a custom call constant/global IC. For constant calls cell is
1024 // NULL. Returns an empty handle if there is no custom call code for the
1025 // given function.
1026 Handle<Code> CompileCustomCall(Handle<Object> object,
1027 Handle<JSObject> holder,
danno@chromium.org41728482013-06-12 22:31:22 +00001028 Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001029 Handle<JSFunction> function,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001030 Handle<String> name,
1031 Code::StubType type);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001032
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001033#define DECLARE_CALL_GENERATOR(name) \
1034 Handle<Code> Compile##name##Call(Handle<Object> object, \
1035 Handle<JSObject> holder, \
danno@chromium.org41728482013-06-12 22:31:22 +00001036 Handle<Cell> cell, \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001037 Handle<JSFunction> function, \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001038 Handle<String> fname, \
1039 Code::StubType type);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001040 CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
1041#undef DECLARE_CALL_GENERATOR
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00001042
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001043 Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
1044 Handle<Object> object,
1045 Handle<JSObject> holder,
danno@chromium.org41728482013-06-12 22:31:22 +00001046 Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001047 Handle<JSFunction> function,
1048 Handle<String> name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049
ulan@chromium.org750145a2013-03-07 15:14:13 +00001050 Handle<Code> GetCode(Code::StubType type, Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001051 Handle<Code> GetCode(Handle<JSFunction> function);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00001052
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001053 const ParameterCount& arguments() { return arguments_; }
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001054
ulan@chromium.org750145a2013-03-07 15:14:13 +00001055 void GenerateNameCheck(Handle<Name> name, Label* miss);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00001056
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001057 void GenerateGlobalReceiverCheck(Handle<JSObject> object,
1058 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00001059 Handle<Name> name,
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +00001060 Label* miss);
1061
1062 // Generates code to load the function from the cell checking that
1063 // it still contains the same function.
danno@chromium.org41728482013-06-12 22:31:22 +00001064 void GenerateLoadFunctionFromCell(Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001065 Handle<JSFunction> function,
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +00001066 Label* miss);
1067
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001068 // Generates a jump to CallIC miss stub.
1069 void GenerateMissBranch();
1070
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001071 const ParameterCount arguments_;
1072 const Code::Kind kind_;
1073 const Code::ExtraICState extra_state_;
1074 const InlineCacheHolderFlag cache_holder_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001075};
1076
1077
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001078// Holds information about possible function call optimizations.
1079class CallOptimization BASE_EMBEDDED {
1080 public:
1081 explicit CallOptimization(LookupResult* lookup);
1082
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001083 explicit CallOptimization(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001084
1085 bool is_constant_call() const {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001086 return !constant_function_.is_null();
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001087 }
1088
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001089 Handle<JSFunction> constant_function() const {
1090 ASSERT(is_constant_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001091 return constant_function_;
1092 }
1093
1094 bool is_simple_api_call() const {
1095 return is_simple_api_call_;
1096 }
1097
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001098 Handle<FunctionTemplateInfo> expected_receiver_type() const {
1099 ASSERT(is_simple_api_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001100 return expected_receiver_type_;
1101 }
1102
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001103 Handle<CallHandlerInfo> api_call_info() const {
1104 ASSERT(is_simple_api_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001105 return api_call_info_;
1106 }
1107
1108 // Returns the depth of the object having the expected type in the
1109 // prototype chain between the two arguments.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001110 int GetPrototypeDepthOfExpectedType(Handle<JSObject> object,
1111 Handle<JSObject> holder) const;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001112
1113 private:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001114 void Initialize(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001115
1116 // Determines whether the given function can be called using the
1117 // fast api call builtin.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001118 void AnalyzePossibleApiFunction(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001119
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001120 Handle<JSFunction> constant_function_;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001121 bool is_simple_api_call_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001122 Handle<FunctionTemplateInfo> expected_receiver_type_;
1123 Handle<CallHandlerInfo> api_call_info_;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001124};
1125
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001127} } // namespace v8::internal
1128
1129#endif // V8_STUB_CACHE_H_