blob: 7bccaa9c12ba8979cb4c4f234091afcf8b31c40e [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_CODE_STUBS_H_
6#define V8_CODE_STUBS_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/allocation.h"
9#include "src/assembler.h"
Ben Murdochc5610432016-08-08 18:44:38 +010010#include "src/code-stub-assembler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/codegen.h"
12#include "src/globals.h"
13#include "src/ic/ic-state.h"
14#include "src/interface-descriptors.h"
15#include "src/macro-assembler.h"
16#include "src/ostreams.h"
Steve Block6ded16b2010-05-10 14:33:55 +010017
Steve Blocka7e24c12009-10-30 11:49:00 +000018namespace v8 {
19namespace internal {
20
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000021// List of code stubs used on all platforms.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022#define CODE_STUB_LIST_ALL_PLATFORMS(V) \
23 /* PlatformCodeStubs */ \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024 V(ArrayConstructor) \
25 V(BinaryOpICWithAllocationSite) \
Ben Murdochda12d292016-06-02 14:46:10 +010026 V(CallApiCallback) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027 V(CallApiGetter) \
28 V(CallConstruct) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029 V(CallIC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 V(CEntry) \
31 V(CompareIC) \
32 V(DoubleToI) \
33 V(FunctionPrototype) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034 V(InternalArrayConstructor) \
35 V(JSEntry) \
36 V(KeyedLoadICTrampoline) \
37 V(LoadICTrampoline) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 V(CallICTrampoline) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040039 V(LoadIndexedString) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 V(MathPow) \
41 V(ProfileEntryHook) \
42 V(RecordWrite) \
43 V(RegExpExec) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044 V(StoreBufferOverflow) \
45 V(StoreElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046 V(StubFailureTrampoline) \
47 V(SubString) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048 V(ToNumber) \
Ben Murdochda12d292016-06-02 14:46:10 +010049 V(NonNumberToNumber) \
50 V(StringToNumber) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 V(ToString) \
Ben Murdoch097c5b22016-05-18 11:27:45 +010052 V(ToName) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 V(ToObject) \
54 V(VectorStoreICTrampoline) \
55 V(VectorKeyedStoreICTrampoline) \
56 V(VectorStoreIC) \
57 V(VectorKeyedStoreIC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 /* HydrogenCodeStubs */ \
59 V(ArrayNArgumentsConstructor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060 V(ArraySingleArgumentConstructor) \
61 V(BinaryOpIC) \
62 V(BinaryOpWithAllocationSite) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 V(CreateAllocationSite) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 V(CreateWeakCell) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 V(ElementsTransitionAndStore) \
Ben Murdochda12d292016-06-02 14:46:10 +010066 V(FastArrayPush) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 V(FastCloneRegExp) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 V(FastCloneShallowArray) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 V(FastNewClosure) \
70 V(FastNewContext) \
Ben Murdoch097c5b22016-05-18 11:27:45 +010071 V(FastNewObject) \
72 V(FastNewRestParameter) \
73 V(FastNewSloppyArguments) \
74 V(FastNewStrictArguments) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 V(GrowArrayElements) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076 V(InternalArrayNArgumentsConstructor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077 V(InternalArraySingleArgumentConstructor) \
78 V(KeyedLoadGeneric) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 V(LoadGlobalViaContext) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040080 V(LoadScriptContextField) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 V(LoadDictionaryElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 V(NameDictionaryLookup) \
83 V(NumberToString) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 V(Typeof) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085 V(RegExpConstructResult) \
86 V(StoreFastElement) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 V(StoreGlobalViaContext) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088 V(StoreScriptContextField) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089 V(StringAdd) \
Ben Murdochda12d292016-06-02 14:46:10 +010090 V(ToBooleanIC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 V(TransitionElementsKind) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 V(KeyedLoadIC) \
93 V(LoadIC) \
94 /* TurboFanCodeStubs */ \
Ben Murdochda12d292016-06-02 14:46:10 +010095 V(AllocateHeapNumber) \
Ben Murdochda12d292016-06-02 14:46:10 +010096 V(AllocateFloat32x4) \
97 V(AllocateInt32x4) \
98 V(AllocateUint32x4) \
99 V(AllocateBool32x4) \
100 V(AllocateInt16x8) \
101 V(AllocateUint16x8) \
102 V(AllocateBool16x8) \
103 V(AllocateInt8x16) \
104 V(AllocateUint8x16) \
105 V(AllocateBool8x16) \
Ben Murdochc5610432016-08-08 18:44:38 +0100106 V(ArrayNoArgumentConstructor) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 V(StringLength) \
Ben Murdochda12d292016-06-02 14:46:10 +0100108 V(Add) \
109 V(Subtract) \
Ben Murdochc5610432016-08-08 18:44:38 +0100110 V(Multiply) \
111 V(Divide) \
112 V(Modulus) \
113 V(ShiftRight) \
114 V(ShiftRightLogical) \
115 V(ShiftLeft) \
Ben Murdochda12d292016-06-02 14:46:10 +0100116 V(BitwiseAnd) \
117 V(BitwiseOr) \
118 V(BitwiseXor) \
Ben Murdochc5610432016-08-08 18:44:38 +0100119 V(Inc) \
120 V(InternalArrayNoArgumentConstructor) \
121 V(Dec) \
122 V(FastCloneShallowObject) \
123 V(InstanceOf) \
Ben Murdochda12d292016-06-02 14:46:10 +0100124 V(LessThan) \
125 V(LessThanOrEqual) \
126 V(GreaterThan) \
127 V(GreaterThanOrEqual) \
128 V(Equal) \
129 V(NotEqual) \
130 V(StrictEqual) \
131 V(StrictNotEqual) \
132 V(StringEqual) \
133 V(StringNotEqual) \
134 V(StringLessThan) \
135 V(StringLessThanOrEqual) \
136 V(StringGreaterThan) \
137 V(StringGreaterThanOrEqual) \
138 V(ToBoolean) \
139 V(ToInteger) \
140 V(ToLength) \
Ben Murdochc5610432016-08-08 18:44:38 +0100141 V(HasProperty) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 /* IC Handler stubs */ \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000143 V(ArrayBufferViewLoadField) \
Ben Murdochc5610432016-08-08 18:44:38 +0100144 V(KeyedLoadSloppyArguments) \
145 V(KeyedStoreSloppyArguments) \
146 V(LoadApiGetter) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 V(LoadConstant) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148 V(LoadFastElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 V(LoadField) \
Ben Murdochda12d292016-06-02 14:46:10 +0100150 V(LoadIndexedInterceptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151 V(StoreField) \
152 V(StoreGlobal) \
Ben Murdochc5610432016-08-08 18:44:38 +0100153 V(StoreInterceptor) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 V(StoreTransition)
Steve Blockd0582a62009-12-15 09:54:21 +0000155
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156// List of code stubs only used on ARM 32 bits platforms.
157#if V8_TARGET_ARCH_ARM
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400158#define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159
Steve Blockd0582a62009-12-15 09:54:21 +0000160#else
161#define CODE_STUB_LIST_ARM(V)
162#endif
163
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164// List of code stubs only used on ARM 64 bits platforms.
165#if V8_TARGET_ARCH_ARM64
166#define CODE_STUB_LIST_ARM64(V) \
167 V(DirectCEntry) \
168 V(RestoreRegistersState) \
169 V(StoreRegistersState)
170
171#else
172#define CODE_STUB_LIST_ARM64(V)
173#endif
174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175// List of code stubs only used on PPC platforms.
176#ifdef V8_TARGET_ARCH_PPC
177#define CODE_STUB_LIST_PPC(V) \
178 V(DirectCEntry) \
179 V(StoreRegistersState) \
180 V(RestoreRegistersState)
181#else
182#define CODE_STUB_LIST_PPC(V)
183#endif
184
Steve Block44f0eee2011-05-26 01:26:41 +0100185// List of code stubs only used on MIPS platforms.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186#if V8_TARGET_ARCH_MIPS
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400187#define CODE_STUB_LIST_MIPS(V) \
188 V(DirectCEntry) \
189 V(RestoreRegistersState) \
190 V(StoreRegistersState)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191#elif V8_TARGET_ARCH_MIPS64
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400192#define CODE_STUB_LIST_MIPS(V) \
193 V(DirectCEntry) \
194 V(RestoreRegistersState) \
195 V(StoreRegistersState)
Steve Block44f0eee2011-05-26 01:26:41 +0100196#else
197#define CODE_STUB_LIST_MIPS(V)
198#endif
199
Ben Murdochda12d292016-06-02 14:46:10 +0100200// List of code stubs only used on S390 platforms.
201#ifdef V8_TARGET_ARCH_S390
202#define CODE_STUB_LIST_S390(V) \
203 V(DirectCEntry) \
204 V(StoreRegistersState) \
205 V(RestoreRegistersState)
206#else
207#define CODE_STUB_LIST_S390(V)
208#endif
209
Steve Blockd0582a62009-12-15 09:54:21 +0000210// Combined list of code stubs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211#define CODE_STUB_LIST(V) \
212 CODE_STUB_LIST_ALL_PLATFORMS(V) \
213 CODE_STUB_LIST_ARM(V) \
214 CODE_STUB_LIST_ARM64(V) \
215 CODE_STUB_LIST_PPC(V) \
Ben Murdochda12d292016-06-02 14:46:10 +0100216 CODE_STUB_LIST_MIPS(V) \
217 CODE_STUB_LIST_S390(V)
Steve Blocka7e24c12009-10-30 11:49:00 +0000218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219static const int kHasReturnedMinusZeroSentinel = 1;
220
Steve Blocka7e24c12009-10-30 11:49:00 +0000221// Stub is base classes of all stubs.
222class CodeStub BASE_EMBEDDED {
223 public:
224 enum Major {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400225 // TODO(mvstanton): eliminate the NoCache key by getting rid
226 // of the non-monomorphic-cache.
227 NoCache = 0, // marker for stubs that do custom caching]
Steve Blockd0582a62009-12-15 09:54:21 +0000228#define DEF_ENUM(name) name,
229 CODE_STUB_LIST(DEF_ENUM)
230#undef DEF_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 NUMBER_OF_IDS
232 };
233
234 // Retrieve the code for the stub. Generate the code if needed.
235 Handle<Code> GetCode();
236
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 // Retrieve the code for the stub, make and return a copy of the code.
238 Handle<Code> GetCodeCopy(const Code::FindAndReplacePattern& pattern);
239
Steve Blocka7e24c12009-10-30 11:49:00 +0000240 static Major MajorKeyFromKey(uint32_t key) {
241 return static_cast<Major>(MajorKeyBits::decode(key));
Iain Merrick9ac36c92010-09-13 15:29:50 +0100242 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 static uint32_t MinorKeyFromKey(uint32_t key) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 return MinorKeyBits::decode(key);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100245 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100246
247 // Gets the major key from a code object that is a code stub or binary op IC.
248 static Major GetMajorKey(Code* code_stub) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 return MajorKeyFromKey(code_stub->stub_key());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100250 }
251
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
253
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000254 static const char* MajorName(Major major_key);
Steve Blocka7e24c12009-10-30 11:49:00 +0000255
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000256 explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000257 virtual ~CodeStub() {}
258
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000259 static void GenerateStubsAheadOfTime(Isolate* isolate);
260 static void GenerateFPStubs(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100261
262 // Some stubs put untagged junk on the stack that cannot be scanned by the
263 // GC. This means that we must be statically sure that no GC can occur while
264 // they are running. If that is the case they should override this to return
265 // true, which will cause an assertion if we try to call something that can
266 // GC or if we try to put a stack frame on top of the junk, which would not
267 // result in a traversable stack.
268 virtual bool SometimesSetsUpAFrame() { return true; }
269
270 // Lookup the code in the (possibly custom) cache.
271 bool FindCodeInCache(Code** code_out);
272
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000273 virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() const = 0;
274
275 virtual int GetStackParameterCount() const {
276 return GetCallInterfaceDescriptor().GetStackParameterCount();
277 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000278
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
280
281 static void InitializeDescriptor(Isolate* isolate, uint32_t key,
282 CodeStubDescriptor* desc);
283
284 static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key);
285
286 // Returns information for computing the number key.
287 virtual Major MajorKey() const = 0;
288 uint32_t MinorKey() const { return minor_key_; }
289
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000290 // BinaryOpStub needs to override this.
291 virtual Code::Kind GetCodeKind() const;
292
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000293 virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
294 virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295
Ben Murdoch097c5b22016-05-18 11:27:45 +0100296 Code::Flags GetCodeFlags() const;
297
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400298 friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 s.PrintName(os);
300 return os;
301 }
302
303 Isolate* isolate() const { return isolate_; }
304
305 protected:
306 CodeStub(uint32_t key, Isolate* isolate)
307 : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
Leon Clarkee46be812010-01-19 14:06:41 +0000308
Steve Blocka7e24c12009-10-30 11:49:00 +0000309 // Generates the assembler code for the stub.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 virtual Handle<Code> GenerateCode() = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000311
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312 // Returns whether the code generated for this stub needs to be allocated as
313 // a fixed (non-moveable) code object.
314 virtual bool NeedsImmovableCode() { return false; }
315
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400316 virtual void PrintName(std::ostream& os) const; // NOLINT
317 virtual void PrintBaseName(std::ostream& os) const; // NOLINT
318 virtual void PrintState(std::ostream& os) const { ; } // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000319
320 // Computes the key based on major and minor.
321 uint32_t GetKey() {
322 DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
323 return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
324 }
325
326 uint32_t minor_key_;
327
328 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000329 // Perform bookkeeping required after code generation when stub code is
330 // initially generated.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000331 void RecordCodeGeneration(Handle<Code> code);
Leon Clarkee46be812010-01-19 14:06:41 +0000332
Ben Murdochb0fe1622011-05-05 13:52:32 +0100333 // Finish the code object after it has been generated.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100334 virtual void FinishCode(Handle<Code> code) { }
335
336 // Activate newly generated stub. Is called after
337 // registering stub in the stub cache.
338 virtual void Activate(Code* code) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100339
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100340 // Add the code to a specialized cache, specific to an individual
341 // stub type. Please note, this method must add the code object to a
342 // roots object, otherwise we will remove the code during GC.
343 virtual void AddToSpecialCache(Handle<Code> new_object) { }
344
345 // Find code in a specialized cache, work is delegated to the specific stub.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346 virtual bool FindCodeInSpecialCache(Code** code_out) {
347 return false;
348 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100349
350 // If a stub uses a special cache override this.
351 virtual bool UseSpecialCache() { return false; }
352
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353 // We use this dispatch to statically instantiate the correct code stub for
354 // the given stub key and call the passed function with that code stub.
355 typedef void (*DispatchedCall)(CodeStub* stub, void** value_out);
356 static void Dispatch(Isolate* isolate, uint32_t key, void** value_out,
357 DispatchedCall call);
Steve Blocka7e24c12009-10-30 11:49:00 +0000358
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 static void GetCodeDispatchCall(CodeStub* stub, void** value_out);
Steve Block44f0eee2011-05-26 01:26:41 +0100360
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361 STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
362 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
363 class MinorKeyBits: public BitField<uint32_t,
364 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +0000365
366 friend class BreakPointIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000367
368 Isolate* isolate_;
369};
370
371
372#define DEFINE_CODE_STUB_BASE(NAME, SUPER) \
373 public: \
374 NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \
375 \
376 private: \
377 DISALLOW_COPY_AND_ASSIGN(NAME)
378
379
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400380#define DEFINE_CODE_STUB(NAME, SUPER) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100381 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 inline Major MajorKey() const override { return NAME; }; \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100383 \
384 protected: \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
386
387
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400388#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \
389 private: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 void Generate(MacroAssembler* masm) override; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391 DEFINE_CODE_STUB(NAME, SUPER)
392
393
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400394#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER) \
395 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000396 void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
397 Handle<Code> GenerateCode() override; \
398 DEFINE_CODE_STUB(NAME, SUPER)
399
Ben Murdochc5610432016-08-08 18:44:38 +0100400#define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER) \
401 public: \
402 void GenerateAssembly(CodeStubAssembler* assembler) const override; \
403 DEFINE_CODE_STUB(NAME, SUPER)
404
405#define DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(NAME, SUPER) \
406 public: \
407 static compiler::Node* Generate(CodeStubAssembler* assembler, \
408 compiler::Node* left, compiler::Node* right, \
409 compiler::Node* context); \
410 void GenerateAssembly(CodeStubAssembler* assembler) const override { \
411 assembler->Return(Generate(assembler, assembler->Parameter(0), \
412 assembler->Parameter(1), \
413 assembler->Parameter(2))); \
414 } \
415 DEFINE_CODE_STUB(NAME, SUPER)
416
417#define DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(NAME, SUPER) \
418 public: \
419 static compiler::Node* Generate(CodeStubAssembler* assembler, \
420 compiler::Node* value, \
421 compiler::Node* context); \
422 void GenerateAssembly(CodeStubAssembler* assembler) const override { \
423 assembler->Return(Generate(assembler, assembler->Parameter(0), \
424 assembler->Parameter(1))); \
425 } \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426 DEFINE_CODE_STUB(NAME, SUPER)
427
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400428#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
429 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000430 Handle<Code> GenerateCode() override; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431 DEFINE_CODE_STUB(NAME, SUPER)
432
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \
434 public: \
435 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
436 return NAME##Descriptor(isolate()); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437 }
438
439// There are some code stubs we just can't describe right now with a
440// CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
441// An attempt to retrieve a descriptor will fail.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000442#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \
443 public: \
444 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
445 UNREACHABLE(); \
446 return CallInterfaceDescriptor(); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447 }
448
449
450class PlatformCodeStub : public CodeStub {
451 public:
452 // Retrieve the code for the stub. Generate the code if needed.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 Handle<Code> GenerateCode() override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454
455 protected:
456 explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
457
458 // Generates the assembler code for the stub.
459 virtual void Generate(MacroAssembler* masm) = 0;
460
461 DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub);
462};
463
464
465enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000466
467
468class CodeStubDescriptor {
469 public:
470 explicit CodeStubDescriptor(CodeStub* stub);
471
472 CodeStubDescriptor(Isolate* isolate, uint32_t stub_key);
473
474 void Initialize(Address deoptimization_handler = NULL,
475 int hint_stack_parameter_count = -1,
476 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
477 void Initialize(Register stack_parameter_count,
478 Address deoptimization_handler = NULL,
479 int hint_stack_parameter_count = -1,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000480 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481
482 void SetMissHandler(ExternalReference handler) {
483 miss_handler_ = handler;
484 has_miss_handler_ = true;
485 // Our miss handler infrastructure doesn't currently support
486 // variable stack parameter counts.
487 DCHECK(!stack_parameter_count_.is_valid());
488 }
489
490 void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
491 CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
492
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493 int GetRegisterParameterCount() const {
494 return call_descriptor().GetRegisterParameterCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000495 }
496
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000497 int GetStackParameterCount() const {
498 return call_descriptor().GetStackParameterCount();
499 }
500
501 int GetParameterCount() const {
502 return call_descriptor().GetParameterCount();
503 }
504
505 Register GetRegisterParameter(int index) const {
506 return call_descriptor().GetRegisterParameter(index);
507 }
508
509 Type* GetParameterType(int index) const {
510 return call_descriptor().GetParameterType(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000511 }
512
513 ExternalReference miss_handler() const {
514 DCHECK(has_miss_handler_);
515 return miss_handler_;
516 }
517
518 bool has_miss_handler() const {
519 return has_miss_handler_;
520 }
521
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000522 int GetHandlerParameterCount() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000523 int params = GetParameterCount();
524 if (PassesArgumentsToDeoptimizationHandler()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000525 params += 1;
526 }
527 return params;
528 }
529
530 int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
531 Register stack_parameter_count() const { return stack_parameter_count_; }
532 StubFunctionMode function_mode() const { return function_mode_; }
533 Address deoptimization_handler() const { return deoptimization_handler_; }
534
535 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000536 bool PassesArgumentsToDeoptimizationHandler() const {
537 return stack_parameter_count_.is_valid();
538 }
539
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000540 CallInterfaceDescriptor call_descriptor_;
541 Register stack_parameter_count_;
542 // If hint_stack_parameter_count_ > 0, the code stub can optimize the
543 // return sequence. Default value is -1, which means it is ignored.
544 int hint_stack_parameter_count_;
545 StubFunctionMode function_mode_;
546
547 Address deoptimization_handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000548
549 ExternalReference miss_handler_;
550 bool has_miss_handler_;
551};
552
553
554class HydrogenCodeStub : public CodeStub {
555 public:
556 enum InitializationState {
557 UNINITIALIZED,
558 INITIALIZED
559 };
560
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000561 template<class SubClass>
562 static Handle<Code> GetUninitialized(Isolate* isolate) {
563 SubClass::GenerateAheadOfTime(isolate);
564 return SubClass().GetCode(isolate);
565 }
566
567 // Retrieve the code for the stub. Generate the code if needed.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 Handle<Code> GenerateCode() override = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569
570 bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
571
572 Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
573
574 template<class StateType>
575 void TraceTransition(StateType from, StateType to);
576
577 protected:
578 explicit HydrogenCodeStub(Isolate* isolate,
579 InitializationState state = INITIALIZED)
580 : CodeStub(isolate) {
581 minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
582 }
583
584 void set_sub_minor_key(uint32_t key) {
585 minor_key_ = SubMinorKeyBits::update(minor_key_, key);
586 }
587
588 uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
589
590 static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
591
592 private:
593 class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};
594 class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
595
596 void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss);
597
598 DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub);
Steve Blocka7e24c12009-10-30 11:49:00 +0000599};
600
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602class TurboFanCodeStub : public CodeStub {
603 public:
604 // Retrieve the code for the stub. Generate the code if needed.
605 Handle<Code> GenerateCode() override;
606
607 int GetStackParameterCount() const override {
608 return GetCallInterfaceDescriptor().GetStackParameterCount();
609 }
610
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 protected:
612 explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
613
Ben Murdochc5610432016-08-08 18:44:38 +0100614 virtual void GenerateAssembly(CodeStubAssembler* assembler) const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000615
616 private:
617 DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
618};
619
620
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100621// Helper interface to prepare to/restore after making runtime calls.
622class RuntimeCallHelper {
623 public:
624 virtual ~RuntimeCallHelper() {}
625
626 virtual void BeforeCall(MacroAssembler* masm) const = 0;
627
628 virtual void AfterCall(MacroAssembler* masm) const = 0;
629
630 protected:
631 RuntimeCallHelper() {}
632
633 private:
634 DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
635};
636
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000638} // namespace internal
639} // namespace v8
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100640
641#if V8_TARGET_ARCH_IA32
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642#include "src/ia32/code-stubs-ia32.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100643#elif V8_TARGET_ARCH_X64
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000644#include "src/x64/code-stubs-x64.h"
645#elif V8_TARGET_ARCH_ARM64
646#include "src/arm64/code-stubs-arm64.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100647#elif V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648#include "src/arm/code-stubs-arm.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649#elif V8_TARGET_ARCH_PPC
650#include "src/ppc/code-stubs-ppc.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100651#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000652#include "src/mips/code-stubs-mips.h"
653#elif V8_TARGET_ARCH_MIPS64
654#include "src/mips64/code-stubs-mips64.h"
Ben Murdochda12d292016-06-02 14:46:10 +0100655#elif V8_TARGET_ARCH_S390
656#include "src/s390/code-stubs-s390.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000657#elif V8_TARGET_ARCH_X87
658#include "src/x87/code-stubs-x87.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100659#else
660#error Unsupported target architecture.
661#endif
662
663namespace v8 {
664namespace internal {
665
666
Ben Murdochb0fe1622011-05-05 13:52:32 +0100667// RuntimeCallHelper implementation used in stubs: enters/leaves a
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100668// newly created internal frame before/after the runtime call.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100669class StubRuntimeCallHelper : public RuntimeCallHelper {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100670 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100671 StubRuntimeCallHelper() {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100672
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 void BeforeCall(MacroAssembler* masm) const override;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100674
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000675 void AfterCall(MacroAssembler* masm) const override;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100676};
677
678
679// Trivial RuntimeCallHelper implementation.
680class NopRuntimeCallHelper : public RuntimeCallHelper {
681 public:
682 NopRuntimeCallHelper() {}
683
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000684 void BeforeCall(MacroAssembler* masm) const override {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000686 void AfterCall(MacroAssembler* masm) const override {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100687};
688
689
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690class StringLengthStub : public TurboFanCodeStub {
691 public:
692 explicit StringLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
693
694 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
695 InlineCacheState GetICState() const override { return MONOMORPHIC; }
696 ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
697
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000698 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
Ben Murdochda12d292016-06-02 14:46:10 +0100699 DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000700};
701
Ben Murdochda12d292016-06-02 14:46:10 +0100702class AddStub final : public TurboFanCodeStub {
703 public:
704 explicit AddStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
705
706 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
Ben Murdochc5610432016-08-08 18:44:38 +0100707 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Add, TurboFanCodeStub);
Ben Murdochda12d292016-06-02 14:46:10 +0100708};
709
710class SubtractStub final : public TurboFanCodeStub {
711 public:
712 explicit SubtractStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
713
714 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
Ben Murdochc5610432016-08-08 18:44:38 +0100715 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Subtract, TurboFanCodeStub);
716};
717
718class MultiplyStub final : public TurboFanCodeStub {
719 public:
720 explicit MultiplyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
721
722 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
723 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Multiply, TurboFanCodeStub);
724};
725
726class DivideStub final : public TurboFanCodeStub {
727 public:
728 explicit DivideStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
729
730 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
731 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Divide, TurboFanCodeStub);
732};
733
734class ModulusStub final : public TurboFanCodeStub {
735 public:
736 explicit ModulusStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
737
738 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
739 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(Modulus, TurboFanCodeStub);
740};
741
742class ShiftRightStub final : public TurboFanCodeStub {
743 public:
744 explicit ShiftRightStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
745
746 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
747 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftRight, TurboFanCodeStub);
748};
749
750class ShiftRightLogicalStub final : public TurboFanCodeStub {
751 public:
752 explicit ShiftRightLogicalStub(Isolate* isolate)
753 : TurboFanCodeStub(isolate) {}
754
755 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
756 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftRightLogical, TurboFanCodeStub);
757};
758
759class ShiftLeftStub final : public TurboFanCodeStub {
760 public:
761 explicit ShiftLeftStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
762
763 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
764 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(ShiftLeft, TurboFanCodeStub);
Ben Murdochda12d292016-06-02 14:46:10 +0100765};
766
767class BitwiseAndStub final : public TurboFanCodeStub {
768 public:
769 explicit BitwiseAndStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
770
771 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
Ben Murdochc5610432016-08-08 18:44:38 +0100772 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseAnd, TurboFanCodeStub);
Ben Murdochda12d292016-06-02 14:46:10 +0100773};
774
775class BitwiseOrStub final : public TurboFanCodeStub {
776 public:
777 explicit BitwiseOrStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
778
779 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
Ben Murdochc5610432016-08-08 18:44:38 +0100780 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseOr, TurboFanCodeStub);
Ben Murdochda12d292016-06-02 14:46:10 +0100781};
782
783class BitwiseXorStub final : public TurboFanCodeStub {
784 public:
785 explicit BitwiseXorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
786
787 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
Ben Murdochc5610432016-08-08 18:44:38 +0100788 DEFINE_TURBOFAN_BINARY_OP_CODE_STUB(BitwiseXor, TurboFanCodeStub);
789};
790
791class IncStub final : public TurboFanCodeStub {
792 public:
793 explicit IncStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
794
795 DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
796 DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(Inc, TurboFanCodeStub);
797};
798
799class DecStub final : public TurboFanCodeStub {
800 public:
801 explicit DecStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
802
803 DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
804 DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(Dec, TurboFanCodeStub);
805};
806
807class InstanceOfStub final : public TurboFanCodeStub {
808 public:
809 explicit InstanceOfStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
810
811 private:
812 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
813 DEFINE_TURBOFAN_CODE_STUB(InstanceOf, TurboFanCodeStub);
Ben Murdochda12d292016-06-02 14:46:10 +0100814};
815
816class LessThanStub final : public TurboFanCodeStub {
817 public:
818 explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
819
820 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
821 DEFINE_TURBOFAN_CODE_STUB(LessThan, TurboFanCodeStub);
822};
823
824class LessThanOrEqualStub final : public TurboFanCodeStub {
825 public:
826 explicit LessThanOrEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
827
828 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
829 DEFINE_TURBOFAN_CODE_STUB(LessThanOrEqual, TurboFanCodeStub);
830};
831
832class GreaterThanStub final : public TurboFanCodeStub {
833 public:
834 explicit GreaterThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
835
836 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
837 DEFINE_TURBOFAN_CODE_STUB(GreaterThan, TurboFanCodeStub);
838};
839
840class GreaterThanOrEqualStub final : public TurboFanCodeStub {
841 public:
842 explicit GreaterThanOrEqualStub(Isolate* isolate)
843 : TurboFanCodeStub(isolate) {}
844
845 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
846 DEFINE_TURBOFAN_CODE_STUB(GreaterThanOrEqual, TurboFanCodeStub);
847};
848
849class EqualStub final : public TurboFanCodeStub {
850 public:
851 explicit EqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
852
853 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
854 DEFINE_TURBOFAN_CODE_STUB(Equal, TurboFanCodeStub);
855};
856
857class NotEqualStub final : public TurboFanCodeStub {
858 public:
859 explicit NotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
860
861 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
862 DEFINE_TURBOFAN_CODE_STUB(NotEqual, TurboFanCodeStub);
863};
864
865class StrictEqualStub final : public TurboFanCodeStub {
866 public:
867 explicit StrictEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
868
869 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
870 DEFINE_TURBOFAN_CODE_STUB(StrictEqual, TurboFanCodeStub);
871};
872
873class StrictNotEqualStub final : public TurboFanCodeStub {
874 public:
875 explicit StrictNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
876
877 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
878 DEFINE_TURBOFAN_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
879};
880
881class StringEqualStub final : public TurboFanCodeStub {
882 public:
883 explicit StringEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
884
885 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
886 DEFINE_TURBOFAN_CODE_STUB(StringEqual, TurboFanCodeStub);
887};
888
889class StringNotEqualStub final : public TurboFanCodeStub {
890 public:
891 explicit StringNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
892
893 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
894 DEFINE_TURBOFAN_CODE_STUB(StringNotEqual, TurboFanCodeStub);
895};
896
897class StringLessThanStub final : public TurboFanCodeStub {
898 public:
899 explicit StringLessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
900
901 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
902 DEFINE_TURBOFAN_CODE_STUB(StringLessThan, TurboFanCodeStub);
903};
904
905class StringLessThanOrEqualStub final : public TurboFanCodeStub {
906 public:
907 explicit StringLessThanOrEqualStub(Isolate* isolate)
908 : TurboFanCodeStub(isolate) {}
909
910 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
911 DEFINE_TURBOFAN_CODE_STUB(StringLessThanOrEqual, TurboFanCodeStub);
912};
913
914class StringGreaterThanStub final : public TurboFanCodeStub {
915 public:
916 explicit StringGreaterThanStub(Isolate* isolate)
917 : TurboFanCodeStub(isolate) {}
918
919 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
920 DEFINE_TURBOFAN_CODE_STUB(StringGreaterThan, TurboFanCodeStub);
921};
922
923class StringGreaterThanOrEqualStub final : public TurboFanCodeStub {
924 public:
925 explicit StringGreaterThanOrEqualStub(Isolate* isolate)
926 : TurboFanCodeStub(isolate) {}
927
928 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
929 DEFINE_TURBOFAN_CODE_STUB(StringGreaterThanOrEqual, TurboFanCodeStub);
930};
931
932class ToBooleanStub final : public TurboFanCodeStub {
933 public:
934 explicit ToBooleanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
935
936 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
937 DEFINE_TURBOFAN_CODE_STUB(ToBoolean, TurboFanCodeStub);
938};
939
940class ToIntegerStub final : public TurboFanCodeStub {
941 public:
942 explicit ToIntegerStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
943
944 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
945 DEFINE_TURBOFAN_CODE_STUB(ToInteger, TurboFanCodeStub);
946};
947
948class ToLengthStub final : public TurboFanCodeStub {
949 public:
950 explicit ToLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
951
952 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
953 DEFINE_TURBOFAN_CODE_STUB(ToLength, TurboFanCodeStub);
954};
955
956class StoreInterceptorStub : public TurboFanCodeStub {
957 public:
958 explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
959
Ben Murdochc5610432016-08-08 18:44:38 +0100960 void GenerateAssembly(CodeStubAssembler* assember) const override;
Ben Murdochda12d292016-06-02 14:46:10 +0100961
962 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdochc5610432016-08-08 18:44:38 +0100963 ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
964 InlineCacheState GetICState() const override { return MONOMORPHIC; }
Ben Murdochda12d292016-06-02 14:46:10 +0100965
966 DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
967 DEFINE_CODE_STUB(StoreInterceptor, TurboFanCodeStub);
968};
969
970class LoadIndexedInterceptorStub : public TurboFanCodeStub {
971 public:
972 explicit LoadIndexedInterceptorStub(Isolate* isolate)
973 : TurboFanCodeStub(isolate) {}
974
975 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdochc5610432016-08-08 18:44:38 +0100976 ExtraICState GetExtraICState() const override { return Code::KEYED_LOAD_IC; }
977 InlineCacheState GetICState() const override { return MONOMORPHIC; }
Ben Murdochda12d292016-06-02 14:46:10 +0100978
979 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
980 DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
981};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000982
Ben Murdochc5610432016-08-08 18:44:38 +0100983// ES6 section 12.10.3 "in" operator evaluation.
984class HasPropertyStub : public TurboFanCodeStub {
985 public:
986 explicit HasPropertyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
987
988 DEFINE_CALL_INTERFACE_DESCRIPTOR(HasProperty);
989 DEFINE_TURBOFAN_CODE_STUB(HasProperty, TurboFanCodeStub);
990};
991
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000992enum StringAddFlags {
993 // Omit both parameter checks.
994 STRING_ADD_CHECK_NONE = 0,
995 // Check left parameter.
996 STRING_ADD_CHECK_LEFT = 1 << 0,
997 // Check right parameter.
998 STRING_ADD_CHECK_RIGHT = 1 << 1,
999 // Check both parameters.
1000 STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT,
1001 // Convert parameters when check fails (instead of throwing an exception).
1002 STRING_ADD_CONVERT = 1 << 2,
1003 STRING_ADD_CONVERT_LEFT = STRING_ADD_CHECK_LEFT | STRING_ADD_CONVERT,
1004 STRING_ADD_CONVERT_RIGHT = STRING_ADD_CHECK_RIGHT | STRING_ADD_CONVERT
1005};
1006
1007
1008std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags);
1009
1010
1011class NumberToStringStub final : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001012 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013 explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001014
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001015 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1016 static const int kNumber = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001017
Ben Murdochda12d292016-06-02 14:46:10 +01001018 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001020};
1021
1022
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001023class TypeofStub final : public HydrogenCodeStub {
1024 public:
1025 explicit TypeofStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1026
1027 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1028 static const int kObject = 0;
1029
1030 static void GenerateAheadOfTime(Isolate* isolate);
1031
1032 DEFINE_CALL_INTERFACE_DESCRIPTOR(Typeof);
1033 DEFINE_HYDROGEN_CODE_STUB(Typeof, HydrogenCodeStub);
1034};
1035
1036
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001037class FastNewClosureStub : public HydrogenCodeStub {
Steve Block1e0659c2011-05-24 12:43:12 +01001038 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001039 FastNewClosureStub(Isolate* isolate, LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001040 FunctionKind kind)
1041 : HydrogenCodeStub(isolate) {
1042 DCHECK(IsValidFunctionKind(kind));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001043 set_sub_minor_key(LanguageModeBits::encode(language_mode) |
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044 FunctionKindBits::encode(kind));
1045 }
Steve Block1e0659c2011-05-24 12:43:12 +01001046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001047 LanguageMode language_mode() const {
1048 return LanguageModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001049 }
1050
1051 FunctionKind kind() const {
1052 return FunctionKindBits::decode(sub_minor_key());
1053 }
Steve Block1e0659c2011-05-24 12:43:12 +01001054
1055 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001056 STATIC_ASSERT(LANGUAGE_END == 3);
1057 class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
Ben Murdochc5610432016-08-08 18:44:38 +01001058 class FunctionKindBits : public BitField<FunctionKind, 2, 9> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059
1060 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
1061 DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
Steve Block1e0659c2011-05-24 12:43:12 +01001062};
1063
1064
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001065class FastNewContextStub final : public HydrogenCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001066 public:
1067 static const int kMaximumSlots = 64;
1068
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001069 FastNewContextStub(Isolate* isolate, int slots) : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 DCHECK(slots >= 0 && slots <= kMaximumSlots);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071 set_sub_minor_key(SlotsBits::encode(slots));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001072 }
1073
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001074 int slots() const { return SlotsBits::decode(sub_minor_key()); }
1075
1076 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1077 static const int kFunction = 0;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001078
1079 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001080 class SlotsBits : public BitField<int, 0, 8> {};
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewContext);
1083 DEFINE_HYDROGEN_CODE_STUB(FastNewContext, HydrogenCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001084};
1085
1086
Ben Murdoch097c5b22016-05-18 11:27:45 +01001087class FastNewObjectStub final : public PlatformCodeStub {
1088 public:
1089 explicit FastNewObjectStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1090
1091 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewObject);
1092 DEFINE_PLATFORM_CODE_STUB(FastNewObject, PlatformCodeStub);
1093};
1094
1095
1096// TODO(turbofan): This stub should be possible to write in TurboFan
1097// using the CodeStubAssembler very soon in a way that is as efficient
1098// and easy as the current handwritten version, which is partly a copy
1099// of the strict arguments object materialization code.
1100class FastNewRestParameterStub final : public PlatformCodeStub {
1101 public:
Ben Murdochc5610432016-08-08 18:44:38 +01001102 explicit FastNewRestParameterStub(Isolate* isolate,
1103 bool skip_stub_frame = false)
1104 : PlatformCodeStub(isolate) {
1105 minor_key_ = SkipStubFrameBits::encode(skip_stub_frame);
1106 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001107
1108 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewRestParameter);
1109 DEFINE_PLATFORM_CODE_STUB(FastNewRestParameter, PlatformCodeStub);
Ben Murdochc5610432016-08-08 18:44:38 +01001110
1111 int skip_stub_frame() const { return SkipStubFrameBits::decode(minor_key_); }
1112
1113 private:
1114 class SkipStubFrameBits : public BitField<bool, 0, 1> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001115};
1116
1117
1118// TODO(turbofan): This stub should be possible to write in TurboFan
1119// using the CodeStubAssembler very soon in a way that is as efficient
1120// and easy as the current handwritten version.
1121class FastNewSloppyArgumentsStub final : public PlatformCodeStub {
1122 public:
Ben Murdochc5610432016-08-08 18:44:38 +01001123 explicit FastNewSloppyArgumentsStub(Isolate* isolate,
1124 bool skip_stub_frame = false)
1125 : PlatformCodeStub(isolate) {
1126 minor_key_ = SkipStubFrameBits::encode(skip_stub_frame);
1127 }
1128
1129 int skip_stub_frame() const { return SkipStubFrameBits::decode(minor_key_); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001130
1131 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewSloppyArguments);
1132 DEFINE_PLATFORM_CODE_STUB(FastNewSloppyArguments, PlatformCodeStub);
Ben Murdochc5610432016-08-08 18:44:38 +01001133
1134 private:
1135 class SkipStubFrameBits : public BitField<bool, 0, 1> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001136};
1137
1138
1139// TODO(turbofan): This stub should be possible to write in TurboFan
1140// using the CodeStubAssembler very soon in a way that is as efficient
1141// and easy as the current handwritten version.
1142class FastNewStrictArgumentsStub final : public PlatformCodeStub {
1143 public:
Ben Murdochc5610432016-08-08 18:44:38 +01001144 explicit FastNewStrictArgumentsStub(Isolate* isolate,
1145 bool skip_stub_frame = false)
1146 : PlatformCodeStub(isolate) {
1147 minor_key_ = SkipStubFrameBits::encode(skip_stub_frame);
1148 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001149
1150 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewStrictArguments);
1151 DEFINE_PLATFORM_CODE_STUB(FastNewStrictArguments, PlatformCodeStub);
Ben Murdochc5610432016-08-08 18:44:38 +01001152
1153 int skip_stub_frame() const { return SkipStubFrameBits::decode(minor_key_); }
1154
1155 private:
1156 class SkipStubFrameBits : public BitField<bool, 0, 1> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001157};
1158
1159
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001160class FastCloneRegExpStub final : public HydrogenCodeStub {
1161 public:
1162 explicit FastCloneRegExpStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1163
1164 private:
1165 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneRegExp);
1166 DEFINE_HYDROGEN_CODE_STUB(FastCloneRegExp, HydrogenCodeStub);
1167};
1168
1169
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170class FastCloneShallowArrayStub : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001171 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001172 FastCloneShallowArrayStub(Isolate* isolate,
1173 AllocationSiteMode allocation_site_mode)
1174 : HydrogenCodeStub(isolate) {
1175 set_sub_minor_key(AllocationSiteModeBits::encode(allocation_site_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001176 }
1177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001178 AllocationSiteMode allocation_site_mode() const {
1179 return AllocationSiteModeBits::decode(sub_minor_key());
1180 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001181
1182 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001183 class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001184
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001185 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowArray);
1186 DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowArray, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001187};
1188
Ben Murdochc5610432016-08-08 18:44:38 +01001189class FastCloneShallowObjectStub : public TurboFanCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001190 public:
1191 // Maximum number of properties in copied object.
1192 static const int kMaximumClonedProperties = 6;
1193
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001194 FastCloneShallowObjectStub(Isolate* isolate, int length)
Ben Murdochc5610432016-08-08 18:44:38 +01001195 : TurboFanCodeStub(isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001196 DCHECK_GE(length, 0);
1197 DCHECK_LE(length, kMaximumClonedProperties);
Ben Murdochc5610432016-08-08 18:44:38 +01001198 minor_key_ = LengthBits::encode(LengthBits::encode(length));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001199 }
1200
Ben Murdochc5610432016-08-08 18:44:38 +01001201 static compiler::Node* GenerateFastPath(
1202 CodeStubAssembler* assembler,
1203 compiler::CodeAssembler::Label* call_runtime, compiler::Node* closure,
1204 compiler::Node* literals_index, compiler::Node* properties_count);
1205
1206 static bool IsSupported(ObjectLiteral* expr);
1207 static int PropertiesCount(int literal_length);
1208
1209 int length() const { return LengthBits::decode(minor_key_); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001210
1211 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001212 class LengthBits : public BitField<int, 0, 4> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001213
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001214 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowObject);
Ben Murdochc5610432016-08-08 18:44:38 +01001215 DEFINE_TURBOFAN_CODE_STUB(FastCloneShallowObject, TurboFanCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001216};
1217
1218
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001219class CreateAllocationSiteStub : public HydrogenCodeStub {
1220 public:
1221 explicit CreateAllocationSiteStub(Isolate* isolate)
1222 : HydrogenCodeStub(isolate) { }
1223
1224 static void GenerateAheadOfTime(Isolate* isolate);
1225
1226 DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite);
1227 DEFINE_HYDROGEN_CODE_STUB(CreateAllocationSite, HydrogenCodeStub);
1228};
1229
1230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001231class CreateWeakCellStub : public HydrogenCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001232 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001233 explicit CreateWeakCellStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Ben Murdochb0fe1622011-05-05 13:52:32 +01001234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001235 static void GenerateAheadOfTime(Isolate* isolate);
1236
1237 DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
1238 DEFINE_HYDROGEN_CODE_STUB(CreateWeakCell, HydrogenCodeStub);
1239};
1240
1241
1242class GrowArrayElementsStub : public HydrogenCodeStub {
1243 public:
1244 GrowArrayElementsStub(Isolate* isolate, bool is_js_array, ElementsKind kind)
1245 : HydrogenCodeStub(isolate) {
1246 set_sub_minor_key(ElementsKindBits::encode(kind) |
1247 IsJsArrayBits::encode(is_js_array));
Ben Murdochb0fe1622011-05-05 13:52:32 +01001248 }
1249
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001250 ElementsKind elements_kind() const {
1251 return ElementsKindBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001252 }
1253
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001254 bool is_js_array() const { return IsJsArrayBits::decode(sub_minor_key()); }
1255
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001256 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001257 class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
1258 class IsJsArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001259
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001260 DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
1261 DEFINE_HYDROGEN_CODE_STUB(GrowArrayElements, HydrogenCodeStub);
1262};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001263
Ben Murdochda12d292016-06-02 14:46:10 +01001264class FastArrayPushStub : public HydrogenCodeStub {
1265 public:
1266 explicit FastArrayPushStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1267
1268 private:
1269 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastArrayPush);
1270 DEFINE_HYDROGEN_CODE_STUB(FastArrayPush, HydrogenCodeStub);
1271};
Ben Murdoch086aeea2011-05-13 15:57:08 +01001272
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001273
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001274enum AllocationSiteOverrideMode {
1275 DONT_OVERRIDE,
1276 DISABLE_ALLOCATION_SITES,
1277 LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
1278};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001279
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001280
1281class ArrayConstructorStub: public PlatformCodeStub {
1282 public:
1283 enum ArgumentCountKey { ANY, NONE, ONE, MORE_THAN_ONE };
1284
1285 ArrayConstructorStub(Isolate* isolate, int argument_count);
1286
1287 explicit ArrayConstructorStub(Isolate* isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001288
1289 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001290 ArgumentCountKey argument_count() const {
1291 return ArgumentCountBits::decode(minor_key_);
1292 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001293
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001294 void GenerateDispatchToArrayStub(MacroAssembler* masm,
1295 AllocationSiteOverrideMode mode);
1296
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001297 void PrintName(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001298
1299 class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
1300
1301 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
1302 DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001303};
1304
1305
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001306class InternalArrayConstructorStub: public PlatformCodeStub {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001307 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001308 explicit InternalArrayConstructorStub(Isolate* isolate);
1309
1310 private:
1311 void GenerateCase(MacroAssembler* masm, ElementsKind kind);
1312
1313 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
1314 DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
1315};
1316
1317
1318class MathPowStub: public PlatformCodeStub {
1319 public:
1320 enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK };
1321
1322 MathPowStub(Isolate* isolate, ExponentType exponent_type)
1323 : PlatformCodeStub(isolate) {
1324 minor_key_ = ExponentTypeBits::encode(exponent_type);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001325 }
1326
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001327 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001328 if (exponent_type() == TAGGED) {
1329 return MathPowTaggedDescriptor(isolate());
1330 } else if (exponent_type() == INTEGER) {
1331 return MathPowIntegerDescriptor(isolate());
1332 }
1333 // A CallInterfaceDescriptor doesn't specify double registers (yet).
1334 return ContextOnlyDescriptor(isolate());
1335 }
1336
1337 private:
1338 ExponentType exponent_type() const {
1339 return ExponentTypeBits::decode(minor_key_);
1340 }
1341
1342 class ExponentTypeBits : public BitField<ExponentType, 0, 2> {};
1343
1344 DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub);
1345};
1346
1347
1348class CallICStub: public PlatformCodeStub {
1349 public:
1350 CallICStub(Isolate* isolate, const CallICState& state)
1351 : PlatformCodeStub(isolate) {
1352 minor_key_ = state.GetExtraICState();
1353 }
1354
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001355 Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001356
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001357 InlineCacheState GetICState() const override { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001358
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001359 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001360 return static_cast<ExtraICState>(minor_key_);
1361 }
1362
1363 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001364 int arg_count() const { return state().argc(); }
1365 ConvertReceiverMode convert_mode() const { return state().convert_mode(); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001366 TailCallMode tail_call_mode() const { return state().tail_call_mode(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001367
1368 CallICState state() const {
1369 return CallICState(static_cast<ExtraICState>(minor_key_));
1370 }
1371
1372 // Code generation helpers.
1373 void GenerateMiss(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001374 void HandleArrayCase(MacroAssembler* masm, Label* miss);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001375
1376 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001377 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001378
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001379 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedbackAndVector);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001380 DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
1381};
1382
1383
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001384// TODO(verwaest): Translate to hydrogen code stub.
1385class FunctionPrototypeStub : public PlatformCodeStub {
1386 public:
1387 explicit FunctionPrototypeStub(Isolate* isolate)
1388 : PlatformCodeStub(isolate) {}
1389
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001390 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001391
1392 // TODO(mvstanton): only the receiver register is accessed. When this is
1393 // translated to a hydrogen code stub, a new CallInterfaceDescriptor
1394 // should be created that just uses that register for more efficient code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001395 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
1396 return LoadWithVectorDescriptor(isolate());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001397 }
1398
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001399 DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
1400};
1401
1402
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001403class LoadIndexedStringStub : public PlatformCodeStub {
1404 public:
1405 explicit LoadIndexedStringStub(Isolate* isolate)
1406 : PlatformCodeStub(isolate) {}
1407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001408 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001409
1410 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
1411 DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
1412};
1413
1414
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001415class HandlerStub : public HydrogenCodeStub {
1416 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1418 ExtraICState GetExtraICState() const override { return kind(); }
1419 InlineCacheState GetICState() const override { return MONOMORPHIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001421 void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001423 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001424
1425 protected:
1426 explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1427
1428 virtual Code::Kind kind() const = 0;
1429
1430 DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub);
1431};
1432
1433
1434class LoadFieldStub: public HandlerStub {
1435 public:
1436 LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate) {
1437 int property_index_key = index.GetFieldAccessStubKey();
1438 set_sub_minor_key(LoadFieldByIndexBits::encode(property_index_key));
1439 }
1440
1441 FieldIndex index() const {
1442 int property_index_key = LoadFieldByIndexBits::decode(sub_minor_key());
1443 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1444 }
1445
1446 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001447 Code::Kind kind() const override { return Code::LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001448
1449 private:
1450 class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
1451
1452 DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub);
1453};
1454
1455
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001456class ArrayBufferViewLoadFieldStub : public HandlerStub {
1457 public:
1458 ArrayBufferViewLoadFieldStub(Isolate* isolate, FieldIndex index)
1459 : HandlerStub(isolate) {
1460 int property_index_key = index.GetFieldAccessStubKey();
1461 set_sub_minor_key(
1462 ArrayBufferViewLoadFieldByIndexBits::encode(property_index_key));
1463 }
1464
1465 FieldIndex index() const {
1466 int property_index_key =
1467 ArrayBufferViewLoadFieldByIndexBits::decode(sub_minor_key());
1468 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1469 }
1470
1471 protected:
1472 Code::Kind kind() const override { return Code::LOAD_IC; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001473
1474 private:
1475 class ArrayBufferViewLoadFieldByIndexBits : public BitField<int, 0, 13> {};
1476
1477 DEFINE_HANDLER_CODE_STUB(ArrayBufferViewLoadField, HandlerStub);
1478};
1479
1480
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001481class KeyedLoadSloppyArgumentsStub : public HandlerStub {
1482 public:
1483 explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
1484 : HandlerStub(isolate) {}
1485
1486 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001487 Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001488
1489 private:
1490 DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
1491};
1492
1493
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001494class CommonStoreModeBits : public BitField<KeyedAccessStoreMode, 0, 3> {};
1495
1496class KeyedStoreSloppyArgumentsStub : public HandlerStub {
1497 public:
1498 explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate,
1499 KeyedAccessStoreMode mode)
1500 : HandlerStub(isolate) {
1501 set_sub_minor_key(CommonStoreModeBits::encode(mode));
1502 }
1503
1504 protected:
1505 Code::Kind kind() const override { return Code::KEYED_STORE_IC; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001506
1507 private:
1508 DEFINE_HANDLER_CODE_STUB(KeyedStoreSloppyArguments, HandlerStub);
1509};
1510
1511
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001512class LoadConstantStub : public HandlerStub {
1513 public:
1514 LoadConstantStub(Isolate* isolate, int constant_index)
1515 : HandlerStub(isolate) {
1516 set_sub_minor_key(ConstantIndexBits::encode(constant_index));
1517 }
1518
1519 int constant_index() const {
1520 return ConstantIndexBits::decode(sub_minor_key());
1521 }
1522
1523 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001524 Code::Kind kind() const override { return Code::LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001525
1526 private:
1527 class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {};
1528
1529 DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub);
1530};
1531
Ben Murdochc5610432016-08-08 18:44:38 +01001532class LoadApiGetterStub : public TurboFanCodeStub {
1533 public:
1534 LoadApiGetterStub(Isolate* isolate, bool receiver_is_holder, int index)
1535 : TurboFanCodeStub(isolate) {
1536 // If that's not true, we need to ensure that the receiver is actually a
1537 // JSReceiver. http://crbug.com/609134
1538 DCHECK(receiver_is_holder);
1539 minor_key_ = IndexBits::encode(index) |
1540 ReceiverIsHolderBits::encode(receiver_is_holder);
1541 }
1542
1543 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1544 ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
1545 InlineCacheState GetICState() const override { return MONOMORPHIC; }
1546
1547 int index() const { return IndexBits::decode(minor_key_); }
1548 bool receiver_is_holder() const {
1549 return ReceiverIsHolderBits::decode(minor_key_);
1550 }
1551
1552 private:
1553 class ReceiverIsHolderBits : public BitField<bool, 0, 1> {};
1554 class IndexBits : public BitField<int, 1, kDescriptorIndexBitCount> {};
1555
1556 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
1557 DEFINE_TURBOFAN_CODE_STUB(LoadApiGetter, TurboFanCodeStub);
1558};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001559
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001560class StoreFieldStub : public HandlerStub {
1561 public:
1562 StoreFieldStub(Isolate* isolate, FieldIndex index,
1563 Representation representation)
1564 : HandlerStub(isolate) {
1565 int property_index_key = index.GetFieldAccessStubKey();
1566 uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1567 set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1568 RepresentationBits::encode(repr));
1569 }
1570
1571 FieldIndex index() const {
1572 int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1573 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1574 }
1575
1576 Representation representation() {
1577 uint8_t repr = RepresentationBits::decode(sub_minor_key());
1578 return PropertyDetails::DecodeRepresentation(repr);
1579 }
1580
1581 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001582 Code::Kind kind() const override { return Code::STORE_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001583
1584 private:
1585 class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1586 class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1587
1588 DEFINE_HANDLER_CODE_STUB(StoreField, HandlerStub);
1589};
1590
1591
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001592// Register and parameter access methods are specified here instead of in
1593// the CallInterfaceDescriptor because the stub uses a different descriptor
1594// if FLAG_vector_stores is on.
1595class StoreTransitionHelper {
1596 public:
1597 static Register ReceiverRegister() {
1598 return StoreTransitionDescriptor::ReceiverRegister();
1599 }
1600
1601 static Register NameRegister() {
1602 return StoreTransitionDescriptor::NameRegister();
1603 }
1604
1605 static Register ValueRegister() {
1606 return StoreTransitionDescriptor::ValueRegister();
1607 }
1608
1609 static Register SlotRegister() {
1610 return VectorStoreTransitionDescriptor::SlotRegister();
1611 }
1612
1613 static Register VectorRegister() {
1614 return VectorStoreTransitionDescriptor::VectorRegister();
1615 }
1616
1617 static Register MapRegister() {
1618 return VectorStoreTransitionDescriptor::MapRegister();
1619 }
1620
1621 static int ReceiverIndex() {
1622 return StoreTransitionDescriptor::kReceiverIndex;
1623 }
1624
1625 static int NameIndex() { return StoreTransitionDescriptor::kReceiverIndex; }
1626
1627 static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; }
1628
1629 static int MapIndex() {
1630 DCHECK(static_cast<int>(VectorStoreTransitionDescriptor::kMapIndex) ==
1631 static_cast<int>(StoreTransitionDescriptor::kMapIndex));
1632 return StoreTransitionDescriptor::kMapIndex;
1633 }
1634
1635 static int VectorIndex() {
1636 if (HasVirtualSlotArg()) {
1637 return VectorStoreTransitionDescriptor::kVirtualSlotVectorIndex;
1638 }
1639 return VectorStoreTransitionDescriptor::kVectorIndex;
1640 }
1641
1642 // Some platforms don't have a slot arg.
1643 static bool HasVirtualSlotArg() {
1644 return SlotRegister().is(no_reg);
1645 }
1646};
1647
1648
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001649class StoreTransitionStub : public HandlerStub {
1650 public:
1651 enum StoreMode {
1652 StoreMapOnly,
1653 StoreMapAndValue,
1654 ExtendStorageAndStoreMapAndValue
1655 };
1656
1657 explicit StoreTransitionStub(Isolate* isolate) : HandlerStub(isolate) {
1658 set_sub_minor_key(StoreModeBits::encode(StoreMapOnly));
1659 }
1660
1661 StoreTransitionStub(Isolate* isolate, FieldIndex index,
1662 Representation representation, StoreMode store_mode)
1663 : HandlerStub(isolate) {
1664 DCHECK(store_mode != StoreMapOnly);
1665 int property_index_key = index.GetFieldAccessStubKey();
1666 uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1667 set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1668 RepresentationBits::encode(repr) |
1669 StoreModeBits::encode(store_mode));
1670 }
1671
1672 FieldIndex index() const {
1673 DCHECK(store_mode() != StoreMapOnly);
1674 int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1675 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1676 }
1677
1678 Representation representation() {
1679 DCHECK(store_mode() != StoreMapOnly);
1680 uint8_t repr = RepresentationBits::decode(sub_minor_key());
1681 return PropertyDetails::DecodeRepresentation(repr);
1682 }
1683
1684 StoreMode store_mode() const {
1685 return StoreModeBits::decode(sub_minor_key());
1686 }
1687
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001688 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001689
1690 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 Code::Kind kind() const override { return Code::STORE_IC; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001692
1693 private:
1694 class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1695 class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1696 class StoreModeBits : public BitField<StoreMode, 17, 2> {};
1697
1698 DEFINE_HANDLER_CODE_STUB(StoreTransition, HandlerStub);
1699};
1700
1701
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001702class StoreGlobalStub : public HandlerStub {
1703 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001704 StoreGlobalStub(Isolate* isolate, PropertyCellType type,
1705 Maybe<PropertyCellConstantType> constant_type,
1706 bool check_global)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001707 : HandlerStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001708 PropertyCellConstantType encoded_constant_type =
1709 constant_type.FromMaybe(PropertyCellConstantType::kSmi);
1710 set_sub_minor_key(CellTypeBits::encode(type) |
1711 ConstantTypeBits::encode(encoded_constant_type) |
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001712 CheckGlobalBits::encode(check_global));
1713 }
1714
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001715 static Handle<HeapObject> property_cell_placeholder(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001716 return isolate->factory()->uninitialized_value();
1717 }
1718
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719 static Handle<HeapObject> global_map_placeholder(Isolate* isolate) {
1720 return isolate->factory()->termination_exception();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001721 }
1722
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001723 Handle<Code> GetCodeCopyFromTemplate(Handle<JSGlobalObject> global,
1724 Handle<PropertyCell> cell) {
1725 Code::FindAndReplacePattern pattern;
1726 if (check_global()) {
1727 pattern.Add(handle(global_map_placeholder(isolate())->map()),
1728 Map::WeakCellForMap(Handle<Map>(global->map())));
1729 }
1730 pattern.Add(handle(property_cell_placeholder(isolate())->map()),
1731 isolate()->factory()->NewWeakCell(cell));
1732 return CodeStub::GetCodeCopy(pattern);
1733 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001734
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001735 Code::Kind kind() const override { return Code::STORE_IC; }
1736
1737 PropertyCellType cell_type() const {
1738 return CellTypeBits::decode(sub_minor_key());
1739 }
1740
1741 PropertyCellConstantType constant_type() const {
1742 DCHECK(PropertyCellType::kConstantType == cell_type());
1743 return ConstantTypeBits::decode(sub_minor_key());
1744 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001745
1746 bool check_global() const { return CheckGlobalBits::decode(sub_minor_key()); }
1747
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001748 Representation representation() {
1749 return Representation::FromKind(
1750 RepresentationBits::decode(sub_minor_key()));
1751 }
1752
1753 void set_representation(Representation r) {
1754 set_sub_minor_key(RepresentationBits::update(sub_minor_key(), r.kind()));
1755 }
1756
1757 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001758 class CellTypeBits : public BitField<PropertyCellType, 0, 2> {};
1759 class ConstantTypeBits : public BitField<PropertyCellConstantType, 2, 2> {};
1760 class RepresentationBits : public BitField<Representation::Kind, 4, 8> {};
1761 class CheckGlobalBits : public BitField<bool, 12, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001762
1763 DEFINE_HANDLER_CODE_STUB(StoreGlobal, HandlerStub);
1764};
1765
1766
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767class LoadGlobalViaContextStub final : public PlatformCodeStub {
1768 public:
1769 static const int kMaximumDepth = 15;
1770
1771 LoadGlobalViaContextStub(Isolate* isolate, int depth)
1772 : PlatformCodeStub(isolate) {
1773 minor_key_ = DepthBits::encode(depth);
1774 }
1775
1776 int depth() const { return DepthBits::decode(minor_key_); }
1777
1778 private:
1779 class DepthBits : public BitField<int, 0, 4> {};
1780 STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
1781
1782 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadGlobalViaContext);
1783 DEFINE_PLATFORM_CODE_STUB(LoadGlobalViaContext, PlatformCodeStub);
1784};
1785
1786
1787class StoreGlobalViaContextStub final : public PlatformCodeStub {
1788 public:
1789 static const int kMaximumDepth = 15;
1790
1791 StoreGlobalViaContextStub(Isolate* isolate, int depth,
1792 LanguageMode language_mode)
1793 : PlatformCodeStub(isolate) {
1794 minor_key_ =
1795 DepthBits::encode(depth) | LanguageModeBits::encode(language_mode);
1796 }
1797
1798 int depth() const { return DepthBits::decode(minor_key_); }
1799 LanguageMode language_mode() const {
1800 return LanguageModeBits::decode(minor_key_);
1801 }
1802
1803 private:
1804 class DepthBits : public BitField<int, 0, 4> {};
1805 STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
1806 class LanguageModeBits : public BitField<LanguageMode, 4, 2> {};
1807 STATIC_ASSERT(LANGUAGE_END == 3);
1808
1809 DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreGlobalViaContext);
1810 DEFINE_PLATFORM_CODE_STUB(StoreGlobalViaContext, PlatformCodeStub);
1811};
1812
Ben Murdochda12d292016-06-02 14:46:10 +01001813class CallApiCallbackStub : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001814 public:
Ben Murdochda12d292016-06-02 14:46:10 +01001815 static const int kArgBits = 3;
1816 static const int kArgMax = (1 << kArgBits) - 1;
1817
1818 // CallApiCallbackStub for regular setters and getters.
1819 CallApiCallbackStub(Isolate* isolate, bool is_store, bool call_data_undefined,
1820 bool is_lazy)
1821 : CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store,
1822 call_data_undefined, is_lazy) {}
1823
1824 // CallApiCallbackStub for callback functions.
1825 CallApiCallbackStub(Isolate* isolate, int argc, bool call_data_undefined)
1826 : CallApiCallbackStub(isolate, argc, false, call_data_undefined, false) {}
1827
1828 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
1829 return ApiCallbackDescriptorBase::ForArgs(isolate(), argc());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001830 }
1831
1832 private:
Ben Murdochda12d292016-06-02 14:46:10 +01001833 CallApiCallbackStub(Isolate* isolate, int argc, bool is_store,
1834 bool call_data_undefined, bool is_lazy)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001835 : PlatformCodeStub(isolate) {
Ben Murdochda12d292016-06-02 14:46:10 +01001836 CHECK(0 <= argc && argc <= kArgMax);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001837 minor_key_ = IsStoreBits::encode(is_store) |
1838 CallDataUndefinedBits::encode(call_data_undefined) |
Ben Murdochda12d292016-06-02 14:46:10 +01001839 ArgumentBits::encode(argc) |
Ben Murdoch097c5b22016-05-18 11:27:45 +01001840 IsLazyAccessorBits::encode(is_lazy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001841 }
1842
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001843 bool is_store() const { return IsStoreBits::decode(minor_key_); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001844 bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001845 bool call_data_undefined() const {
1846 return CallDataUndefinedBits::decode(minor_key_);
1847 }
1848 int argc() const { return ArgumentBits::decode(minor_key_); }
1849
1850 class IsStoreBits: public BitField<bool, 0, 1> {};
1851 class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001852 class ArgumentBits : public BitField<int, 2, kArgBits> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001853 class IsLazyAccessorBits : public BitField<bool, 3 + kArgBits, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001854
Ben Murdochda12d292016-06-02 14:46:10 +01001855 DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001856};
1857
1858
1859class CallApiGetterStub : public PlatformCodeStub {
1860 public:
1861 explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1862
1863 DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
1864 DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
1865};
1866
1867
1868class BinaryOpICStub : public HydrogenCodeStub {
1869 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001870 BinaryOpICStub(Isolate* isolate, Token::Value op)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001871 : HydrogenCodeStub(isolate, UNINITIALIZED) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001872 BinaryOpICState state(isolate, op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001873 set_sub_minor_key(state.GetExtraICState());
1874 }
1875
1876 BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
1877 : HydrogenCodeStub(isolate) {
1878 set_sub_minor_key(state.GetExtraICState());
1879 }
1880
1881 static void GenerateAheadOfTime(Isolate* isolate);
1882
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001883 Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001884
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001885 InlineCacheState GetICState() const final { return state().GetICState(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001886
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001887 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001888 return static_cast<ExtraICState>(sub_minor_key());
1889 }
1890
1891 BinaryOpICState state() const {
1892 return BinaryOpICState(isolate(), GetExtraICState());
1893 }
1894
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001895 void PrintState(std::ostream& os) const final; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001896
1897 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1898 static const int kLeft = 0;
1899 static const int kRight = 1;
1900
1901 private:
1902 static void GenerateAheadOfTime(Isolate* isolate,
1903 const BinaryOpICState& state);
1904
1905 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1906 DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
1907};
1908
1909
1910// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
1911// call support for stubs in Hydrogen.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001912class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001913 public:
1914 BinaryOpICWithAllocationSiteStub(Isolate* isolate,
1915 const BinaryOpICState& state)
1916 : PlatformCodeStub(isolate) {
1917 minor_key_ = state.GetExtraICState();
1918 }
1919
1920 static void GenerateAheadOfTime(Isolate* isolate);
1921
1922 Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
1923 Code::FindAndReplacePattern pattern;
1924 pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
1925 return CodeStub::GetCodeCopy(pattern);
1926 }
1927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001928 Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001929
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001930 InlineCacheState GetICState() const override { return state().GetICState(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001932 ExtraICState GetExtraICState() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001933 return static_cast<ExtraICState>(minor_key_);
1934 }
1935
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001936 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001937
1938 private:
1939 BinaryOpICState state() const {
1940 return BinaryOpICState(isolate(), static_cast<ExtraICState>(minor_key_));
1941 }
1942
1943 static void GenerateAheadOfTime(Isolate* isolate,
1944 const BinaryOpICState& state);
1945
1946 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1947 DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
1948};
1949
1950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001951class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001952 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001953 BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
1954 : BinaryOpICStub(isolate, op) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001955
1956 BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
1957 : BinaryOpICStub(isolate, state) {}
1958
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001959 Code::Kind GetCodeKind() const final { return Code::STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001960
1961 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1962 static const int kAllocationSite = 0;
1963 static const int kLeft = 1;
1964 static const int kRight = 2;
1965
1966 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1967 DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub);
1968};
1969
1970
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001971class StringAddStub final : public HydrogenCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001972 public:
1973 StringAddStub(Isolate* isolate, StringAddFlags flags,
1974 PretenureFlag pretenure_flag)
1975 : HydrogenCodeStub(isolate) {
1976 set_sub_minor_key(StringAddFlagsBits::encode(flags) |
1977 PretenureFlagBits::encode(pretenure_flag));
1978 }
1979
1980 StringAddFlags flags() const {
1981 return StringAddFlagsBits::decode(sub_minor_key());
1982 }
1983
1984 PretenureFlag pretenure_flag() const {
1985 return PretenureFlagBits::decode(sub_minor_key());
1986 }
1987
1988 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1989 static const int kLeft = 0;
1990 static const int kRight = 1;
1991
1992 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001993 class StringAddFlagsBits : public BitField<StringAddFlags, 0, 3> {};
1994 class PretenureFlagBits : public BitField<PretenureFlag, 3, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001995
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001996 void PrintBaseName(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001997
1998 DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
1999 DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub);
2000};
2001
2002
2003class CompareICStub : public PlatformCodeStub {
2004 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002005 CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
2006 CompareICState::State right, CompareICState::State state)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002007 : PlatformCodeStub(isolate) {
2008 DCHECK(Token::IsCompareOp(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002009 minor_key_ = OpBits::encode(op - Token::EQ) |
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002010 LeftStateBits::encode(left) | RightStateBits::encode(right) |
2011 StateBits::encode(state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002012 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002013
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002014 void set_known_map(Handle<Map> map) { known_map_ = map; }
2015
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002016 InlineCacheState GetICState() const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002017
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002018 Token::Value op() const {
2019 return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002020 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002021
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002022 CompareICState::State left() const {
2023 return LeftStateBits::decode(minor_key_);
2024 }
2025 CompareICState::State right() const {
2026 return RightStateBits::decode(minor_key_);
2027 }
2028 CompareICState::State state() const { return StateBits::decode(minor_key_); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002029
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002030 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002031 Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002032
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002033 void GenerateBooleans(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002034 void GenerateSmis(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002035 void GenerateNumbers(MacroAssembler* masm);
2036 void GenerateInternalizedStrings(MacroAssembler* masm);
Ben Murdoch257744e2011-11-30 15:57:28 +00002037 void GenerateStrings(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002038 void GenerateUniqueNames(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002039 void GenerateReceivers(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002040 void GenerateMiss(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002041 void GenerateKnownReceivers(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002042 void GenerateGeneric(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002043
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002044 bool strict() const { return op() == Token::EQ_STRICT; }
2045 Condition GetCondition() const;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002047 void AddToSpecialCache(Handle<Code> new_object) override;
2048 bool FindCodeInSpecialCache(Code** code_out) override;
2049 bool UseSpecialCache() override {
2050 return state() == CompareICState::KNOWN_RECEIVER;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002051 }
2052
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002053 class OpBits : public BitField<int, 0, 3> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01002054 class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
2055 class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
2056 class StateBits : public BitField<CompareICState::State, 11, 4> {};
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002057
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002058 Handle<Map> known_map_;
2059
2060 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
2061 DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002062};
2063
2064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002065class CEntryStub : public PlatformCodeStub {
2066 public:
2067 CEntryStub(Isolate* isolate, int result_size,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002068 SaveFPRegsMode save_doubles = kDontSaveFPRegs,
2069 ArgvMode argv_mode = kArgvOnStack)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002070 : PlatformCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002071 minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) |
2072 ArgvMode::encode(argv_mode == kArgvInRegister);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002073 DCHECK(result_size == 1 || result_size == 2 || result_size == 3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002074 minor_key_ = ResultSizeBits::update(minor_key_, result_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002075 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002076
2077 // The version of this stub that doesn't save doubles is generated ahead of
2078 // time, so it's OK to call it from other stubs that can't cope with GC during
2079 // their code generation. On machines that always have gp registers (x64) we
2080 // can generate both variants ahead of time.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002081 static void GenerateAheadOfTime(Isolate* isolate);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002082
2083 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002084 bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002085 bool argv_in_register() const { return ArgvMode::decode(minor_key_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002086 int result_size() const { return ResultSizeBits::decode(minor_key_); }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002088 bool NeedsImmovableCode() override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002089
2090 class SaveDoublesBits : public BitField<bool, 0, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002091 class ArgvMode : public BitField<bool, 1, 1> {};
2092 class ResultSizeBits : public BitField<int, 2, 3> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002093
2094 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2095 DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002096};
2097
2098
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002099class JSEntryStub : public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002100 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002101 JSEntryStub(Isolate* isolate, StackFrame::Type type)
2102 : PlatformCodeStub(isolate) {
2103 DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT);
2104 minor_key_ = StackFrameTypeBits::encode(type);
2105 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002106
2107 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002108 void FinishCode(Handle<Code> code) override;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002109
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002110 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002111 os << (type() == StackFrame::ENTRY ? "JSEntryStub"
2112 : "JSConstructEntryStub");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002113 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002114
2115 StackFrame::Type type() const {
2116 return StackFrameTypeBits::decode(minor_key_);
2117 }
2118
2119 class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {};
2120
2121 int handler_offset_;
2122
2123 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2124 DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002125};
2126
2127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002128class RegExpExecStub: public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002129 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002130 explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002132 DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
2133 DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002134};
2135
2136
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002137class RegExpConstructResultStub final : public HydrogenCodeStub {
Ben Murdochb0fe1622011-05-05 13:52:32 +01002138 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002139 explicit RegExpConstructResultStub(Isolate* isolate)
2140 : HydrogenCodeStub(isolate) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002141
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002142 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2143 static const int kLength = 0;
2144 static const int kIndex = 1;
2145 static const int kInput = 2;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002146
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002147 DEFINE_CALL_INTERFACE_DESCRIPTOR(RegExpConstructResult);
2148 DEFINE_HYDROGEN_CODE_STUB(RegExpConstructResult, HydrogenCodeStub);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002149};
2150
2151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002152// TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
2153class CallConstructStub final : public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002154 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002155 explicit CallConstructStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002156
2157 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
2158 DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002159};
2160
2161
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002162enum StringIndexFlags {
2163 // Accepts smis or heap numbers.
2164 STRING_INDEX_IS_NUMBER,
2165
2166 // Accepts smis or heap numbers that are valid array indices
2167 // (ECMA-262 15.4). Invalid indices are reported as being out of
2168 // range.
2169 STRING_INDEX_IS_ARRAY_INDEX
2170};
2171
2172
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002173enum ReceiverCheckMode {
2174 // We don't know anything about the receiver.
2175 RECEIVER_IS_UNKNOWN,
2176
2177 // We know the receiver is a string.
2178 RECEIVER_IS_STRING
2179};
2180
2181
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002182enum EmbedMode {
2183 // The code being generated is part of an IC handler, which may MISS
2184 // to an IC in failure cases.
2185 PART_OF_IC_HANDLER,
2186
2187 NOT_PART_OF_IC_HANDLER
2188};
2189
2190
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002191// Generates code implementing String.prototype.charCodeAt.
2192//
2193// Only supports the case when the receiver is a string and the index
2194// is a number (smi or heap number) that is a valid index into the
2195// string. Additional index constraints are specified by the
2196// flags. Otherwise, bails out to the provided labels.
2197//
2198// Register usage: |object| may be changed to another string in a way
2199// that doesn't affect charCodeAt/charAt semantics, |index| is
2200// preserved, |scratch| and |result| are clobbered.
2201class StringCharCodeAtGenerator {
2202 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002203 StringCharCodeAtGenerator(Register object, Register index, Register result,
2204 Label* receiver_not_string, Label* index_not_number,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002205 Label* index_out_of_range,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002206 StringIndexFlags index_flags,
2207 ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002208 : object_(object),
2209 index_(index),
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002210 result_(result),
2211 receiver_not_string_(receiver_not_string),
2212 index_not_number_(index_not_number),
2213 index_out_of_range_(index_out_of_range),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002214 index_flags_(index_flags),
2215 check_mode_(check_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002216 DCHECK(!result_.is(object_));
2217 DCHECK(!result_.is(index_));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002218 }
2219
2220 // Generates the fast case code. On the fallthrough path |result|
2221 // register contains the result.
2222 void GenerateFast(MacroAssembler* masm);
2223
2224 // Generates the slow case code. Must not be naturally
2225 // reachable. Expected to be put after a ret instruction (e.g., in
2226 // deferred code). Always jumps back to the fast case.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002227 void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002228 const RuntimeCallHelper& call_helper);
2229
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002230 // Skip handling slow case and directly jump to bailout.
2231 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2232 masm->bind(&index_not_smi_);
2233 masm->bind(&call_runtime_);
2234 masm->jmp(bailout);
2235 }
2236
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002237 private:
2238 Register object_;
2239 Register index_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002240 Register result_;
2241
2242 Label* receiver_not_string_;
2243 Label* index_not_number_;
2244 Label* index_out_of_range_;
2245
2246 StringIndexFlags index_flags_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002247 ReceiverCheckMode check_mode_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002248
2249 Label call_runtime_;
2250 Label index_not_smi_;
2251 Label got_smi_index_;
2252 Label exit_;
2253
2254 DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
2255};
2256
2257
2258// Generates code for creating a one-char string from a char code.
2259class StringCharFromCodeGenerator {
2260 public:
2261 StringCharFromCodeGenerator(Register code,
2262 Register result)
2263 : code_(code),
2264 result_(result) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002265 DCHECK(!code_.is(result_));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002266 }
2267
2268 // Generates the fast case code. On the fallthrough path |result|
2269 // register contains the result.
2270 void GenerateFast(MacroAssembler* masm);
2271
2272 // Generates the slow case code. Must not be naturally
2273 // reachable. Expected to be put after a ret instruction (e.g., in
2274 // deferred code). Always jumps back to the fast case.
2275 void GenerateSlow(MacroAssembler* masm,
2276 const RuntimeCallHelper& call_helper);
2277
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002278 // Skip handling slow case and directly jump to bailout.
2279 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2280 masm->bind(&slow_case_);
2281 masm->jmp(bailout);
2282 }
2283
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002284 private:
2285 Register code_;
2286 Register result_;
2287
2288 Label slow_case_;
2289 Label exit_;
2290
2291 DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator);
2292};
2293
2294
2295// Generates code implementing String.prototype.charAt.
2296//
2297// Only supports the case when the receiver is a string and the index
2298// is a number (smi or heap number) that is a valid index into the
2299// string. Additional index constraints are specified by the
2300// flags. Otherwise, bails out to the provided labels.
2301//
2302// Register usage: |object| may be changed to another string in a way
2303// that doesn't affect charCodeAt/charAt semantics, |index| is
2304// preserved, |scratch1|, |scratch2|, and |result| are clobbered.
2305class StringCharAtGenerator {
2306 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002307 StringCharAtGenerator(Register object, Register index, Register scratch,
2308 Register result, Label* receiver_not_string,
2309 Label* index_not_number, Label* index_out_of_range,
2310 StringIndexFlags index_flags,
2311 ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
2312 : char_code_at_generator_(object, index, scratch, receiver_not_string,
2313 index_not_number, index_out_of_range,
2314 index_flags, check_mode),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002315 char_from_code_generator_(scratch, result) {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002316
2317 // Generates the fast case code. On the fallthrough path |result|
2318 // register contains the result.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002319 void GenerateFast(MacroAssembler* masm) {
2320 char_code_at_generator_.GenerateFast(masm);
2321 char_from_code_generator_.GenerateFast(masm);
2322 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002323
2324 // Generates the slow case code. Must not be naturally
2325 // reachable. Expected to be put after a ret instruction (e.g., in
2326 // deferred code). Always jumps back to the fast case.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002327 void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002328 const RuntimeCallHelper& call_helper) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002329 char_code_at_generator_.GenerateSlow(masm, embed_mode, call_helper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002330 char_from_code_generator_.GenerateSlow(masm, call_helper);
2331 }
2332
2333 // Skip handling slow case and directly jump to bailout.
2334 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2335 char_code_at_generator_.SkipSlow(masm, bailout);
2336 char_from_code_generator_.SkipSlow(masm, bailout);
2337 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002338
2339 private:
2340 StringCharCodeAtGenerator char_code_at_generator_;
2341 StringCharFromCodeGenerator char_from_code_generator_;
2342
2343 DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator);
2344};
2345
Ben Murdoch086aeea2011-05-13 15:57:08 +01002346
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002347class LoadDictionaryElementStub : public HydrogenCodeStub {
Ben Murdoch086aeea2011-05-13 15:57:08 +01002348 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002349 explicit LoadDictionaryElementStub(Isolate* isolate, const LoadICState& state)
2350 : HydrogenCodeStub(isolate) {
2351 minor_key_ = state.GetExtraICState();
2352 }
Ben Murdoch086aeea2011-05-13 15:57:08 +01002353
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002354 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
2355 return LoadWithVectorDescriptor(isolate());
2356 }
2357
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002358 DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
Ben Murdoch086aeea2011-05-13 15:57:08 +01002359};
2360
Ben Murdoch257744e2011-11-30 15:57:28 +00002361
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002362class KeyedLoadGenericStub : public HydrogenCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00002363 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002364 explicit KeyedLoadGenericStub(Isolate* isolate, const LoadICState& state)
2365 : HydrogenCodeStub(isolate) {
2366 minor_key_ = state.GetExtraICState();
2367 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002368
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002369 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2370 InlineCacheState GetICState() const override { return GENERIC; }
Ben Murdoch257744e2011-11-30 15:57:28 +00002371
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002372 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002373
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002374 DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
Ben Murdoch257744e2011-11-30 15:57:28 +00002375};
2376
2377
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002378class LoadICTrampolineStub : public PlatformCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00002379 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002380 LoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
2381 : PlatformCodeStub(isolate) {
2382 minor_key_ = state.GetExtraICState();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002383 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002384
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002385 Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002386
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002387 InlineCacheState GetICState() const final { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002388
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002389 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002390 return static_cast<ExtraICState>(minor_key_);
2391 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002392
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002393 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002394 LoadICState state() const {
2395 return LoadICState(static_cast<ExtraICState>(minor_key_));
2396 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002397
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002398 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002399 DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub);
Ben Murdoch257744e2011-11-30 15:57:28 +00002400};
2401
2402
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002403class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
2404 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002405 explicit KeyedLoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
2406 : LoadICTrampolineStub(isolate, state) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002407
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002408 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002409
2410 DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub);
2411};
2412
2413
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002414class VectorStoreICTrampolineStub : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002415 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002416 VectorStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2417 : PlatformCodeStub(isolate) {
2418 minor_key_ = state.GetExtraICState();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002419 }
2420
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002421 Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002423 InlineCacheState GetICState() const final { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002424
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002425 ExtraICState GetExtraICState() const final {
2426 return static_cast<ExtraICState>(minor_key_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002427 }
2428
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002429 protected:
2430 StoreICState state() const {
2431 return StoreICState(static_cast<ExtraICState>(minor_key_));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002432 }
2433
2434 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002435 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreICTrampoline);
2436 DEFINE_PLATFORM_CODE_STUB(VectorStoreICTrampoline, PlatformCodeStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002437};
2438
2439
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002440class VectorKeyedStoreICTrampolineStub : public VectorStoreICTrampolineStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002441 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002442 VectorKeyedStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2443 : VectorStoreICTrampolineStub(isolate, state) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002444
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002445 Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002446
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002447 DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreICTrampoline,
2448 VectorStoreICTrampolineStub);
2449};
2450
2451
2452class CallICTrampolineStub : public PlatformCodeStub {
2453 public:
2454 CallICTrampolineStub(Isolate* isolate, const CallICState& state)
2455 : PlatformCodeStub(isolate) {
2456 minor_key_ = state.GetExtraICState();
2457 }
2458
2459 Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
2460
2461 InlineCacheState GetICState() const final { return GENERIC; }
2462
2463 ExtraICState GetExtraICState() const final {
2464 return static_cast<ExtraICState>(minor_key_);
2465 }
2466
2467 protected:
2468 CallICState state() const {
2469 return CallICState(static_cast<ExtraICState>(minor_key_));
2470 }
2471
2472 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
2473 DEFINE_PLATFORM_CODE_STUB(CallICTrampoline, PlatformCodeStub);
2474};
2475
2476
2477class LoadICStub : public PlatformCodeStub {
2478 public:
2479 explicit LoadICStub(Isolate* isolate, const LoadICState& state)
2480 : PlatformCodeStub(isolate) {
2481 minor_key_ = state.GetExtraICState();
2482 }
2483
2484 void GenerateForTrampoline(MacroAssembler* masm);
2485
2486 Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
2487 InlineCacheState GetICState() const final { return GENERIC; }
2488 ExtraICState GetExtraICState() const final {
2489 return static_cast<ExtraICState>(minor_key_);
2490 }
2491
2492 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2493 DEFINE_PLATFORM_CODE_STUB(LoadIC, PlatformCodeStub);
2494
2495 protected:
2496 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2497};
2498
2499
2500class KeyedLoadICStub : public PlatformCodeStub {
2501 public:
2502 explicit KeyedLoadICStub(Isolate* isolate, const LoadICState& state)
2503 : PlatformCodeStub(isolate) {
2504 minor_key_ = state.GetExtraICState();
2505 }
2506
2507 void GenerateForTrampoline(MacroAssembler* masm);
2508
2509 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2510 InlineCacheState GetICState() const final { return GENERIC; }
2511 ExtraICState GetExtraICState() const final {
2512 return static_cast<ExtraICState>(minor_key_);
2513 }
2514
2515 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2516 DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
2517
2518 protected:
2519 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2520};
2521
2522
2523class VectorStoreICStub : public PlatformCodeStub {
2524 public:
2525 VectorStoreICStub(Isolate* isolate, const StoreICState& state)
2526 : PlatformCodeStub(isolate) {
2527 minor_key_ = state.GetExtraICState();
2528 }
2529
2530 void GenerateForTrampoline(MacroAssembler* masm);
2531
2532 Code::Kind GetCodeKind() const final { return Code::STORE_IC; }
2533 InlineCacheState GetICState() const final { return GENERIC; }
2534 ExtraICState GetExtraICState() const final {
2535 return static_cast<ExtraICState>(minor_key_);
2536 }
2537
2538 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2539 DEFINE_PLATFORM_CODE_STUB(VectorStoreIC, PlatformCodeStub);
2540
2541 protected:
2542 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2543};
2544
2545
2546class VectorKeyedStoreICStub : public PlatformCodeStub {
2547 public:
2548 VectorKeyedStoreICStub(Isolate* isolate, const StoreICState& state)
2549 : PlatformCodeStub(isolate) {
2550 minor_key_ = state.GetExtraICState();
2551 }
2552
2553 void GenerateForTrampoline(MacroAssembler* masm);
2554
2555 Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
2556 InlineCacheState GetICState() const final { return GENERIC; }
2557 ExtraICState GetExtraICState() const final {
2558 return static_cast<ExtraICState>(minor_key_);
2559 }
2560
2561 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2562 DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);
2563
2564 protected:
2565 void GenerateImpl(MacroAssembler* masm, bool in_frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002566};
2567
2568
2569class DoubleToIStub : public PlatformCodeStub {
2570 public:
2571 DoubleToIStub(Isolate* isolate, Register source, Register destination,
2572 int offset, bool is_truncating, bool skip_fastpath = false)
2573 : PlatformCodeStub(isolate) {
2574 minor_key_ = SourceRegisterBits::encode(source.code()) |
2575 DestinationRegisterBits::encode(destination.code()) |
2576 OffsetBits::encode(offset) |
2577 IsTruncatingBits::encode(is_truncating) |
2578 SkipFastPathBits::encode(skip_fastpath) |
2579 SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
2580 }
2581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002582 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002583
2584 private:
2585 Register source() const {
2586 return Register::from_code(SourceRegisterBits::decode(minor_key_));
2587 }
2588 Register destination() const {
2589 return Register::from_code(DestinationRegisterBits::decode(minor_key_));
2590 }
2591 bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); }
2592 bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); }
2593 int offset() const { return OffsetBits::decode(minor_key_); }
2594
2595 static const int kBitsPerRegisterNumber = 6;
2596 STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
2597 class SourceRegisterBits:
2598 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT
2599 class DestinationRegisterBits:
2600 public BitField<int, kBitsPerRegisterNumber,
2601 kBitsPerRegisterNumber> {}; // NOLINT
2602 class IsTruncatingBits:
2603 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT
2604 class OffsetBits:
2605 public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT
2606 class SkipFastPathBits:
2607 public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT
2608 class SSE3Bits:
2609 public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {}; // NOLINT
2610
2611 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2612 DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
2613};
2614
2615
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002616class ScriptContextFieldStub : public HandlerStub {
2617 public:
2618 ScriptContextFieldStub(Isolate* isolate,
2619 const ScriptContextTable::LookupResult* lookup_result)
2620 : HandlerStub(isolate) {
2621 DCHECK(Accepted(lookup_result));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002622 STATIC_ASSERT(kContextIndexBits + kSlotIndexBits <= kSubMinorKeyBits);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002623 set_sub_minor_key(ContextIndexBits::encode(lookup_result->context_index) |
2624 SlotIndexBits::encode(lookup_result->slot_index));
2625 }
2626
2627 int context_index() const {
2628 return ContextIndexBits::decode(sub_minor_key());
2629 }
2630
2631 int slot_index() const { return SlotIndexBits::decode(sub_minor_key()); }
2632
2633 static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
2634 return ContextIndexBits::is_valid(lookup_result->context_index) &&
2635 SlotIndexBits::is_valid(lookup_result->slot_index);
2636 }
2637
2638 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002639 static const int kContextIndexBits = 9;
Ben Murdochc5610432016-08-08 18:44:38 +01002640 static const int kSlotIndexBits = 12;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002641 class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
2642 class SlotIndexBits
2643 : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
2644
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002645 DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, HandlerStub);
2646};
2647
2648
2649class LoadScriptContextFieldStub : public ScriptContextFieldStub {
2650 public:
2651 LoadScriptContextFieldStub(
2652 Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2653 : ScriptContextFieldStub(isolate, lookup_result) {}
2654
2655 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002656 Code::Kind kind() const override { return Code::LOAD_IC; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002657
2658 DEFINE_HANDLER_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
2659};
2660
2661
2662class StoreScriptContextFieldStub : public ScriptContextFieldStub {
2663 public:
2664 StoreScriptContextFieldStub(
2665 Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2666 : ScriptContextFieldStub(isolate, lookup_result) {}
2667
2668 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002669 Code::Kind kind() const override { return Code::STORE_IC; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002670
2671 DEFINE_HANDLER_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
2672};
2673
2674
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002675class LoadFastElementStub : public HandlerStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002676 public:
2677 LoadFastElementStub(Isolate* isolate, bool is_js_array,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002678 ElementsKind elements_kind,
2679 bool convert_hole_to_undefined = false)
2680 : HandlerStub(isolate) {
2681 set_sub_minor_key(
2682 ElementsKindBits::encode(elements_kind) |
2683 IsJSArrayBits::encode(is_js_array) |
2684 CanConvertHoleToUndefined::encode(convert_hole_to_undefined));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002685 }
2686
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002687 Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
2688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002689 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002690 bool convert_hole_to_undefined() const {
2691 return CanConvertHoleToUndefined::decode(sub_minor_key());
2692 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002693
2694 ElementsKind elements_kind() const {
2695 return ElementsKindBits::decode(sub_minor_key());
2696 }
2697
2698 private:
2699 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2700 class IsJSArrayBits: public BitField<bool, 8, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002701 class CanConvertHoleToUndefined : public BitField<bool, 9, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002702
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002703 DEFINE_HANDLER_CODE_STUB(LoadFastElement, HandlerStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002704};
2705
2706
2707class StoreFastElementStub : public HydrogenCodeStub {
2708 public:
2709 StoreFastElementStub(Isolate* isolate, bool is_js_array,
2710 ElementsKind elements_kind, KeyedAccessStoreMode mode)
2711 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002712 set_sub_minor_key(CommonStoreModeBits::encode(mode) |
2713 ElementsKindBits::encode(elements_kind) |
2714 IsJSArrayBits::encode(is_js_array));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002715 }
2716
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002717 static void GenerateAheadOfTime(Isolate* isolate);
2718
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002719 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2720
2721 ElementsKind elements_kind() const {
2722 return ElementsKindBits::decode(sub_minor_key());
2723 }
2724
2725 KeyedAccessStoreMode store_mode() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002726 return CommonStoreModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002727 }
2728
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002729 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
2730 return VectorStoreICDescriptor(isolate());
2731 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
2734
2735 private:
2736 class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
2737 class IsJSArrayBits : public BitField<bool, 11, 1> {};
2738
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002739 DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub);
2740};
2741
2742
2743class TransitionElementsKindStub : public HydrogenCodeStub {
2744 public:
2745 TransitionElementsKindStub(Isolate* isolate,
2746 ElementsKind from_kind,
2747 ElementsKind to_kind,
2748 bool is_js_array) : HydrogenCodeStub(isolate) {
2749 set_sub_minor_key(FromKindBits::encode(from_kind) |
2750 ToKindBits::encode(to_kind) |
2751 IsJSArrayBits::encode(is_js_array));
2752 }
2753
2754 ElementsKind from_kind() const {
2755 return FromKindBits::decode(sub_minor_key());
2756 }
2757
2758 ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); }
2759
2760 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2761
2762 private:
2763 class FromKindBits: public BitField<ElementsKind, 8, 8> {};
2764 class ToKindBits: public BitField<ElementsKind, 0, 8> {};
2765 class IsJSArrayBits: public BitField<bool, 16, 1> {};
2766
2767 DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind);
2768 DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub);
2769};
2770
Ben Murdochda12d292016-06-02 14:46:10 +01002771class AllocateHeapNumberStub : public TurboFanCodeStub {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002772 public:
2773 explicit AllocateHeapNumberStub(Isolate* isolate)
Ben Murdochda12d292016-06-02 14:46:10 +01002774 : TurboFanCodeStub(isolate) {}
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002775
Ben Murdochda12d292016-06-02 14:46:10 +01002776 void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
Ben Murdochc5610432016-08-08 18:44:38 +01002777 void GenerateAssembly(CodeStubAssembler* assembler) const override;
Ben Murdochda12d292016-06-02 14:46:10 +01002778
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002779 DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
Ben Murdochda12d292016-06-02 14:46:10 +01002780 DEFINE_CODE_STUB(AllocateHeapNumber, TurboFanCodeStub);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002781};
2782
Ben Murdochda12d292016-06-02 14:46:10 +01002783#define SIMD128_ALLOC_STUB(TYPE, Type, type, lane_count, lane_type) \
2784 class Allocate##Type##Stub : public TurboFanCodeStub { \
2785 public: \
2786 explicit Allocate##Type##Stub(Isolate* isolate) \
2787 : TurboFanCodeStub(isolate) {} \
2788 \
2789 void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
Ben Murdochc5610432016-08-08 18:44:38 +01002790 void GenerateAssembly(CodeStubAssembler* assembler) const override; \
Ben Murdochda12d292016-06-02 14:46:10 +01002791 \
2792 DEFINE_CALL_INTERFACE_DESCRIPTOR(Allocate##Type); \
2793 DEFINE_CODE_STUB(Allocate##Type, TurboFanCodeStub); \
2794 };
2795SIMD128_TYPES(SIMD128_ALLOC_STUB)
2796#undef SIMD128_ALLOC_STUB
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002797
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002798class ArrayConstructorStubBase : public HydrogenCodeStub {
2799 public:
2800 ArrayConstructorStubBase(Isolate* isolate,
2801 ElementsKind kind,
2802 AllocationSiteOverrideMode override_mode)
2803 : HydrogenCodeStub(isolate) {
2804 // It only makes sense to override local allocation site behavior
2805 // if there is a difference between the global allocation site policy
2806 // for an ElementsKind and the desired usage of the stub.
2807 DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
2808 AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
2809 set_sub_minor_key(ElementsKindBits::encode(kind) |
2810 AllocationSiteOverrideModeBits::encode(override_mode));
2811 }
2812
2813 ElementsKind elements_kind() const {
2814 return ElementsKindBits::decode(sub_minor_key());
2815 }
2816
2817 AllocationSiteOverrideMode override_mode() const {
2818 return AllocationSiteOverrideModeBits::decode(sub_minor_key());
2819 }
2820
2821 static void GenerateStubsAheadOfTime(Isolate* isolate);
2822
2823 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2824 static const int kConstructor = 0;
2825 static const int kAllocationSite = 1;
2826
2827 protected:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002828 std::ostream& BasePrintName(std::ostream& os,
2829 const char* name) const; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002830
2831 private:
2832 // Ensure data fits within available bits.
2833 STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
2834
2835 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2836 class AllocationSiteOverrideModeBits: public
2837 BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
2838
2839 DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub);
2840};
2841
Ben Murdochc5610432016-08-08 18:44:38 +01002842class CommonArrayConstructorStub : public TurboFanCodeStub {
2843 protected:
2844 CommonArrayConstructorStub(Isolate* isolate, ElementsKind kind,
2845 AllocationSiteOverrideMode override_mode)
2846 : TurboFanCodeStub(isolate) {
2847 // It only makes sense to override local allocation site behavior
2848 // if there is a difference between the global allocation site policy
2849 // for an ElementsKind and the desired usage of the stub.
2850 DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
2851 AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
2852 set_sub_minor_key(ElementsKindBits::encode(kind) |
2853 AllocationSiteOverrideModeBits::encode(override_mode));
2854 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002855
Ben Murdochc5610432016-08-08 18:44:38 +01002856 void set_sub_minor_key(uint32_t key) { minor_key_ = key; }
2857
2858 uint32_t sub_minor_key() const { return minor_key_; }
2859
2860 CommonArrayConstructorStub(uint32_t key, Isolate* isolate)
2861 : TurboFanCodeStub(key, isolate) {}
2862
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002863 public:
Ben Murdochc5610432016-08-08 18:44:38 +01002864 ElementsKind elements_kind() const {
2865 return ElementsKindBits::decode(sub_minor_key());
2866 }
2867
2868 AllocationSiteOverrideMode override_mode() const {
2869 return AllocationSiteOverrideModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002870 }
2871
2872 private:
Ben Murdochc5610432016-08-08 18:44:38 +01002873 // Ensure data fits within available bits.
2874 STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002875
Ben Murdochc5610432016-08-08 18:44:38 +01002876 class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
2877 class AllocationSiteOverrideModeBits
2878 : public BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002879};
2880
Ben Murdochc5610432016-08-08 18:44:38 +01002881class ArrayNoArgumentConstructorStub : public CommonArrayConstructorStub {
2882 public:
2883 ArrayNoArgumentConstructorStub(
2884 Isolate* isolate, ElementsKind kind,
2885 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2886 : CommonArrayConstructorStub(isolate, kind, override_mode) {}
2887
2888 private:
2889 void PrintName(std::ostream& os) const override { // NOLINT
2890 os << "ArrayNoArgumentConstructorStub";
2891 }
2892
2893 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
2894 DEFINE_TURBOFAN_CODE_STUB(ArrayNoArgumentConstructor,
2895 CommonArrayConstructorStub);
2896};
2897
2898class InternalArrayNoArgumentConstructorStub
2899 : public CommonArrayConstructorStub {
2900 public:
2901 InternalArrayNoArgumentConstructorStub(Isolate* isolate, ElementsKind kind)
2902 : CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
2903
2904 private:
2905 void PrintName(std::ostream& os) const override { // NOLINT
2906 os << "InternalArrayNoArgumentConstructorStub";
2907 }
2908
2909 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
2910 DEFINE_TURBOFAN_CODE_STUB(InternalArrayNoArgumentConstructor,
2911 CommonArrayConstructorStub);
2912};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002913
2914class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
2915 public:
2916 ArraySingleArgumentConstructorStub(
2917 Isolate* isolate,
2918 ElementsKind kind,
2919 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2920 : ArrayConstructorStubBase(isolate, kind, override_mode) {
2921 }
2922
2923 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002924 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002925 BasePrintName(os, "ArraySingleArgumentConstructorStub");
2926 }
2927
2928 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2929 DEFINE_HYDROGEN_CODE_STUB(ArraySingleArgumentConstructor,
2930 ArrayConstructorStubBase);
2931};
2932
2933
2934class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
2935 public:
2936 ArrayNArgumentsConstructorStub(
2937 Isolate* isolate,
2938 ElementsKind kind,
2939 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2940 : ArrayConstructorStubBase(isolate, kind, override_mode) {
2941 }
2942
2943 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002944 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002945 BasePrintName(os, "ArrayNArgumentsConstructorStub");
2946 }
2947
2948 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2949 DEFINE_HYDROGEN_CODE_STUB(ArrayNArgumentsConstructor,
2950 ArrayConstructorStubBase);
2951};
2952
2953
2954class InternalArrayConstructorStubBase : public HydrogenCodeStub {
2955 public:
2956 InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind)
2957 : HydrogenCodeStub(isolate) {
2958 set_sub_minor_key(ElementsKindBits::encode(kind));
2959 }
2960
2961 static void GenerateStubsAheadOfTime(Isolate* isolate);
2962
2963 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2964 static const int kConstructor = 0;
2965
2966 ElementsKind elements_kind() const {
2967 return ElementsKindBits::decode(sub_minor_key());
2968 }
2969
2970 private:
2971 class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
2972
2973 DEFINE_CODE_STUB_BASE(InternalArrayConstructorStubBase, HydrogenCodeStub);
2974};
2975
2976
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002977class InternalArraySingleArgumentConstructorStub : public
2978 InternalArrayConstructorStubBase {
2979 public:
2980 InternalArraySingleArgumentConstructorStub(Isolate* isolate,
2981 ElementsKind kind)
2982 : InternalArrayConstructorStubBase(isolate, kind) { }
2983
2984 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2985 DEFINE_HYDROGEN_CODE_STUB(InternalArraySingleArgumentConstructor,
2986 InternalArrayConstructorStubBase);
2987};
2988
2989
2990class InternalArrayNArgumentsConstructorStub : public
2991 InternalArrayConstructorStubBase {
2992 public:
2993 InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind)
2994 : InternalArrayConstructorStubBase(isolate, kind) { }
2995
2996 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2997 DEFINE_HYDROGEN_CODE_STUB(InternalArrayNArgumentsConstructor,
2998 InternalArrayConstructorStubBase);
2999};
3000
3001
3002class StoreElementStub : public PlatformCodeStub {
3003 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003004 StoreElementStub(Isolate* isolate, ElementsKind elements_kind,
3005 KeyedAccessStoreMode mode)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003006 : PlatformCodeStub(isolate) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003007 // TODO(jkummerow): Rename this stub to StoreSlowElementStub,
3008 // drop elements_kind parameter.
3009 DCHECK_EQ(DICTIONARY_ELEMENTS, elements_kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003010 minor_key_ = ElementsKindBits::encode(elements_kind) |
3011 CommonStoreModeBits::encode(mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003012 }
3013
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003014 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
3015 return VectorStoreICDescriptor(isolate());
3016 }
3017
3018 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
3019
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003020 private:
3021 ElementsKind elements_kind() const {
3022 return ElementsKindBits::decode(minor_key_);
3023 }
3024
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003025 class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003026
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003027 DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
3028};
3029
Ben Murdochda12d292016-06-02 14:46:10 +01003030class ToBooleanICStub : public HydrogenCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00003031 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003032 enum Type {
3033 UNDEFINED,
3034 BOOLEAN,
3035 NULL_TYPE,
3036 SMI,
3037 SPEC_OBJECT,
3038 STRING,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003039 SYMBOL,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003040 HEAP_NUMBER,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003041 SIMD_VALUE,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003042 NUMBER_OF_TYPES
3043 };
3044
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003045 // At most 16 different types can be distinguished, because the Code object
3046 // only has room for two bytes to hold a set of these types. :-P
3047 STATIC_ASSERT(NUMBER_OF_TYPES <= 16);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003048
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003049 class Types : public EnumSet<Type, uint16_t> {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003050 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003051 Types() : EnumSet<Type, uint16_t>(0) {}
3052 explicit Types(uint16_t bits) : EnumSet<Type, uint16_t>(bits) {}
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003053
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003054 bool UpdateStatus(Handle<Object> object);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003055 bool NeedsMap() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003056 bool CanBeUndetectable() const {
Ben Murdochda12d292016-06-02 14:46:10 +01003057 return Contains(ToBooleanICStub::SPEC_OBJECT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003058 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003059 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003060
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003061 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003062 };
3063
Ben Murdochda12d292016-06-02 14:46:10 +01003064 ToBooleanICStub(Isolate* isolate, ExtraICState state)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003065 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003066 set_sub_minor_key(TypesBits::encode(static_cast<uint16_t>(state)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003067 }
Ben Murdoch257744e2011-11-30 15:57:28 +00003068
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003069 bool UpdateStatus(Handle<Object> object);
3070 Types types() const { return Types(TypesBits::decode(sub_minor_key())); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003072 Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
3073 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdoch257744e2011-11-30 15:57:28 +00003074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003075 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003076
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003077 static Handle<Code> GetUninitialized(Isolate* isolate) {
Ben Murdochda12d292016-06-02 14:46:10 +01003078 return ToBooleanICStub(isolate, UNINITIALIZED).GetCode();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003079 }
3080
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003081 ExtraICState GetExtraICState() const override { return types().ToIntegral(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00003082
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003083 InlineCacheState GetICState() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003084 if (types().IsEmpty()) {
3085 return ::v8::internal::UNINITIALIZED;
3086 } else {
3087 return MONOMORPHIC;
3088 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003089 }
3090
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003091 private:
Ben Murdochda12d292016-06-02 14:46:10 +01003092 ToBooleanICStub(Isolate* isolate, InitializationState init_state)
3093 : HydrogenCodeStub(isolate, init_state) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003094
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003095 class TypesBits : public BitField<uint16_t, 0, NUMBER_OF_TYPES> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003096
Ben Murdochda12d292016-06-02 14:46:10 +01003097 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
3098 DEFINE_HYDROGEN_CODE_STUB(ToBooleanIC, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003099};
3100
Ben Murdochda12d292016-06-02 14:46:10 +01003101std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102
3103class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003104 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003105 ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
3106 ElementsKind to_kind, bool is_jsarray,
3107 KeyedAccessStoreMode store_mode)
3108 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003109 set_sub_minor_key(CommonStoreModeBits::encode(store_mode) |
3110 FromBits::encode(from_kind) | ToBits::encode(to_kind) |
3111 IsJSArrayBits::encode(is_jsarray));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003112 }
3113
3114 ElementsKind from_kind() const { return FromBits::decode(sub_minor_key()); }
3115 ElementsKind to_kind() const { return ToBits::decode(sub_minor_key()); }
3116 bool is_jsarray() const { return IsJSArrayBits::decode(sub_minor_key()); }
3117 KeyedAccessStoreMode store_mode() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003118 return CommonStoreModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003119 }
3120
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003121 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
3122 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003123
3124 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003125 class FromBits : public BitField<ElementsKind, 3, 8> {};
3126 class ToBits : public BitField<ElementsKind, 11, 8> {};
3127 class IsJSArrayBits : public BitField<bool, 19, 1> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003128
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003129 DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003130};
3131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003133class StubFailureTrampolineStub : public PlatformCodeStub {
3134 public:
3135 StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
3136 : PlatformCodeStub(isolate) {
3137 minor_key_ = FunctionModeField::encode(function_mode);
3138 }
3139
3140 static void GenerateAheadOfTime(Isolate* isolate);
3141
3142 private:
3143 StubFunctionMode function_mode() const {
3144 return FunctionModeField::decode(minor_key_);
3145 }
3146
3147 class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
3148
3149 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
3150 DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub);
3151};
3152
3153
3154class ProfileEntryHookStub : public PlatformCodeStub {
3155 public:
3156 explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3157
3158 // The profile entry hook function is not allowed to cause a GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003159 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003160
3161 // Generates a call to the entry hook if it's enabled.
3162 static void MaybeCallEntryHook(MacroAssembler* masm);
3163
3164 private:
3165 static void EntryHookTrampoline(intptr_t function,
3166 intptr_t stack_pointer,
3167 Isolate* isolate);
3168
3169 // ProfileEntryHookStub is called at the start of a function, so it has the
3170 // same register set.
3171 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction)
3172 DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub);
3173};
3174
3175
3176class StoreBufferOverflowStub : public PlatformCodeStub {
3177 public:
3178 StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
3179 : PlatformCodeStub(isolate) {
3180 minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs);
3181 }
3182
3183 static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003184 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003185
3186 private:
3187 bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
3188
3189 class SaveDoublesBits : public BitField<bool, 0, 1> {};
3190
3191 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
3192 DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
3193};
3194
3195
3196class SubStringStub : public PlatformCodeStub {
3197 public:
3198 explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3199
3200 DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
3201 DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub);
3202};
3203
3204
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003205class ToNumberStub final : public PlatformCodeStub {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003206 public:
3207 explicit ToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3208
Ben Murdochda12d292016-06-02 14:46:10 +01003209 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003210 DEFINE_PLATFORM_CODE_STUB(ToNumber, PlatformCodeStub);
3211};
3212
Ben Murdochda12d292016-06-02 14:46:10 +01003213class NonNumberToNumberStub final : public PlatformCodeStub {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003214 public:
Ben Murdochda12d292016-06-02 14:46:10 +01003215 explicit NonNumberToNumberStub(Isolate* isolate)
3216 : PlatformCodeStub(isolate) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003217
Ben Murdochda12d292016-06-02 14:46:10 +01003218 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
3219 DEFINE_PLATFORM_CODE_STUB(NonNumberToNumber, PlatformCodeStub);
3220};
3221
3222class StringToNumberStub final : public PlatformCodeStub {
3223 public:
3224 explicit StringToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3225
3226 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
3227 DEFINE_PLATFORM_CODE_STUB(StringToNumber, PlatformCodeStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003228};
3229
3230
3231class ToStringStub final : public PlatformCodeStub {
3232 public:
3233 explicit ToStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3234
Ben Murdochda12d292016-06-02 14:46:10 +01003235 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003236 DEFINE_PLATFORM_CODE_STUB(ToString, PlatformCodeStub);
3237};
3238
3239
Ben Murdoch097c5b22016-05-18 11:27:45 +01003240class ToNameStub final : public PlatformCodeStub {
3241 public:
3242 explicit ToNameStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3243
Ben Murdochda12d292016-06-02 14:46:10 +01003244 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003245 DEFINE_PLATFORM_CODE_STUB(ToName, PlatformCodeStub);
3246};
3247
3248
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003249class ToObjectStub final : public HydrogenCodeStub {
3250 public:
3251 explicit ToObjectStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
3252
Ben Murdochda12d292016-06-02 14:46:10 +01003253 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003254 DEFINE_HYDROGEN_CODE_STUB(ToObject, HydrogenCodeStub);
3255};
3256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003257#undef DEFINE_CALL_INTERFACE_DESCRIPTOR
3258#undef DEFINE_PLATFORM_CODE_STUB
3259#undef DEFINE_HANDLER_CODE_STUB
3260#undef DEFINE_HYDROGEN_CODE_STUB
3261#undef DEFINE_CODE_STUB
3262#undef DEFINE_CODE_STUB_BASE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003263
3264extern Representation RepresentationFromType(Type* type);
3265
3266} // namespace internal
3267} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00003268
3269#endif // V8_CODE_STUBS_H_