blob: adfa44a3ef01a8e4ff794bffb66a1c9d57986450 [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
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +000051
52class CallOptimization;
ricow@chromium.orgddd545c2011-08-24 12:02:41 +000053class SmallMapList;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000054class StubCache;
55
ricow@chromium.orgddd545c2011-08-24 12:02:41 +000056
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000057class SCTableReference {
58 public:
59 Address address() const { return address_; }
60
61 private:
62 explicit SCTableReference(Address address) : address_(address) {}
63
64 Address address_;
65
66 friend class StubCache;
67};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000070class StubCache {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000071 public:
72 struct Entry {
ulan@chromium.org750145a2013-03-07 15:14:13 +000073 Name* key;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000074 Code* value;
ulan@chromium.org812308e2012-02-29 15:58:45 +000075 Map* map;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076 };
77
ulan@chromium.org812308e2012-02-29 15:58:45 +000078 void Initialize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000079
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000080 Handle<JSObject> StubHolder(Handle<JSObject> receiver,
81 Handle<JSObject> holder);
82
ulan@chromium.org750145a2013-03-07 15:14:13 +000083 Handle<Code> FindIC(Handle<Name> name,
danno@chromium.orgca29dd82013-04-26 11:59:48 +000084 Handle<Map> stub_holder_map,
85 Code::Kind kind,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +000086 Code::ExtraICState extra_state = Code::kNoExtraICState,
87 InlineCacheHolderFlag cache_holder = OWN_MAP);
ulan@chromium.org750145a2013-03-07 15:14:13 +000088
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +000089 Handle<Code> FindHandler(Handle<Name> name,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +000090 Handle<HeapObject> stub_holder,
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +000091 Code::Kind kind,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +000092 InlineCacheHolderFlag cache_holder = OWN_MAP,
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +000093 StrictModeFlag strict_mode = kNonStrictMode);
danno@chromium.orgbee51992013-07-10 14:57:15 +000094
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +000095 Handle<Code> ComputeMonomorphicIC(Handle<Name> name,
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +000096 Handle<Type> type,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +000097 Handle<Code> handler,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +000098 StrictModeFlag strict_mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000099
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000100 Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<Object> object);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000101
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000102 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map);
103
104 Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map,
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000105 StrictModeFlag strict_mode,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000106 KeyedAccessStoreMode store_mode);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000107
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000108 Handle<Code> ComputeCallField(int argc,
109 Code::Kind,
110 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000111 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000112 Handle<Object> object,
113 Handle<JSObject> holder,
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000114 PropertyIndex index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000115
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000116 Handle<Code> ComputeCallConstant(int argc,
117 Code::Kind,
118 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000119 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000120 Handle<Object> object,
121 Handle<JSObject> holder,
122 Handle<JSFunction> function);
lrn@chromium.org303ada72010-10-27 09:33:13 +0000123
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000124 Handle<Code> ComputeCallInterceptor(int argc,
125 Code::Kind,
126 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000127 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000128 Handle<Object> object,
129 Handle<JSObject> holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000130
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000131 Handle<Code> ComputeCallGlobal(int argc,
132 Code::Kind,
133 Code::ExtraICState extra_state,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000134 Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000135 Handle<JSObject> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000136 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000137 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000138 Handle<JSFunction> function);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140 // ---
141
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000142 Handle<Code> ComputeCallInitialize(int argc, RelocInfo::Mode mode);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000143
lrn@chromium.org34e60782011-09-15 07:25:40 +0000144 Handle<Code> ComputeKeyedCallInitialize(int argc);
erik.corry@gmail.com4a6c3272010-11-18 12:04:40 +0000145
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000146 Handle<Code> ComputeCallPreMonomorphic(int argc,
147 Code::Kind kind,
148 Code::ExtraICState extra_state);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000149
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000150 Handle<Code> ComputeCallNormal(int argc,
151 Code::Kind kind,
152 Code::ExtraICState state);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000153
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000154 Handle<Code> ComputeCallArguments(int argc);
whesse@chromium.org7b260152011-06-20 15:33:18 +0000155
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000156 Handle<Code> ComputeCallMegamorphic(int argc,
157 Code::Kind kind,
158 Code::ExtraICState state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000160 Handle<Code> ComputeCallMiss(int argc,
161 Code::Kind kind,
162 Code::ExtraICState state);
163
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000164 // ---
165
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000166 Handle<Code> ComputeCompareNil(Handle<Map> receiver_map,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000167 CompareNilICStub& stub);
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000168
169 // ---
170
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000171 Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps);
172 Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000173 KeyedAccessStoreMode store_mode,
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000174 StrictModeFlag strict_mode);
175
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +0000176 Handle<Code> ComputePolymorphicIC(TypeHandleList* types,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000177 CodeHandleList* handlers,
178 int number_of_valid_maps,
179 Handle<Name> name,
180 StrictModeFlag strict_mode);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182 // Finds the Code object stored in the Heap::non_monomorphic_cache().
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000183 Code* FindCallInitialize(int argc, RelocInfo::Mode mode, Code::Kind kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000185#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000186 Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000187
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000188 Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000189#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000191 // Update cache for entry hash(name, map).
ulan@chromium.org750145a2013-03-07 15:14:13 +0000192 Code* Set(Name* name, Map* map, Code* code);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193
194 // Clear the lookup table (@ mark compact collection).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000195 void Clear();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197 // Collect all maps that match the name and flags.
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000198 void CollectMatchingMaps(SmallMapList* types,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000199 Handle<Name> name,
ricow@chromium.org7ad65222011-12-19 12:13:11 +0000200 Code::Flags flags,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000201 Handle<Context> native_context,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000202 Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204 // Generate code for probing the stub cache table.
ulan@chromium.org812308e2012-02-29 15:58:45 +0000205 // Arguments extra, extra2 and extra3 may be used to pass additional scratch
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000206 // registers. Set to no_reg if not needed.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000207 void GenerateProbe(MacroAssembler* masm,
208 Code::Flags flags,
209 Register receiver,
210 Register name,
211 Register scratch,
212 Register extra,
ulan@chromium.org812308e2012-02-29 15:58:45 +0000213 Register extra2 = no_reg,
214 Register extra3 = no_reg);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215
216 enum Table {
217 kPrimary,
218 kSecondary
219 };
220
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000221
222 SCTableReference key_reference(StubCache::Table table) {
223 return SCTableReference(
224 reinterpret_cast<Address>(&first_entry(table)->key));
225 }
226
227
ulan@chromium.org812308e2012-02-29 15:58:45 +0000228 SCTableReference map_reference(StubCache::Table table) {
229 return SCTableReference(
230 reinterpret_cast<Address>(&first_entry(table)->map));
231 }
232
233
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000234 SCTableReference value_reference(StubCache::Table table) {
235 return SCTableReference(
236 reinterpret_cast<Address>(&first_entry(table)->value));
237 }
238
239
240 StubCache::Entry* first_entry(StubCache::Table table) {
241 switch (table) {
242 case StubCache::kPrimary: return StubCache::primary_;
243 case StubCache::kSecondary: return StubCache::secondary_;
244 }
245 UNREACHABLE();
246 return NULL;
247 }
248
lrn@chromium.org7516f052011-03-30 08:52:27 +0000249 Isolate* isolate() { return isolate_; }
250 Heap* heap() { return isolate()->heap(); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000251 Factory* factory() { return isolate()->factory(); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000252
dslomov@chromium.org4a35c5a2013-09-13 07:28:52 +0000253 // These constants describe the structure of the interceptor arguments on the
254 // stack. The arguments are pushed by the (platform-specific)
255 // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
256 // LoadWithInterceptor.
257 static const int kInterceptorArgsNameIndex = 0;
258 static const int kInterceptorArgsInfoIndex = 1;
259 static const int kInterceptorArgsThisIndex = 2;
260 static const int kInterceptorArgsHolderIndex = 3;
261 static const int kInterceptorArgsLength = 4;
262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263 private:
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000264 explicit StubCache(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000265
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000266 Handle<Code> ComputeCallInitialize(int argc,
267 RelocInfo::Mode mode,
268 Code::Kind kind);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000269
ulan@chromium.org812308e2012-02-29 15:58:45 +0000270 // The stub cache has a primary and secondary level. The two levels have
271 // different hashing algorithms in order to avoid simultaneous collisions
272 // in both caches. Unlike a probing strategy (quadratic or otherwise) the
273 // update strategy on updates is fairly clear and simple: Any existing entry
274 // in the primary cache is moved to the secondary cache, and secondary cache
275 // entries are overwritten.
276
277 // Hash algorithm for the primary table. This algorithm is replicated in
278 // assembler for every architecture. Returns an index into the table that
279 // is scaled by 1 << kHeapObjectTagSize.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000280 static int PrimaryOffset(Name* name, Code::Flags flags, Map* map) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000281 // This works well because the heap object tag size and the hash
282 // shift are equal. Shifting down the length field to get the
283 // hash code would effectively throw away two bits of the hash
284 // code.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000285 STATIC_ASSERT(kHeapObjectTagSize == Name::kHashShift);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000286 // Compute the hash of the name (use entire hash field).
ager@chromium.org7c537e22008-10-16 08:43:32 +0000287 ASSERT(name->HasHashCode());
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000288 uint32_t field = name->hash_field();
ager@chromium.org9085a012009-05-11 19:22:57 +0000289 // Using only the low bits in 64-bit mode is unlikely to increase the
290 // risk of collision even if the heap is spread over an area larger than
291 // 4Gb (and not at all if it isn't).
292 uint32_t map_low32bits =
293 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000294 // We always set the in_loop bit to zero when generating the lookup code
295 // so do it here too so the hash codes match.
296 uint32_t iflags =
297 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000298 // Base the offset on a simple combination of name, flags, and map.
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000299 uint32_t key = (map_low32bits + field) ^ iflags;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000300 return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
301 }
302
ulan@chromium.org812308e2012-02-29 15:58:45 +0000303 // Hash algorithm for the secondary table. This algorithm is replicated in
304 // assembler for every architecture. Returns an index into the table that
305 // is scaled by 1 << kHeapObjectTagSize.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000306 static int SecondaryOffset(Name* name, Code::Flags flags, int seed) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000307 // Use the seed from the primary cache in the secondary cache.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000308 uint32_t name_low32bits =
ager@chromium.org9085a012009-05-11 19:22:57 +0000309 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
ulan@chromium.org812308e2012-02-29 15:58:45 +0000310 // We always set the in_loop bit to zero when generating the lookup code
311 // so do it here too so the hash codes match.
312 uint32_t iflags =
313 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000314 uint32_t key = (seed - name_low32bits) + iflags;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315 return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
316 }
317
318 // Compute the entry for a given offset in exactly the same way as
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000319 // we do in generated code. We generate an hash code that already
ulan@chromium.org750145a2013-03-07 15:14:13 +0000320 // ends in Name::kHashShift 0s. Then we multiply it so it is a multiple
kasperl@chromium.orge959c182009-07-27 08:59:04 +0000321 // of sizeof(Entry). This makes it easier to avoid making mistakes
322 // in the hashed offset computations.
danno@chromium.org40cb8782011-05-25 07:58:50 +0000323 static Entry* entry(Entry* table, int offset) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000324 const int multiplier = sizeof(*table) >> Name::kHashShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000325 return reinterpret_cast<Entry*>(
ulan@chromium.org812308e2012-02-29 15:58:45 +0000326 reinterpret_cast<Address>(table) + offset * multiplier);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000327 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000328
jkummerow@chromium.org1145ef82012-02-02 16:21:15 +0000329 static const int kPrimaryTableBits = 11;
330 static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
331 static const int kSecondaryTableBits = 9;
332 static const int kSecondaryTableSize = (1 << kSecondaryTableBits);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000333
334 Entry primary_[kPrimaryTableSize];
335 Entry secondary_[kSecondaryTableSize];
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000336 Isolate* isolate_;
337
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000338 friend class Isolate;
339 friend class SCTableReference;
340
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000341 DISALLOW_COPY_AND_ASSIGN(StubCache);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342};
343
344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000345// ------------------------------------------------------------------------
346
347
348// Support functions for IC stubs for callbacks.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000349DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000350
351
352// Support functions for IC stubs for interceptors.
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000353DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly);
354DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad);
355DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall);
356DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty);
357DECLARE_RUNTIME_FUNCTION(MaybeObject*, CallInterceptorProperty);
358DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000359
360
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000361enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
362enum IcCheckType { ELEMENT, PROPERTY };
363
364
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000365// The stub compilers compile stubs for the stub cache.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000366class StubCompiler BASE_EMBEDDED {
367 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000368 explicit StubCompiler(Isolate* isolate)
369 : isolate_(isolate), masm_(isolate, NULL, 256), failure_(NULL) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000370
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000371 // Functions to compile either CallIC or KeyedCallIC. The specific kind
372 // is extracted from the code flags.
373 Handle<Code> CompileCallInitialize(Code::Flags flags);
374 Handle<Code> CompileCallPreMonomorphic(Code::Flags flags);
375 Handle<Code> CompileCallNormal(Code::Flags flags);
376 Handle<Code> CompileCallMegamorphic(Code::Flags flags);
377 Handle<Code> CompileCallArguments(Code::Flags flags);
378 Handle<Code> CompileCallMiss(Code::Flags flags);
379
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000380#ifdef ENABLE_DEBUGGER_SUPPORT
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000381 Handle<Code> CompileCallDebugBreak(Code::Flags flags);
382 Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000383#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000384
385 // Static functions for generating parts of stubs.
386 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
387 int index,
388 Register prototype);
ager@chromium.org5c838252010-02-19 08:53:10 +0000389
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000390 // Helper function used to check that the dictionary doesn't contain
391 // the property. This function may return false negatives, so miss_label
392 // must always call a backup property check that is complete.
393 // This function is safe to call if the receiver has fast properties.
394 // Name must be unique and receiver must be a heap object.
395 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
396 Label* miss_label,
397 Register receiver,
398 Handle<Name> name,
399 Register r0,
400 Register r1);
401
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000402 // Generates prototype loading code that uses the objects from the
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000403 // context we were in when this function was called. If the context
404 // has changed, a jump to miss is performed. This ties the generated
405 // code to a particular context and so must not be used in cases
406 // where the generated code is not allowed to have references to
407 // objects from a context.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000408 static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
409 int index,
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000410 Register prototype,
411 Label* miss);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000412
ager@chromium.org7c537e22008-10-16 08:43:32 +0000413 static void GenerateFastPropertyLoad(MacroAssembler* masm,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000414 Register dst,
415 Register src,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000416 bool inobject,
417 int index,
418 Representation representation);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000420 static void GenerateLoadArrayLength(MacroAssembler* masm,
421 Register receiver,
422 Register scratch,
423 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000424
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000425 static void GenerateLoadStringLength(MacroAssembler* masm,
426 Register receiver,
ager@chromium.org5c838252010-02-19 08:53:10 +0000427 Register scratch1,
428 Register scratch2,
machenbach@chromium.org528ce022013-09-23 14:09:36 +0000429 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431 static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
432 Register receiver,
433 Register scratch1,
434 Register scratch2,
435 Label* miss_label);
ager@chromium.org5c838252010-02-19 08:53:10 +0000436
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000437 // Generate code to check that a global property cell is empty. Create
438 // the property cell at compilation time if no cell exists for the
439 // property.
440 static void GenerateCheckPropertyCell(MacroAssembler* masm,
441 Handle<JSGlobalObject> global,
442 Handle<Name> name,
443 Register scratch,
444 Label* miss);
445
446 // Calls GenerateCheckPropertyCell for each global object in the prototype
447 // chain from object to (but not including) holder.
448 static void GenerateCheckPropertyCells(MacroAssembler* masm,
449 Handle<JSObject> object,
450 Handle<JSObject> holder,
451 Handle<Name> name,
452 Register scratch,
453 Label* miss);
454
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000455 static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000456
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +0000457 // Generates code that verifies that the property holder has not changed
458 // (checking maps of objects in the prototype chain for fast and global
459 // objects or doing negative lookup for slow objects, ensures that the
460 // property cells for global objects are still empty) and checks that the map
461 // of the holder has not changed. If necessary the function also generates
462 // code for security check in case of global object holders. Helps to make
463 // sure that the current IC is still valid.
464 //
465 // The scratch and holder registers are always clobbered, but the object
466 // register is only clobbered if it the same as the holder register. The
467 // function returns a register containing the holder - either object_reg or
468 // holder_reg.
469 // The function can optionally (when save_at_depth !=
470 // kInvalidProtoDepth) save the object at the given depth by moving
471 // it to [esp + kPointerSize].
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000472 Register CheckPrototypes(Handle<JSObject> object,
473 Register object_reg,
474 Handle<JSObject> holder,
475 Register holder_reg,
476 Register scratch1,
477 Register scratch2,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000478 Handle<Name> name,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000479 Label* miss,
480 PrototypeCheckType check = CHECK_ALL_MAPS) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000481 return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000482 scratch2, name, kInvalidProtoDepth, miss, check);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000483 }
ager@chromium.org5c838252010-02-19 08:53:10 +0000484
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000485 Register CheckPrototypes(Handle<JSObject> object,
486 Register object_reg,
487 Handle<JSObject> holder,
488 Register holder_reg,
489 Register scratch1,
490 Register scratch2,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000491 Handle<Name> name,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000492 int save_at_depth,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000493 Label* miss,
494 PrototypeCheckType check = CHECK_ALL_MAPS);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000495
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000496 void GenerateBooleanCheck(Register object, Label* miss);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000497
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000498 protected:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000499 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000500 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000501
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000502 MacroAssembler* masm() { return &masm_; }
503 void set_failure(Failure* failure) { failure_ = failure; }
504
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000505 static void LookupPostInterceptor(Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000506 Handle<Name> name,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000507 LookupResult* lookup);
508
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000509 Isolate* isolate() { return isolate_; }
lrn@chromium.org7516f052011-03-30 08:52:27 +0000510 Heap* heap() { return isolate()->heap(); }
511 Factory* factory() { return isolate()->factory(); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000512
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000513 static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000515 private:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000516 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000517 MacroAssembler masm_;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000518 Failure* failure_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000519};
520
521
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000522enum FrontendCheckType { PERFORM_INITIAL_CHECKS, SKIP_INITIAL_CHECKS };
523
524
danno@chromium.orgbee51992013-07-10 14:57:15 +0000525class BaseLoadStoreStubCompiler: public StubCompiler {
526 public:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000527 BaseLoadStoreStubCompiler(Isolate* isolate,
528 Code::Kind kind,
529 InlineCacheHolderFlag cache_holder = OWN_MAP)
530 : StubCompiler(isolate), kind_(kind), cache_holder_(cache_holder) {
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000531 InitializeRegisters();
532 }
danno@chromium.orgbee51992013-07-10 14:57:15 +0000533 virtual ~BaseLoadStoreStubCompiler() { }
534
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +0000535 Handle<Code> CompileMonomorphicIC(Handle<Type> type,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000536 Handle<Code> handler,
537 Handle<Name> name);
538
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +0000539 Handle<Code> CompilePolymorphicIC(TypeHandleList* types,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000540 CodeHandleList* handlers,
541 Handle<Name> name,
542 Code::StubType type,
543 IcCheckType check);
544
545 virtual void GenerateNameCheck(Handle<Name> name,
546 Register name_reg,
547 Label* miss) { }
548
549 static Builtins::Name MissBuiltin(Code::Kind kind) {
550 switch (kind) {
551 case Code::LOAD_IC: return Builtins::kLoadIC_Miss;
552 case Code::STORE_IC: return Builtins::kStoreIC_Miss;
553 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss;
554 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss;
555 default: UNREACHABLE();
556 }
557 return Builtins::kLoadIC_Miss;
558 }
559
560 protected:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000561 virtual Register HandlerFrontendHeader(Handle<Object> object,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000562 Register object_reg,
563 Handle<JSObject> holder,
564 Handle<Name> name,
565 Label* miss) = 0;
566
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000567 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss) = 0;
danno@chromium.orgbee51992013-07-10 14:57:15 +0000568
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000569 Register HandlerFrontend(Handle<Object> object,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000570 Register object_reg,
571 Handle<JSObject> holder,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000572 Handle<Name> name);
danno@chromium.orgbee51992013-07-10 14:57:15 +0000573
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000574 Handle<Code> GetCode(Code::Kind kind,
575 Code::StubType type,
576 Handle<Name> name);
577
danno@chromium.orgbee51992013-07-10 14:57:15 +0000578 Handle<Code> GetICCode(Code::Kind kind,
579 Code::StubType type,
580 Handle<Name> name,
581 InlineCacheState state = MONOMORPHIC);
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000582 Code::Kind kind() { return kind_; }
583
584 Logger::LogEventsAndTags log_kind(Handle<Code> code) {
585 if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
586 if (kind_ == Code::LOAD_IC) {
587 return code->ic_state() == MONOMORPHIC
588 ? Logger::LOAD_IC_TAG : Logger::LOAD_POLYMORPHIC_IC_TAG;
589 } else if (kind_ == Code::KEYED_LOAD_IC) {
590 return code->ic_state() == MONOMORPHIC
591 ? Logger::KEYED_LOAD_IC_TAG : Logger::KEYED_LOAD_POLYMORPHIC_IC_TAG;
592 } else if (kind_ == Code::STORE_IC) {
593 return code->ic_state() == MONOMORPHIC
594 ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
595 } else {
596 return code->ic_state() == MONOMORPHIC
597 ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
598 }
599 }
600 void JitEvent(Handle<Name> name, Handle<Code> code);
danno@chromium.orgbee51992013-07-10 14:57:15 +0000601
602 virtual Code::ExtraICState extra_state() { return Code::kNoExtraICState; }
danno@chromium.orgbee51992013-07-10 14:57:15 +0000603 virtual Register receiver() = 0;
604 virtual Register name() = 0;
605 virtual Register scratch1() = 0;
606 virtual Register scratch2() = 0;
607 virtual Register scratch3() = 0;
608
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000609 void InitializeRegisters();
610
machenbach@chromium.orgaf9cfcb2013-11-19 11:05:18 +0000611 bool IncludesNumberType(TypeHandleList* types);
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000612
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000613 Code::Kind kind_;
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000614 InlineCacheHolderFlag cache_holder_;
danno@chromium.orgbee51992013-07-10 14:57:15 +0000615 Register* registers_;
616};
617
618
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000619class LoadStubCompiler: public BaseLoadStoreStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 public:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000621 LoadStubCompiler(Isolate* isolate,
622 InlineCacheHolderFlag cache_holder = OWN_MAP,
623 Code::Kind kind = Code::LOAD_IC)
624 : BaseLoadStoreStubCompiler(isolate, kind, cache_holder) { }
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000625 virtual ~LoadStubCompiler() { }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000626
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000627 Handle<Code> CompileLoadField(Handle<Object> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000628 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000629 Handle<Name> name,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000630 PropertyIndex index,
631 Representation representation);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000632
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000633 Handle<Code> CompileLoadCallback(Handle<Object> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000634 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000635 Handle<Name> name,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000636 Handle<ExecutableAccessorInfo> callback);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000637
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000638 Handle<Code> CompileLoadCallback(Handle<Object> object,
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000639 Handle<JSObject> holder,
640 Handle<Name> name,
641 const CallOptimization& call_optimization);
642
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000643 Handle<Code> CompileLoadConstant(Handle<Object> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000644 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000645 Handle<Name> name,
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000646 Handle<Object> value);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000647
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000648 Handle<Code> CompileLoadInterceptor(Handle<Object> object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000649 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000650 Handle<Name> name);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000651
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000652 Handle<Code> CompileLoadViaGetter(Handle<Object> object,
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000653 Handle<JSObject> holder,
654 Handle<Name> name,
655 Handle<JSFunction> getter);
656
657 static void GenerateLoadViaGetter(MacroAssembler* masm,
658 Register receiver,
659 Handle<JSFunction> getter);
660
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000661 Handle<Code> CompileLoadNonexistent(Handle<Object> object,
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000662 Handle<JSObject> last,
663 Handle<Name> name,
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000664 Handle<JSGlobalObject> global);
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000665
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000666 Handle<Code> CompileLoadGlobal(Handle<Object> object,
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000667 Handle<GlobalObject> holder,
668 Handle<PropertyCell> cell,
669 Handle<Name> name,
670 bool is_dont_delete);
671
672 static Register* registers();
673
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000674 protected:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000675 virtual Register HandlerFrontendHeader(Handle<Object> object,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000676 Register object_reg,
677 Handle<JSObject> holder,
678 Handle<Name> name,
679 Label* miss);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000680
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000681 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss);
danno@chromium.orgbee51992013-07-10 14:57:15 +0000682
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000683 Register CallbackHandlerFrontend(Handle<Object> object,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000684 Register object_reg,
685 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000686 Handle<Name> name,
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000687 Handle<Object> callback);
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000688 void NonexistentHandlerFrontend(Handle<Object> object,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000689 Handle<JSObject> last,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000690 Handle<Name> name,
verwaest@chromium.org057bd502013-11-06 12:03:29 +0000691 Handle<JSGlobalObject> global);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000692
693 void GenerateLoadField(Register reg,
694 Handle<JSObject> holder,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000695 PropertyIndex field,
696 Representation representation);
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000697 void GenerateLoadConstant(Handle<Object> value);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000698 void GenerateLoadCallback(Register reg,
699 Handle<ExecutableAccessorInfo> callback);
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000700 void GenerateLoadCallback(const CallOptimization& call_optimization);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000701 void GenerateLoadInterceptor(Register holder_reg,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000702 Handle<Object> object,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000703 Handle<JSObject> holder,
704 LookupResult* lookup,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000705 Handle<Name> name);
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000706 void GenerateLoadPostInterceptor(Register reg,
707 Handle<JSObject> interceptor_holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000708 Handle<Name> name,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000709 LookupResult* lookup);
710
danno@chromium.orgbee51992013-07-10 14:57:15 +0000711 virtual Register receiver() { return registers_[0]; }
712 virtual Register name() { return registers_[1]; }
713 virtual Register scratch1() { return registers_[2]; }
714 virtual Register scratch2() { return registers_[3]; }
715 virtual Register scratch3() { return registers_[4]; }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000716 Register scratch4() { return registers_[5]; }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000717};
718
719
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000720class KeyedLoadStubCompiler: public LoadStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721 public:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000722 KeyedLoadStubCompiler(Isolate* isolate,
723 InlineCacheHolderFlag cache_holder = OWN_MAP)
724 : LoadStubCompiler(isolate, cache_holder, Code::KEYED_LOAD_IC) { }
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000725
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000726 Handle<Code> CompileLoadElement(Handle<Map> receiver_map);
727
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000728 void CompileElementHandlers(MapHandleList* receiver_maps,
729 CodeHandleList* handlers);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000730
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000731 static void GenerateLoadDictionaryElement(MacroAssembler* masm);
732
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000733 protected:
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000734 static Register* registers();
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000735
736 private:
ulan@chromium.org750145a2013-03-07 15:14:13 +0000737 virtual void GenerateNameCheck(Handle<Name> name,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000738 Register name_reg,
739 Label* miss);
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000740 friend class BaseLoadStoreStubCompiler;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000741};
742
743
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000744class StoreStubCompiler: public BaseLoadStoreStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745 public:
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000746 StoreStubCompiler(Isolate* isolate,
747 StrictModeFlag strict_mode,
748 Code::Kind kind = Code::STORE_IC)
749 : BaseLoadStoreStubCompiler(isolate, kind),
danno@chromium.orgbee51992013-07-10 14:57:15 +0000750 strict_mode_(strict_mode) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000751
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000752 virtual ~StoreStubCompiler() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000753
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000754 Handle<Code> CompileStoreTransition(Handle<JSObject> object,
755 LookupResult* lookup,
756 Handle<Map> transition,
757 Handle<Name> name);
758
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000759 Handle<Code> CompileStoreField(Handle<JSObject> object,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000760 LookupResult* lookup,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000761 Handle<Name> name);
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000762
danno@chromium.orgbee51992013-07-10 14:57:15 +0000763 void GenerateNegativeHolderLookup(MacroAssembler* masm,
764 Handle<JSObject> holder,
765 Register holder_reg,
766 Handle<Name> name,
767 Label* miss);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000768
danno@chromium.orgbee51992013-07-10 14:57:15 +0000769 void GenerateStoreTransition(MacroAssembler* masm,
770 Handle<JSObject> object,
771 LookupResult* lookup,
772 Handle<Map> transition,
773 Handle<Name> name,
774 Register receiver_reg,
775 Register name_reg,
776 Register value_reg,
777 Register scratch1,
778 Register scratch2,
779 Register scratch3,
780 Label* miss_label,
781 Label* slow);
782
783 void GenerateStoreField(MacroAssembler* masm,
784 Handle<JSObject> object,
785 LookupResult* lookup,
786 Register receiver_reg,
787 Register name_reg,
788 Register value_reg,
789 Register scratch1,
790 Register scratch2,
791 Label* miss_label);
792
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000793 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
794 Handle<JSObject> holder,
795 Handle<Name> name,
796 Handle<ExecutableAccessorInfo> callback);
797
798 Handle<Code> CompileStoreCallback(Handle<JSObject> object,
799 Handle<JSObject> holder,
800 Handle<Name> name,
801 const CallOptimization& call_optimization);
802
803 static void GenerateStoreViaSetter(MacroAssembler* masm,
804 Handle<JSFunction> setter);
805
806 Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
807 Handle<JSObject> holder,
808 Handle<Name> name,
809 Handle<JSFunction> setter);
810
811 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object,
812 Handle<Name> name);
813
danno@chromium.orgbee51992013-07-10 14:57:15 +0000814 static Builtins::Name SlowBuiltin(Code::Kind kind) {
815 switch (kind) {
816 case Code::STORE_IC: return Builtins::kStoreIC_Slow;
817 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow;
818 default: UNREACHABLE();
819 }
820 return Builtins::kStoreIC_Slow;
821 }
822
823 protected:
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000824 virtual Register HandlerFrontendHeader(Handle<Object> object,
danno@chromium.orgbee51992013-07-10 14:57:15 +0000825 Register object_reg,
826 Handle<JSObject> holder,
827 Handle<Name> name,
828 Label* miss);
829
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000830 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000831 void GenerateRestoreName(MacroAssembler* masm,
832 Label* label,
833 Handle<Name> name);
834
danno@chromium.orgbee51992013-07-10 14:57:15 +0000835 virtual Register receiver() { return registers_[0]; }
836 virtual Register name() { return registers_[1]; }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000837 Register value() { return registers_[2]; }
danno@chromium.orgbee51992013-07-10 14:57:15 +0000838 virtual Register scratch1() { return registers_[3]; }
839 virtual Register scratch2() { return registers_[4]; }
840 virtual Register scratch3() { return registers_[5]; }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000841 StrictModeFlag strict_mode() { return strict_mode_; }
842 virtual Code::ExtraICState extra_state() { return strict_mode_; }
843
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000844 protected:
845 static Register* registers();
846
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000847 private:
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000848 StrictModeFlag strict_mode_;
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000849 friend class BaseLoadStoreStubCompiler;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000850};
851
852
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000853class KeyedStoreStubCompiler: public StoreStubCompiler {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000854 public:
ulan@chromium.org65a89c22012-02-14 11:46:07 +0000855 KeyedStoreStubCompiler(Isolate* isolate,
856 StrictModeFlag strict_mode,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000857 KeyedAccessStoreMode store_mode)
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000858 : StoreStubCompiler(isolate, strict_mode, Code::KEYED_STORE_IC),
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000859 store_mode_(store_mode) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000860
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000861 Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000862
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000863 Handle<Code> CompileStorePolymorphic(MapHandleList* receiver_maps,
864 CodeHandleList* handler_stubs,
865 MapHandleList* transitioned_maps);
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000866
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000867 Handle<Code> CompileStoreElementPolymorphic(MapHandleList* receiver_maps);
868
sgjesse@chromium.org6db88712011-07-11 11:41:22 +0000869 static void GenerateStoreDictionaryElement(MacroAssembler* masm);
870
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000871 protected:
872 virtual Code::ExtraICState extra_state() {
873 return Code::ComputeExtraICState(store_mode_, strict_mode());
874 }
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000875 static Register* registers();
ager@chromium.org9ee27ae2011-03-02 13:43:26 +0000876
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000877 private:
878 Register transition_map() {
879 return registers()[3];
880 }
881
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000882 virtual void GenerateNameCheck(Handle<Name> name,
883 Register name_reg,
884 Label* miss);
ulan@chromium.org750145a2013-03-07 15:14:13 +0000885 KeyedAccessStoreMode store_mode_;
mstarzinger@chromium.org2efc3e42013-10-14 08:45:38 +0000886 friend class BaseLoadStoreStubCompiler;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887};
888
889
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000890// Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call
891// IC stubs.
892#define CUSTOM_CALL_IC_GENERATORS(V) \
893 V(ArrayPush) \
894 V(ArrayPop) \
895 V(StringCharCodeAt) \
896 V(StringCharAt) \
897 V(StringFromCharCode) \
898 V(MathFloor) \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000899 V(MathAbs) \
900 V(ArrayCode)
901
902
903#define SITE_SPECIFIC_CALL_GENERATORS(V) \
904 V(ArrayCode)
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000905
906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907class CallStubCompiler: public StubCompiler {
908 public:
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000909 CallStubCompiler(Isolate* isolate,
910 int argc,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +0000911 Code::Kind kind,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000912 Code::ExtraICState extra_state,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000913 InlineCacheHolderFlag cache_holder = OWN_MAP);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000914
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000915 Handle<Code> CompileCallField(Handle<JSObject> object,
916 Handle<JSObject> holder,
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000917 PropertyIndex index,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000918 Handle<Name> name);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000919
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +0000920 void CompileHandlerFrontend(Handle<Object> object,
921 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000922 Handle<Name> name,
machenbach@chromium.orgb5be0a92013-11-15 10:32:41 +0000923 CheckType check);
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +0000924
925 void CompileHandlerBackend(Handle<JSFunction> function);
926
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000927 Handle<Code> CompileCallConstant(Handle<Object> object,
928 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000929 Handle<Name> name,
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +0000930 CheckType check,
931 Handle<JSFunction> function);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000932
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000933 Handle<Code> CompileCallInterceptor(Handle<JSObject> object,
934 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000935 Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000936
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000937 Handle<Code> CompileCallGlobal(Handle<JSObject> object,
938 Handle<GlobalObject> holder,
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000939 Handle<PropertyCell> cell,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000940 Handle<JSFunction> function,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000941 Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000942
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000943 static bool HasCustomCallGenerator(Handle<JSFunction> function);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000944 static bool CanBeCached(Handle<JSFunction> function);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000945
946 private:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000947 // Compiles a custom call constant/global IC. For constant calls cell is
948 // NULL. Returns an empty handle if there is no custom call code for the
949 // given function.
950 Handle<Code> CompileCustomCall(Handle<Object> object,
951 Handle<JSObject> holder,
danno@chromium.org41728482013-06-12 22:31:22 +0000952 Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000953 Handle<JSFunction> function,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000954 Handle<String> name,
955 Code::StubType type);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000956
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000957#define DECLARE_CALL_GENERATOR(name) \
958 Handle<Code> Compile##name##Call(Handle<Object> object, \
959 Handle<JSObject> holder, \
danno@chromium.org41728482013-06-12 22:31:22 +0000960 Handle<Cell> cell, \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000961 Handle<JSFunction> function, \
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000962 Handle<String> fname, \
963 Code::StubType type);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000964 CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
965#undef DECLARE_CALL_GENERATOR
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000966
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000967 Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
968 Handle<Object> object,
969 Handle<JSObject> holder,
danno@chromium.org41728482013-06-12 22:31:22 +0000970 Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000971 Handle<JSFunction> function,
972 Handle<String> name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000973
ulan@chromium.org750145a2013-03-07 15:14:13 +0000974 Handle<Code> GetCode(Code::StubType type, Handle<Name> name);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000975 Handle<Code> GetCode(Handle<JSFunction> function);
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000976
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000977 const ParameterCount& arguments() { return arguments_; }
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000978
ulan@chromium.org750145a2013-03-07 15:14:13 +0000979 void GenerateNameCheck(Handle<Name> name, Label* miss);
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +0000980
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000981 void GenerateGlobalReceiverCheck(Handle<JSObject> object,
982 Handle<JSObject> holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000983 Handle<Name> name,
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000984 Label* miss);
985
986 // Generates code to load the function from the cell checking that
987 // it still contains the same function.
danno@chromium.org41728482013-06-12 22:31:22 +0000988 void GenerateLoadFunctionFromCell(Handle<Cell> cell,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000989 Handle<JSFunction> function,
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000990 Label* miss);
991
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000992 // Generates a jump to CallIC miss stub.
993 void GenerateMissBranch();
994
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000995 const ParameterCount arguments_;
996 const Code::Kind kind_;
997 const Code::ExtraICState extra_state_;
998 const InlineCacheHolderFlag cache_holder_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000999};
1000
1001
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001002// Holds information about possible function call optimizations.
1003class CallOptimization BASE_EMBEDDED {
1004 public:
1005 explicit CallOptimization(LookupResult* lookup);
1006
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001007 explicit CallOptimization(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001008
1009 bool is_constant_call() const {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001010 return !constant_function_.is_null();
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001011 }
1012
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001013 Handle<JSFunction> constant_function() const {
1014 ASSERT(is_constant_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001015 return constant_function_;
1016 }
1017
1018 bool is_simple_api_call() const {
1019 return is_simple_api_call_;
1020 }
1021
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001022 Handle<FunctionTemplateInfo> expected_receiver_type() const {
1023 ASSERT(is_simple_api_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001024 return expected_receiver_type_;
1025 }
1026
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001027 Handle<CallHandlerInfo> api_call_info() const {
1028 ASSERT(is_simple_api_call());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001029 return api_call_info_;
1030 }
1031
1032 // Returns the depth of the object having the expected type in the
1033 // prototype chain between the two arguments.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001034 int GetPrototypeDepthOfExpectedType(Handle<JSObject> object,
1035 Handle<JSObject> holder) const;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001036
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00001037 bool IsCompatibleReceiver(Object* receiver) {
1038 ASSERT(is_simple_api_call());
1039 if (expected_receiver_type_.is_null()) return true;
1040 return receiver->IsInstanceOf(*expected_receiver_type_);
1041 }
1042
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001043 private:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001044 void Initialize(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001045
1046 // Determines whether the given function can be called using the
1047 // fast api call builtin.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001048 void AnalyzePossibleApiFunction(Handle<JSFunction> function);
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001049
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001050 Handle<JSFunction> constant_function_;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001051 bool is_simple_api_call_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001052 Handle<FunctionTemplateInfo> expected_receiver_type_;
1053 Handle<CallHandlerInfo> api_call_info_;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00001054};
1055
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001056
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001057} } // namespace v8::internal
1058
1059#endif // V8_STUB_CACHE_H_