blob: ace4aae6142341012de8eb887ae2c3b1afc8b26c [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"
10#include "src/codegen.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/compiler/code-stub-assembler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#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 Murdoch4a90d5f2016-03-22 12:00:34 +000034 V(InstanceOf) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 V(InternalArrayConstructor) \
36 V(JSEntry) \
37 V(KeyedLoadICTrampoline) \
38 V(LoadICTrampoline) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 V(CallICTrampoline) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040040 V(LoadIndexedString) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 V(MathPow) \
42 V(ProfileEntryHook) \
43 V(RecordWrite) \
44 V(RegExpExec) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 V(StoreBufferOverflow) \
46 V(StoreElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047 V(StubFailureTrampoline) \
48 V(SubString) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 V(ToNumber) \
Ben Murdochda12d292016-06-02 14:46:10 +010050 V(NonNumberToNumber) \
51 V(StringToNumber) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 V(ToString) \
Ben Murdoch097c5b22016-05-18 11:27:45 +010053 V(ToName) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 V(ToObject) \
55 V(VectorStoreICTrampoline) \
56 V(VectorKeyedStoreICTrampoline) \
57 V(VectorStoreIC) \
58 V(VectorKeyedStoreIC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 /* HydrogenCodeStubs */ \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060 V(AllocateInNewSpace) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 V(ArrayNArgumentsConstructor) \
62 V(ArrayNoArgumentConstructor) \
63 V(ArraySingleArgumentConstructor) \
64 V(BinaryOpIC) \
65 V(BinaryOpWithAllocationSite) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 V(CreateAllocationSite) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 V(CreateWeakCell) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 V(ElementsTransitionAndStore) \
Ben Murdochda12d292016-06-02 14:46:10 +010069 V(FastArrayPush) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 V(FastCloneRegExp) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 V(FastCloneShallowArray) \
72 V(FastCloneShallowObject) \
73 V(FastNewClosure) \
74 V(FastNewContext) \
Ben Murdoch097c5b22016-05-18 11:27:45 +010075 V(FastNewObject) \
76 V(FastNewRestParameter) \
77 V(FastNewSloppyArguments) \
78 V(FastNewStrictArguments) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 V(GrowArrayElements) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080 V(InternalArrayNArgumentsConstructor) \
81 V(InternalArrayNoArgumentConstructor) \
82 V(InternalArraySingleArgumentConstructor) \
83 V(KeyedLoadGeneric) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 V(LoadGlobalViaContext) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040085 V(LoadScriptContextField) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086 V(LoadDictionaryElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 V(NameDictionaryLookup) \
88 V(NumberToString) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 V(Typeof) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 V(RegExpConstructResult) \
91 V(StoreFastElement) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 V(StoreGlobalViaContext) \
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093 V(StoreScriptContextField) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094 V(StringAdd) \
Ben Murdochda12d292016-06-02 14:46:10 +010095 V(ToBooleanIC) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 V(TransitionElementsKind) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 V(KeyedLoadIC) \
98 V(LoadIC) \
99 /* TurboFanCodeStubs */ \
Ben Murdochda12d292016-06-02 14:46:10 +0100100 V(AllocateHeapNumber) \
101 V(AllocateMutableHeapNumber) \
102 V(AllocateFloat32x4) \
103 V(AllocateInt32x4) \
104 V(AllocateUint32x4) \
105 V(AllocateBool32x4) \
106 V(AllocateInt16x8) \
107 V(AllocateUint16x8) \
108 V(AllocateBool16x8) \
109 V(AllocateInt8x16) \
110 V(AllocateUint8x16) \
111 V(AllocateBool8x16) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 V(StringLength) \
Ben Murdochda12d292016-06-02 14:46:10 +0100113 V(Add) \
114 V(Subtract) \
115 V(BitwiseAnd) \
116 V(BitwiseOr) \
117 V(BitwiseXor) \
118 V(LessThan) \
119 V(LessThanOrEqual) \
120 V(GreaterThan) \
121 V(GreaterThanOrEqual) \
122 V(Equal) \
123 V(NotEqual) \
124 V(StrictEqual) \
125 V(StrictNotEqual) \
126 V(StringEqual) \
127 V(StringNotEqual) \
128 V(StringLessThan) \
129 V(StringLessThanOrEqual) \
130 V(StringGreaterThan) \
131 V(StringGreaterThanOrEqual) \
132 V(ToBoolean) \
133 V(ToInteger) \
134 V(ToLength) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 /* IC Handler stubs */ \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 V(ArrayBufferViewLoadField) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 V(LoadConstant) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 V(LoadFastElement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139 V(LoadField) \
Ben Murdochda12d292016-06-02 14:46:10 +0100140 V(LoadIndexedInterceptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141 V(KeyedLoadSloppyArguments) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142 V(KeyedStoreSloppyArguments) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 V(StoreField) \
Ben Murdochda12d292016-06-02 14:46:10 +0100144 V(StoreInterceptor) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 V(StoreGlobal) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 V(StoreTransition)
Steve Blockd0582a62009-12-15 09:54:21 +0000147
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148// List of code stubs only used on ARM 32 bits platforms.
149#if V8_TARGET_ARCH_ARM
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400150#define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151
Steve Blockd0582a62009-12-15 09:54:21 +0000152#else
153#define CODE_STUB_LIST_ARM(V)
154#endif
155
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156// List of code stubs only used on ARM 64 bits platforms.
157#if V8_TARGET_ARCH_ARM64
158#define CODE_STUB_LIST_ARM64(V) \
159 V(DirectCEntry) \
160 V(RestoreRegistersState) \
161 V(StoreRegistersState)
162
163#else
164#define CODE_STUB_LIST_ARM64(V)
165#endif
166
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167// List of code stubs only used on PPC platforms.
168#ifdef V8_TARGET_ARCH_PPC
169#define CODE_STUB_LIST_PPC(V) \
170 V(DirectCEntry) \
171 V(StoreRegistersState) \
172 V(RestoreRegistersState)
173#else
174#define CODE_STUB_LIST_PPC(V)
175#endif
176
Steve Block44f0eee2011-05-26 01:26:41 +0100177// List of code stubs only used on MIPS platforms.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178#if V8_TARGET_ARCH_MIPS
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179#define CODE_STUB_LIST_MIPS(V) \
180 V(DirectCEntry) \
181 V(RestoreRegistersState) \
182 V(StoreRegistersState)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183#elif V8_TARGET_ARCH_MIPS64
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184#define CODE_STUB_LIST_MIPS(V) \
185 V(DirectCEntry) \
186 V(RestoreRegistersState) \
187 V(StoreRegistersState)
Steve Block44f0eee2011-05-26 01:26:41 +0100188#else
189#define CODE_STUB_LIST_MIPS(V)
190#endif
191
Ben Murdochda12d292016-06-02 14:46:10 +0100192// List of code stubs only used on S390 platforms.
193#ifdef V8_TARGET_ARCH_S390
194#define CODE_STUB_LIST_S390(V) \
195 V(DirectCEntry) \
196 V(StoreRegistersState) \
197 V(RestoreRegistersState)
198#else
199#define CODE_STUB_LIST_S390(V)
200#endif
201
Steve Blockd0582a62009-12-15 09:54:21 +0000202// Combined list of code stubs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203#define CODE_STUB_LIST(V) \
204 CODE_STUB_LIST_ALL_PLATFORMS(V) \
205 CODE_STUB_LIST_ARM(V) \
206 CODE_STUB_LIST_ARM64(V) \
207 CODE_STUB_LIST_PPC(V) \
Ben Murdochda12d292016-06-02 14:46:10 +0100208 CODE_STUB_LIST_MIPS(V) \
209 CODE_STUB_LIST_S390(V)
Steve Blocka7e24c12009-10-30 11:49:00 +0000210
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211static const int kHasReturnedMinusZeroSentinel = 1;
212
Steve Blocka7e24c12009-10-30 11:49:00 +0000213// Stub is base classes of all stubs.
214class CodeStub BASE_EMBEDDED {
215 public:
216 enum Major {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400217 // TODO(mvstanton): eliminate the NoCache key by getting rid
218 // of the non-monomorphic-cache.
219 NoCache = 0, // marker for stubs that do custom caching]
Steve Blockd0582a62009-12-15 09:54:21 +0000220#define DEF_ENUM(name) name,
221 CODE_STUB_LIST(DEF_ENUM)
222#undef DEF_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 NUMBER_OF_IDS
224 };
225
226 // Retrieve the code for the stub. Generate the code if needed.
227 Handle<Code> GetCode();
228
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000229 // Retrieve the code for the stub, make and return a copy of the code.
230 Handle<Code> GetCodeCopy(const Code::FindAndReplacePattern& pattern);
231
Steve Blocka7e24c12009-10-30 11:49:00 +0000232 static Major MajorKeyFromKey(uint32_t key) {
233 return static_cast<Major>(MajorKeyBits::decode(key));
Iain Merrick9ac36c92010-09-13 15:29:50 +0100234 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235 static uint32_t MinorKeyFromKey(uint32_t key) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000236 return MinorKeyBits::decode(key);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100237 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100238
239 // Gets the major key from a code object that is a code stub or binary op IC.
240 static Major GetMajorKey(Code* code_stub) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 return MajorKeyFromKey(code_stub->stub_key());
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100242 }
243
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244 static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
245
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 static const char* MajorName(Major major_key);
Steve Blocka7e24c12009-10-30 11:49:00 +0000247
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000248 explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000249 virtual ~CodeStub() {}
250
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000251 static void GenerateStubsAheadOfTime(Isolate* isolate);
252 static void GenerateFPStubs(Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100253
254 // Some stubs put untagged junk on the stack that cannot be scanned by the
255 // GC. This means that we must be statically sure that no GC can occur while
256 // they are running. If that is the case they should override this to return
257 // true, which will cause an assertion if we try to call something that can
258 // GC or if we try to put a stack frame on top of the junk, which would not
259 // result in a traversable stack.
260 virtual bool SometimesSetsUpAFrame() { return true; }
261
262 // Lookup the code in the (possibly custom) cache.
263 bool FindCodeInCache(Code** code_out);
264
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000265 virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() const = 0;
266
267 virtual int GetStackParameterCount() const {
268 return GetCallInterfaceDescriptor().GetStackParameterCount();
269 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000270
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
272
273 static void InitializeDescriptor(Isolate* isolate, uint32_t key,
274 CodeStubDescriptor* desc);
275
276 static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key);
277
278 // Returns information for computing the number key.
279 virtual Major MajorKey() const = 0;
280 uint32_t MinorKey() const { return minor_key_; }
281
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282 // BinaryOpStub needs to override this.
283 virtual Code::Kind GetCodeKind() const;
284
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285 virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
286 virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000287 virtual Code::StubType GetStubType() const { return Code::NORMAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000288
Ben Murdoch097c5b22016-05-18 11:27:45 +0100289 Code::Flags GetCodeFlags() const;
290
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400291 friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292 s.PrintName(os);
293 return os;
294 }
295
296 Isolate* isolate() const { return isolate_; }
297
298 protected:
299 CodeStub(uint32_t key, Isolate* isolate)
300 : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
Leon Clarkee46be812010-01-19 14:06:41 +0000301
Steve Blocka7e24c12009-10-30 11:49:00 +0000302 // Generates the assembler code for the stub.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000303 virtual Handle<Code> GenerateCode() = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000304
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000305 // Returns whether the code generated for this stub needs to be allocated as
306 // a fixed (non-moveable) code object.
307 virtual bool NeedsImmovableCode() { return false; }
308
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400309 virtual void PrintName(std::ostream& os) const; // NOLINT
310 virtual void PrintBaseName(std::ostream& os) const; // NOLINT
311 virtual void PrintState(std::ostream& os) const { ; } // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312
313 // Computes the key based on major and minor.
314 uint32_t GetKey() {
315 DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
316 return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
317 }
318
319 uint32_t minor_key_;
320
321 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000322 // Perform bookkeeping required after code generation when stub code is
323 // initially generated.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324 void RecordCodeGeneration(Handle<Code> code);
Leon Clarkee46be812010-01-19 14:06:41 +0000325
Ben Murdochb0fe1622011-05-05 13:52:32 +0100326 // Finish the code object after it has been generated.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100327 virtual void FinishCode(Handle<Code> code) { }
328
329 // Activate newly generated stub. Is called after
330 // registering stub in the stub cache.
331 virtual void Activate(Code* code) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100332
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100333 // Add the code to a specialized cache, specific to an individual
334 // stub type. Please note, this method must add the code object to a
335 // roots object, otherwise we will remove the code during GC.
336 virtual void AddToSpecialCache(Handle<Code> new_object) { }
337
338 // Find code in a specialized cache, work is delegated to the specific stub.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339 virtual bool FindCodeInSpecialCache(Code** code_out) {
340 return false;
341 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100342
343 // If a stub uses a special cache override this.
344 virtual bool UseSpecialCache() { return false; }
345
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346 // We use this dispatch to statically instantiate the correct code stub for
347 // the given stub key and call the passed function with that code stub.
348 typedef void (*DispatchedCall)(CodeStub* stub, void** value_out);
349 static void Dispatch(Isolate* isolate, uint32_t key, void** value_out,
350 DispatchedCall call);
Steve Blocka7e24c12009-10-30 11:49:00 +0000351
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 static void GetCodeDispatchCall(CodeStub* stub, void** value_out);
Steve Block44f0eee2011-05-26 01:26:41 +0100353
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000354 STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
355 class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
356 class MinorKeyBits: public BitField<uint32_t,
357 kStubMajorKeyBits, kStubMinorKeyBits> {}; // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +0000358
359 friend class BreakPointIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000360
361 Isolate* isolate_;
362};
363
364
365#define DEFINE_CODE_STUB_BASE(NAME, SUPER) \
366 public: \
367 NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \
368 \
369 private: \
370 DISALLOW_COPY_AND_ASSIGN(NAME)
371
372
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400373#define DEFINE_CODE_STUB(NAME, SUPER) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100374 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000375 inline Major MajorKey() const override { return NAME; }; \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100376 \
377 protected: \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000378 DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
379
380
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400381#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \
382 private: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 void Generate(MacroAssembler* masm) override; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384 DEFINE_CODE_STUB(NAME, SUPER)
385
386
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400387#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER) \
388 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
390 Handle<Code> GenerateCode() override; \
391 DEFINE_CODE_STUB(NAME, SUPER)
392
Ben Murdochda12d292016-06-02 14:46:10 +0100393#define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER) \
394 public: \
395 void GenerateAssembly(compiler::CodeStubAssembler* assembler) \
396 const override; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000397 DEFINE_CODE_STUB(NAME, SUPER)
398
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400399#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
400 public: \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401 Handle<Code> GenerateCode() override; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000402 DEFINE_CODE_STUB(NAME, SUPER)
403
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \
405 public: \
406 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
407 return NAME##Descriptor(isolate()); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000408 }
409
410// There are some code stubs we just can't describe right now with a
411// CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
412// An attempt to retrieve a descriptor will fail.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \
414 public: \
415 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
416 UNREACHABLE(); \
417 return CallInterfaceDescriptor(); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000418 }
419
420
421class PlatformCodeStub : public CodeStub {
422 public:
423 // Retrieve the code for the stub. Generate the code if needed.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424 Handle<Code> GenerateCode() override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425
426 protected:
427 explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
428
429 // Generates the assembler code for the stub.
430 virtual void Generate(MacroAssembler* masm) = 0;
431
432 DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub);
433};
434
435
436enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437
438
439class CodeStubDescriptor {
440 public:
441 explicit CodeStubDescriptor(CodeStub* stub);
442
443 CodeStubDescriptor(Isolate* isolate, uint32_t stub_key);
444
445 void Initialize(Address deoptimization_handler = NULL,
446 int hint_stack_parameter_count = -1,
447 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
448 void Initialize(Register stack_parameter_count,
449 Address deoptimization_handler = NULL,
450 int hint_stack_parameter_count = -1,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000451 StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000452
453 void SetMissHandler(ExternalReference handler) {
454 miss_handler_ = handler;
455 has_miss_handler_ = true;
456 // Our miss handler infrastructure doesn't currently support
457 // variable stack parameter counts.
458 DCHECK(!stack_parameter_count_.is_valid());
459 }
460
461 void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
462 CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
463
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 int GetRegisterParameterCount() const {
465 return call_descriptor().GetRegisterParameterCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000466 }
467
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000468 int GetStackParameterCount() const {
469 return call_descriptor().GetStackParameterCount();
470 }
471
472 int GetParameterCount() const {
473 return call_descriptor().GetParameterCount();
474 }
475
476 Register GetRegisterParameter(int index) const {
477 return call_descriptor().GetRegisterParameter(index);
478 }
479
480 Type* GetParameterType(int index) const {
481 return call_descriptor().GetParameterType(index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000482 }
483
484 ExternalReference miss_handler() const {
485 DCHECK(has_miss_handler_);
486 return miss_handler_;
487 }
488
489 bool has_miss_handler() const {
490 return has_miss_handler_;
491 }
492
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000493 int GetHandlerParameterCount() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000494 int params = GetParameterCount();
495 if (PassesArgumentsToDeoptimizationHandler()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000496 params += 1;
497 }
498 return params;
499 }
500
501 int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
502 Register stack_parameter_count() const { return stack_parameter_count_; }
503 StubFunctionMode function_mode() const { return function_mode_; }
504 Address deoptimization_handler() const { return deoptimization_handler_; }
505
506 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 bool PassesArgumentsToDeoptimizationHandler() const {
508 return stack_parameter_count_.is_valid();
509 }
510
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000511 CallInterfaceDescriptor call_descriptor_;
512 Register stack_parameter_count_;
513 // If hint_stack_parameter_count_ > 0, the code stub can optimize the
514 // return sequence. Default value is -1, which means it is ignored.
515 int hint_stack_parameter_count_;
516 StubFunctionMode function_mode_;
517
518 Address deoptimization_handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000519
520 ExternalReference miss_handler_;
521 bool has_miss_handler_;
522};
523
524
525class HydrogenCodeStub : public CodeStub {
526 public:
527 enum InitializationState {
528 UNINITIALIZED,
529 INITIALIZED
530 };
531
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532 template<class SubClass>
533 static Handle<Code> GetUninitialized(Isolate* isolate) {
534 SubClass::GenerateAheadOfTime(isolate);
535 return SubClass().GetCode(isolate);
536 }
537
538 // Retrieve the code for the stub. Generate the code if needed.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000539 Handle<Code> GenerateCode() override = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000540
541 bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
542
543 Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
544
545 template<class StateType>
546 void TraceTransition(StateType from, StateType to);
547
548 protected:
549 explicit HydrogenCodeStub(Isolate* isolate,
550 InitializationState state = INITIALIZED)
551 : CodeStub(isolate) {
552 minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
553 }
554
555 void set_sub_minor_key(uint32_t key) {
556 minor_key_ = SubMinorKeyBits::update(minor_key_, key);
557 }
558
559 uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
560
561 static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
562
563 private:
564 class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};
565 class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
566
567 void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss);
568
569 DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub);
Steve Blocka7e24c12009-10-30 11:49:00 +0000570};
571
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100572
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573class TurboFanCodeStub : public CodeStub {
574 public:
575 // Retrieve the code for the stub. Generate the code if needed.
576 Handle<Code> GenerateCode() override;
577
578 int GetStackParameterCount() const override {
579 return GetCallInterfaceDescriptor().GetStackParameterCount();
580 }
581
582 Code::StubType GetStubType() const override { return Code::FAST; }
583
584 protected:
585 explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
586
587 virtual void GenerateAssembly(
588 compiler::CodeStubAssembler* assembler) const = 0;
589
590 private:
591 DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
592};
593
594
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100595// Helper interface to prepare to/restore after making runtime calls.
596class RuntimeCallHelper {
597 public:
598 virtual ~RuntimeCallHelper() {}
599
600 virtual void BeforeCall(MacroAssembler* masm) const = 0;
601
602 virtual void AfterCall(MacroAssembler* masm) const = 0;
603
604 protected:
605 RuntimeCallHelper() {}
606
607 private:
608 DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
609};
610
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000611
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000612} // namespace internal
613} // namespace v8
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100614
615#if V8_TARGET_ARCH_IA32
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000616#include "src/ia32/code-stubs-ia32.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100617#elif V8_TARGET_ARCH_X64
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618#include "src/x64/code-stubs-x64.h"
619#elif V8_TARGET_ARCH_ARM64
620#include "src/arm64/code-stubs-arm64.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100621#elif V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000622#include "src/arm/code-stubs-arm.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623#elif V8_TARGET_ARCH_PPC
624#include "src/ppc/code-stubs-ppc.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100625#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000626#include "src/mips/code-stubs-mips.h"
627#elif V8_TARGET_ARCH_MIPS64
628#include "src/mips64/code-stubs-mips64.h"
Ben Murdochda12d292016-06-02 14:46:10 +0100629#elif V8_TARGET_ARCH_S390
630#include "src/s390/code-stubs-s390.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000631#elif V8_TARGET_ARCH_X87
632#include "src/x87/code-stubs-x87.h"
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100633#else
634#error Unsupported target architecture.
635#endif
636
637namespace v8 {
638namespace internal {
639
640
Ben Murdochb0fe1622011-05-05 13:52:32 +0100641// RuntimeCallHelper implementation used in stubs: enters/leaves a
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100642// newly created internal frame before/after the runtime call.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100643class StubRuntimeCallHelper : public RuntimeCallHelper {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100644 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100645 StubRuntimeCallHelper() {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100646
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000647 void BeforeCall(MacroAssembler* masm) const override;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649 void AfterCall(MacroAssembler* masm) const override;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100650};
651
652
653// Trivial RuntimeCallHelper implementation.
654class NopRuntimeCallHelper : public RuntimeCallHelper {
655 public:
656 NopRuntimeCallHelper() {}
657
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000658 void BeforeCall(MacroAssembler* masm) const override {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100659
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000660 void AfterCall(MacroAssembler* masm) const override {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100661};
662
663
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664class StringLengthStub : public TurboFanCodeStub {
665 public:
666 explicit StringLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
667
668 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
669 InlineCacheState GetICState() const override { return MONOMORPHIC; }
670 ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
Ben Murdochda12d292016-06-02 14:46:10 +0100673 DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000674};
675
Ben Murdochda12d292016-06-02 14:46:10 +0100676class AddStub final : public TurboFanCodeStub {
677 public:
678 explicit AddStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
679
680 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
681 DEFINE_TURBOFAN_CODE_STUB(Add, TurboFanCodeStub);
682};
683
684class SubtractStub final : public TurboFanCodeStub {
685 public:
686 explicit SubtractStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
687
688 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
689 DEFINE_TURBOFAN_CODE_STUB(Subtract, TurboFanCodeStub);
690};
691
692class BitwiseAndStub final : public TurboFanCodeStub {
693 public:
694 explicit BitwiseAndStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
695
696 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
697 DEFINE_TURBOFAN_CODE_STUB(BitwiseAnd, TurboFanCodeStub);
698};
699
700class BitwiseOrStub final : public TurboFanCodeStub {
701 public:
702 explicit BitwiseOrStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
703
704 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
705 DEFINE_TURBOFAN_CODE_STUB(BitwiseOr, TurboFanCodeStub);
706};
707
708class BitwiseXorStub final : public TurboFanCodeStub {
709 public:
710 explicit BitwiseXorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
711
712 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
713 DEFINE_TURBOFAN_CODE_STUB(BitwiseXor, TurboFanCodeStub);
714};
715
716class LessThanStub final : public TurboFanCodeStub {
717 public:
718 explicit LessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
719
720 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
721 DEFINE_TURBOFAN_CODE_STUB(LessThan, TurboFanCodeStub);
722};
723
724class LessThanOrEqualStub final : public TurboFanCodeStub {
725 public:
726 explicit LessThanOrEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
727
728 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
729 DEFINE_TURBOFAN_CODE_STUB(LessThanOrEqual, TurboFanCodeStub);
730};
731
732class GreaterThanStub final : public TurboFanCodeStub {
733 public:
734 explicit GreaterThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
735
736 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
737 DEFINE_TURBOFAN_CODE_STUB(GreaterThan, TurboFanCodeStub);
738};
739
740class GreaterThanOrEqualStub final : public TurboFanCodeStub {
741 public:
742 explicit GreaterThanOrEqualStub(Isolate* isolate)
743 : TurboFanCodeStub(isolate) {}
744
745 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
746 DEFINE_TURBOFAN_CODE_STUB(GreaterThanOrEqual, TurboFanCodeStub);
747};
748
749class EqualStub final : public TurboFanCodeStub {
750 public:
751 explicit EqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
752
753 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
754 DEFINE_TURBOFAN_CODE_STUB(Equal, TurboFanCodeStub);
755};
756
757class NotEqualStub final : public TurboFanCodeStub {
758 public:
759 explicit NotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
760
761 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
762 DEFINE_TURBOFAN_CODE_STUB(NotEqual, TurboFanCodeStub);
763};
764
765class StrictEqualStub final : public TurboFanCodeStub {
766 public:
767 explicit StrictEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
768
769 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
770 DEFINE_TURBOFAN_CODE_STUB(StrictEqual, TurboFanCodeStub);
771};
772
773class StrictNotEqualStub final : public TurboFanCodeStub {
774 public:
775 explicit StrictNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
776
777 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
778 DEFINE_TURBOFAN_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
779};
780
781class StringEqualStub final : public TurboFanCodeStub {
782 public:
783 explicit StringEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
784
785 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
786 DEFINE_TURBOFAN_CODE_STUB(StringEqual, TurboFanCodeStub);
787};
788
789class StringNotEqualStub final : public TurboFanCodeStub {
790 public:
791 explicit StringNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
792
793 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
794 DEFINE_TURBOFAN_CODE_STUB(StringNotEqual, TurboFanCodeStub);
795};
796
797class StringLessThanStub final : public TurboFanCodeStub {
798 public:
799 explicit StringLessThanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
800
801 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
802 DEFINE_TURBOFAN_CODE_STUB(StringLessThan, TurboFanCodeStub);
803};
804
805class StringLessThanOrEqualStub final : public TurboFanCodeStub {
806 public:
807 explicit StringLessThanOrEqualStub(Isolate* isolate)
808 : TurboFanCodeStub(isolate) {}
809
810 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
811 DEFINE_TURBOFAN_CODE_STUB(StringLessThanOrEqual, TurboFanCodeStub);
812};
813
814class StringGreaterThanStub final : public TurboFanCodeStub {
815 public:
816 explicit StringGreaterThanStub(Isolate* isolate)
817 : TurboFanCodeStub(isolate) {}
818
819 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
820 DEFINE_TURBOFAN_CODE_STUB(StringGreaterThan, TurboFanCodeStub);
821};
822
823class StringGreaterThanOrEqualStub final : public TurboFanCodeStub {
824 public:
825 explicit StringGreaterThanOrEqualStub(Isolate* isolate)
826 : TurboFanCodeStub(isolate) {}
827
828 DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
829 DEFINE_TURBOFAN_CODE_STUB(StringGreaterThanOrEqual, TurboFanCodeStub);
830};
831
832class ToBooleanStub final : public TurboFanCodeStub {
833 public:
834 explicit ToBooleanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
835
836 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
837 DEFINE_TURBOFAN_CODE_STUB(ToBoolean, TurboFanCodeStub);
838};
839
840class ToIntegerStub final : public TurboFanCodeStub {
841 public:
842 explicit ToIntegerStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
843
844 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
845 DEFINE_TURBOFAN_CODE_STUB(ToInteger, TurboFanCodeStub);
846};
847
848class ToLengthStub final : public TurboFanCodeStub {
849 public:
850 explicit ToLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
851
852 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
853 DEFINE_TURBOFAN_CODE_STUB(ToLength, TurboFanCodeStub);
854};
855
856class StoreInterceptorStub : public TurboFanCodeStub {
857 public:
858 explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
859
860 void GenerateAssembly(compiler::CodeStubAssembler* assember) const override;
861
862 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
863
864 DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
865 DEFINE_CODE_STUB(StoreInterceptor, TurboFanCodeStub);
866};
867
868class LoadIndexedInterceptorStub : public TurboFanCodeStub {
869 public:
870 explicit LoadIndexedInterceptorStub(Isolate* isolate)
871 : TurboFanCodeStub(isolate) {}
872
873 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
874
875 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
876 DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
877};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878
879enum StringAddFlags {
880 // Omit both parameter checks.
881 STRING_ADD_CHECK_NONE = 0,
882 // Check left parameter.
883 STRING_ADD_CHECK_LEFT = 1 << 0,
884 // Check right parameter.
885 STRING_ADD_CHECK_RIGHT = 1 << 1,
886 // Check both parameters.
887 STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT,
888 // Convert parameters when check fails (instead of throwing an exception).
889 STRING_ADD_CONVERT = 1 << 2,
890 STRING_ADD_CONVERT_LEFT = STRING_ADD_CHECK_LEFT | STRING_ADD_CONVERT,
891 STRING_ADD_CONVERT_RIGHT = STRING_ADD_CHECK_RIGHT | STRING_ADD_CONVERT
892};
893
894
895std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags);
896
897
898class NumberToStringStub final : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100899 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000900 explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100901
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
903 static const int kNumber = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100904
Ben Murdochda12d292016-06-02 14:46:10 +0100905 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000906 DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100907};
908
909
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000910class TypeofStub final : public HydrogenCodeStub {
911 public:
912 explicit TypeofStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
913
914 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
915 static const int kObject = 0;
916
917 static void GenerateAheadOfTime(Isolate* isolate);
918
919 DEFINE_CALL_INTERFACE_DESCRIPTOR(Typeof);
920 DEFINE_HYDROGEN_CODE_STUB(Typeof, HydrogenCodeStub);
921};
922
923
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000924class FastNewClosureStub : public HydrogenCodeStub {
Steve Block1e0659c2011-05-24 12:43:12 +0100925 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000926 FastNewClosureStub(Isolate* isolate, LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927 FunctionKind kind)
928 : HydrogenCodeStub(isolate) {
929 DCHECK(IsValidFunctionKind(kind));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000930 set_sub_minor_key(LanguageModeBits::encode(language_mode) |
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000931 FunctionKindBits::encode(kind));
932 }
Steve Block1e0659c2011-05-24 12:43:12 +0100933
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 LanguageMode language_mode() const {
935 return LanguageModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000936 }
937
938 FunctionKind kind() const {
939 return FunctionKindBits::decode(sub_minor_key());
940 }
Steve Block1e0659c2011-05-24 12:43:12 +0100941
942 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000943 STATIC_ASSERT(LANGUAGE_END == 3);
944 class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
945 class FunctionKindBits : public BitField<FunctionKind, 2, 8> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000946
947 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
948 DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
Steve Block1e0659c2011-05-24 12:43:12 +0100949};
950
951
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000952class FastNewContextStub final : public HydrogenCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100953 public:
954 static const int kMaximumSlots = 64;
955
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000956 FastNewContextStub(Isolate* isolate, int slots) : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 DCHECK(slots >= 0 && slots <= kMaximumSlots);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000958 set_sub_minor_key(SlotsBits::encode(slots));
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100959 }
960
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000961 int slots() const { return SlotsBits::decode(sub_minor_key()); }
962
963 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
964 static const int kFunction = 0;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100965
966 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000967 class SlotsBits : public BitField<int, 0, 8> {};
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100968
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000969 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewContext);
970 DEFINE_HYDROGEN_CODE_STUB(FastNewContext, HydrogenCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100971};
972
973
Ben Murdoch097c5b22016-05-18 11:27:45 +0100974class FastNewObjectStub final : public PlatformCodeStub {
975 public:
976 explicit FastNewObjectStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
977
978 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewObject);
979 DEFINE_PLATFORM_CODE_STUB(FastNewObject, PlatformCodeStub);
980};
981
982
983// TODO(turbofan): This stub should be possible to write in TurboFan
984// using the CodeStubAssembler very soon in a way that is as efficient
985// and easy as the current handwritten version, which is partly a copy
986// of the strict arguments object materialization code.
987class FastNewRestParameterStub final : public PlatformCodeStub {
988 public:
989 explicit FastNewRestParameterStub(Isolate* isolate)
990 : PlatformCodeStub(isolate) {}
991
992 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewRestParameter);
993 DEFINE_PLATFORM_CODE_STUB(FastNewRestParameter, PlatformCodeStub);
994};
995
996
997// TODO(turbofan): This stub should be possible to write in TurboFan
998// using the CodeStubAssembler very soon in a way that is as efficient
999// and easy as the current handwritten version.
1000class FastNewSloppyArgumentsStub final : public PlatformCodeStub {
1001 public:
1002 explicit FastNewSloppyArgumentsStub(Isolate* isolate)
1003 : PlatformCodeStub(isolate) {}
1004
1005 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewSloppyArguments);
1006 DEFINE_PLATFORM_CODE_STUB(FastNewSloppyArguments, PlatformCodeStub);
1007};
1008
1009
1010// TODO(turbofan): This stub should be possible to write in TurboFan
1011// using the CodeStubAssembler very soon in a way that is as efficient
1012// and easy as the current handwritten version.
1013class FastNewStrictArgumentsStub final : public PlatformCodeStub {
1014 public:
1015 explicit FastNewStrictArgumentsStub(Isolate* isolate)
1016 : PlatformCodeStub(isolate) {}
1017
1018 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewStrictArguments);
1019 DEFINE_PLATFORM_CODE_STUB(FastNewStrictArguments, PlatformCodeStub);
1020};
1021
1022
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001023class FastCloneRegExpStub final : public HydrogenCodeStub {
1024 public:
1025 explicit FastCloneRegExpStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1026
1027 private:
1028 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneRegExp);
1029 DEFINE_HYDROGEN_CODE_STUB(FastCloneRegExp, HydrogenCodeStub);
1030};
1031
1032
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001033class FastCloneShallowArrayStub : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001034 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001035 FastCloneShallowArrayStub(Isolate* isolate,
1036 AllocationSiteMode allocation_site_mode)
1037 : HydrogenCodeStub(isolate) {
1038 set_sub_minor_key(AllocationSiteModeBits::encode(allocation_site_mode));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001039 }
1040
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041 AllocationSiteMode allocation_site_mode() const {
1042 return AllocationSiteModeBits::decode(sub_minor_key());
1043 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001044
1045 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001046 class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001047
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001048 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowArray);
1049 DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowArray, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001050};
1051
1052
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001053class FastCloneShallowObjectStub : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001054 public:
1055 // Maximum number of properties in copied object.
1056 static const int kMaximumClonedProperties = 6;
1057
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001058 FastCloneShallowObjectStub(Isolate* isolate, int length)
1059 : HydrogenCodeStub(isolate) {
1060 DCHECK_GE(length, 0);
1061 DCHECK_LE(length, kMaximumClonedProperties);
1062 set_sub_minor_key(LengthBits::encode(length));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001063 }
1064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001065 int length() const { return LengthBits::decode(sub_minor_key()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001066
1067 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001068 class LengthBits : public BitField<int, 0, 4> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowObject);
1071 DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowObject, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001072};
1073
1074
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075class CreateAllocationSiteStub : public HydrogenCodeStub {
1076 public:
1077 explicit CreateAllocationSiteStub(Isolate* isolate)
1078 : HydrogenCodeStub(isolate) { }
1079
1080 static void GenerateAheadOfTime(Isolate* isolate);
1081
1082 DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite);
1083 DEFINE_HYDROGEN_CODE_STUB(CreateAllocationSite, HydrogenCodeStub);
1084};
1085
1086
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001087class CreateWeakCellStub : public HydrogenCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001088 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001089 explicit CreateWeakCellStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
Ben Murdochb0fe1622011-05-05 13:52:32 +01001090
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001091 static void GenerateAheadOfTime(Isolate* isolate);
1092
1093 DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
1094 DEFINE_HYDROGEN_CODE_STUB(CreateWeakCell, HydrogenCodeStub);
1095};
1096
1097
1098class GrowArrayElementsStub : public HydrogenCodeStub {
1099 public:
1100 GrowArrayElementsStub(Isolate* isolate, bool is_js_array, ElementsKind kind)
1101 : HydrogenCodeStub(isolate) {
1102 set_sub_minor_key(ElementsKindBits::encode(kind) |
1103 IsJsArrayBits::encode(is_js_array));
Ben Murdochb0fe1622011-05-05 13:52:32 +01001104 }
1105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001106 ElementsKind elements_kind() const {
1107 return ElementsKindBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001108 }
1109
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001110 bool is_js_array() const { return IsJsArrayBits::decode(sub_minor_key()); }
1111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001112 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001113 class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
1114 class IsJsArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116 DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
1117 DEFINE_HYDROGEN_CODE_STUB(GrowArrayElements, HydrogenCodeStub);
1118};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001119
Ben Murdochda12d292016-06-02 14:46:10 +01001120class FastArrayPushStub : public HydrogenCodeStub {
1121 public:
1122 explicit FastArrayPushStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1123
1124 private:
1125 DEFINE_CALL_INTERFACE_DESCRIPTOR(FastArrayPush);
1126 DEFINE_HYDROGEN_CODE_STUB(FastArrayPush, HydrogenCodeStub);
1127};
Ben Murdoch086aeea2011-05-13 15:57:08 +01001128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001129class InstanceOfStub final : public PlatformCodeStub {
1130 public:
Ben Murdochda12d292016-06-02 14:46:10 +01001131 explicit InstanceOfStub(Isolate* isolate, bool es6_instanceof = false)
1132 : PlatformCodeStub(isolate) {
1133 minor_key_ = IsES6InstanceOfBits::encode(es6_instanceof);
1134 }
1135
1136 bool is_es6_instanceof() const {
1137 return IsES6InstanceOfBits::decode(minor_key_);
1138 }
Ben Murdoch086aeea2011-05-13 15:57:08 +01001139
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 private:
Ben Murdochda12d292016-06-02 14:46:10 +01001141 class IsES6InstanceOfBits : public BitField<bool, 0, 1> {};
1142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001143 DEFINE_CALL_INTERFACE_DESCRIPTOR(InstanceOf);
1144 DEFINE_PLATFORM_CODE_STUB(InstanceOf, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001145};
1146
1147
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001148enum AllocationSiteOverrideMode {
1149 DONT_OVERRIDE,
1150 DISABLE_ALLOCATION_SITES,
1151 LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
1152};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001153
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001154
1155class ArrayConstructorStub: public PlatformCodeStub {
1156 public:
1157 enum ArgumentCountKey { ANY, NONE, ONE, MORE_THAN_ONE };
1158
1159 ArrayConstructorStub(Isolate* isolate, int argument_count);
1160
1161 explicit ArrayConstructorStub(Isolate* isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001162
1163 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001164 ArgumentCountKey argument_count() const {
1165 return ArgumentCountBits::decode(minor_key_);
1166 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001168 void GenerateDispatchToArrayStub(MacroAssembler* masm,
1169 AllocationSiteOverrideMode mode);
1170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171 void PrintName(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001172
1173 class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
1174
1175 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
1176 DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001177};
1178
1179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180class InternalArrayConstructorStub: public PlatformCodeStub {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001181 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001182 explicit InternalArrayConstructorStub(Isolate* isolate);
1183
1184 private:
1185 void GenerateCase(MacroAssembler* masm, ElementsKind kind);
1186
1187 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
1188 DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
1189};
1190
1191
1192class MathPowStub: public PlatformCodeStub {
1193 public:
1194 enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK };
1195
1196 MathPowStub(Isolate* isolate, ExponentType exponent_type)
1197 : PlatformCodeStub(isolate) {
1198 minor_key_ = ExponentTypeBits::encode(exponent_type);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001199 }
1200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001201 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001202 if (exponent_type() == TAGGED) {
1203 return MathPowTaggedDescriptor(isolate());
1204 } else if (exponent_type() == INTEGER) {
1205 return MathPowIntegerDescriptor(isolate());
1206 }
1207 // A CallInterfaceDescriptor doesn't specify double registers (yet).
1208 return ContextOnlyDescriptor(isolate());
1209 }
1210
1211 private:
1212 ExponentType exponent_type() const {
1213 return ExponentTypeBits::decode(minor_key_);
1214 }
1215
1216 class ExponentTypeBits : public BitField<ExponentType, 0, 2> {};
1217
1218 DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub);
1219};
1220
1221
1222class CallICStub: public PlatformCodeStub {
1223 public:
1224 CallICStub(Isolate* isolate, const CallICState& state)
1225 : PlatformCodeStub(isolate) {
1226 minor_key_ = state.GetExtraICState();
1227 }
1228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001229 Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001230
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001231 InlineCacheState GetICState() const override { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001232
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001233 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001234 return static_cast<ExtraICState>(minor_key_);
1235 }
1236
1237 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001238 int arg_count() const { return state().argc(); }
1239 ConvertReceiverMode convert_mode() const { return state().convert_mode(); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001240 TailCallMode tail_call_mode() const { return state().tail_call_mode(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001241
1242 CallICState state() const {
1243 return CallICState(static_cast<ExtraICState>(minor_key_));
1244 }
1245
1246 // Code generation helpers.
1247 void GenerateMiss(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001248 void HandleArrayCase(MacroAssembler* masm, Label* miss);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001249
1250 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001253 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedbackAndVector);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001254 DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
1255};
1256
1257
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001258// TODO(verwaest): Translate to hydrogen code stub.
1259class FunctionPrototypeStub : public PlatformCodeStub {
1260 public:
1261 explicit FunctionPrototypeStub(Isolate* isolate)
1262 : PlatformCodeStub(isolate) {}
1263
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001264 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001265
1266 // TODO(mvstanton): only the receiver register is accessed. When this is
1267 // translated to a hydrogen code stub, a new CallInterfaceDescriptor
1268 // should be created that just uses that register for more efficient code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001269 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
1270 return LoadWithVectorDescriptor(isolate());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001271 }
1272
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001273 DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
1274};
1275
1276
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001277class LoadIndexedStringStub : public PlatformCodeStub {
1278 public:
1279 explicit LoadIndexedStringStub(Isolate* isolate)
1280 : PlatformCodeStub(isolate) {}
1281
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001282 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1283 Code::StubType GetStubType() const override { return Code::FAST; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001284
1285 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
1286 DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
1287};
1288
1289
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001290class HandlerStub : public HydrogenCodeStub {
1291 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001292 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1293 ExtraICState GetExtraICState() const override { return kind(); }
1294 InlineCacheState GetICState() const override { return MONOMORPHIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001295
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001296 void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001298 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001299
1300 protected:
1301 explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1302
1303 virtual Code::Kind kind() const = 0;
1304
1305 DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub);
1306};
1307
1308
1309class LoadFieldStub: public HandlerStub {
1310 public:
1311 LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate) {
1312 int property_index_key = index.GetFieldAccessStubKey();
1313 set_sub_minor_key(LoadFieldByIndexBits::encode(property_index_key));
1314 }
1315
1316 FieldIndex index() const {
1317 int property_index_key = LoadFieldByIndexBits::decode(sub_minor_key());
1318 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1319 }
1320
1321 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001322 Code::Kind kind() const override { return Code::LOAD_IC; }
1323 Code::StubType GetStubType() const override { return Code::FAST; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001324
1325 private:
1326 class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
1327
1328 DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub);
1329};
1330
1331
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001332class ArrayBufferViewLoadFieldStub : public HandlerStub {
1333 public:
1334 ArrayBufferViewLoadFieldStub(Isolate* isolate, FieldIndex index)
1335 : HandlerStub(isolate) {
1336 int property_index_key = index.GetFieldAccessStubKey();
1337 set_sub_minor_key(
1338 ArrayBufferViewLoadFieldByIndexBits::encode(property_index_key));
1339 }
1340
1341 FieldIndex index() const {
1342 int property_index_key =
1343 ArrayBufferViewLoadFieldByIndexBits::decode(sub_minor_key());
1344 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1345 }
1346
1347 protected:
1348 Code::Kind kind() const override { return Code::LOAD_IC; }
1349 Code::StubType GetStubType() const override { return Code::FAST; }
1350
1351 private:
1352 class ArrayBufferViewLoadFieldByIndexBits : public BitField<int, 0, 13> {};
1353
1354 DEFINE_HANDLER_CODE_STUB(ArrayBufferViewLoadField, HandlerStub);
1355};
1356
1357
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001358class KeyedLoadSloppyArgumentsStub : public HandlerStub {
1359 public:
1360 explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
1361 : HandlerStub(isolate) {}
1362
1363 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001364 Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
1365 Code::StubType GetStubType() const override { return Code::FAST; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001366
1367 private:
1368 DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
1369};
1370
1371
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001372class CommonStoreModeBits : public BitField<KeyedAccessStoreMode, 0, 3> {};
1373
1374class KeyedStoreSloppyArgumentsStub : public HandlerStub {
1375 public:
1376 explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate,
1377 KeyedAccessStoreMode mode)
1378 : HandlerStub(isolate) {
1379 set_sub_minor_key(CommonStoreModeBits::encode(mode));
1380 }
1381
1382 protected:
1383 Code::Kind kind() const override { return Code::KEYED_STORE_IC; }
1384 Code::StubType GetStubType() const override { return Code::FAST; }
1385
1386 private:
1387 DEFINE_HANDLER_CODE_STUB(KeyedStoreSloppyArguments, HandlerStub);
1388};
1389
1390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001391class LoadConstantStub : public HandlerStub {
1392 public:
1393 LoadConstantStub(Isolate* isolate, int constant_index)
1394 : HandlerStub(isolate) {
1395 set_sub_minor_key(ConstantIndexBits::encode(constant_index));
1396 }
1397
1398 int constant_index() const {
1399 return ConstantIndexBits::decode(sub_minor_key());
1400 }
1401
1402 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001403 Code::Kind kind() const override { return Code::LOAD_IC; }
1404 Code::StubType GetStubType() const override { return Code::FAST; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001405
1406 private:
1407 class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {};
1408
1409 DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub);
1410};
1411
1412
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001413class StoreFieldStub : public HandlerStub {
1414 public:
1415 StoreFieldStub(Isolate* isolate, FieldIndex index,
1416 Representation representation)
1417 : HandlerStub(isolate) {
1418 int property_index_key = index.GetFieldAccessStubKey();
1419 uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1420 set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1421 RepresentationBits::encode(repr));
1422 }
1423
1424 FieldIndex index() const {
1425 int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1426 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1427 }
1428
1429 Representation representation() {
1430 uint8_t repr = RepresentationBits::decode(sub_minor_key());
1431 return PropertyDetails::DecodeRepresentation(repr);
1432 }
1433
1434 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001435 Code::Kind kind() const override { return Code::STORE_IC; }
1436 Code::StubType GetStubType() const override { return Code::FAST; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001437
1438 private:
1439 class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1440 class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1441
1442 DEFINE_HANDLER_CODE_STUB(StoreField, HandlerStub);
1443};
1444
1445
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001446// Register and parameter access methods are specified here instead of in
1447// the CallInterfaceDescriptor because the stub uses a different descriptor
1448// if FLAG_vector_stores is on.
1449class StoreTransitionHelper {
1450 public:
1451 static Register ReceiverRegister() {
1452 return StoreTransitionDescriptor::ReceiverRegister();
1453 }
1454
1455 static Register NameRegister() {
1456 return StoreTransitionDescriptor::NameRegister();
1457 }
1458
1459 static Register ValueRegister() {
1460 return StoreTransitionDescriptor::ValueRegister();
1461 }
1462
1463 static Register SlotRegister() {
1464 return VectorStoreTransitionDescriptor::SlotRegister();
1465 }
1466
1467 static Register VectorRegister() {
1468 return VectorStoreTransitionDescriptor::VectorRegister();
1469 }
1470
1471 static Register MapRegister() {
1472 return VectorStoreTransitionDescriptor::MapRegister();
1473 }
1474
1475 static int ReceiverIndex() {
1476 return StoreTransitionDescriptor::kReceiverIndex;
1477 }
1478
1479 static int NameIndex() { return StoreTransitionDescriptor::kReceiverIndex; }
1480
1481 static int ValueIndex() { return StoreTransitionDescriptor::kValueIndex; }
1482
1483 static int MapIndex() {
1484 DCHECK(static_cast<int>(VectorStoreTransitionDescriptor::kMapIndex) ==
1485 static_cast<int>(StoreTransitionDescriptor::kMapIndex));
1486 return StoreTransitionDescriptor::kMapIndex;
1487 }
1488
1489 static int VectorIndex() {
1490 if (HasVirtualSlotArg()) {
1491 return VectorStoreTransitionDescriptor::kVirtualSlotVectorIndex;
1492 }
1493 return VectorStoreTransitionDescriptor::kVectorIndex;
1494 }
1495
1496 // Some platforms don't have a slot arg.
1497 static bool HasVirtualSlotArg() {
1498 return SlotRegister().is(no_reg);
1499 }
1500};
1501
1502
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001503class StoreTransitionStub : public HandlerStub {
1504 public:
1505 enum StoreMode {
1506 StoreMapOnly,
1507 StoreMapAndValue,
1508 ExtendStorageAndStoreMapAndValue
1509 };
1510
1511 explicit StoreTransitionStub(Isolate* isolate) : HandlerStub(isolate) {
1512 set_sub_minor_key(StoreModeBits::encode(StoreMapOnly));
1513 }
1514
1515 StoreTransitionStub(Isolate* isolate, FieldIndex index,
1516 Representation representation, StoreMode store_mode)
1517 : HandlerStub(isolate) {
1518 DCHECK(store_mode != StoreMapOnly);
1519 int property_index_key = index.GetFieldAccessStubKey();
1520 uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1521 set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1522 RepresentationBits::encode(repr) |
1523 StoreModeBits::encode(store_mode));
1524 }
1525
1526 FieldIndex index() const {
1527 DCHECK(store_mode() != StoreMapOnly);
1528 int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1529 return FieldIndex::FromFieldAccessStubKey(property_index_key);
1530 }
1531
1532 Representation representation() {
1533 DCHECK(store_mode() != StoreMapOnly);
1534 uint8_t repr = RepresentationBits::decode(sub_minor_key());
1535 return PropertyDetails::DecodeRepresentation(repr);
1536 }
1537
1538 StoreMode store_mode() const {
1539 return StoreModeBits::decode(sub_minor_key());
1540 }
1541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001542 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001543
1544 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001545 Code::Kind kind() const override { return Code::STORE_IC; }
1546 Code::StubType GetStubType() const override { return Code::FAST; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001547
1548 private:
1549 class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1550 class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1551 class StoreModeBits : public BitField<StoreMode, 17, 2> {};
1552
1553 DEFINE_HANDLER_CODE_STUB(StoreTransition, HandlerStub);
1554};
1555
1556
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001557class StoreGlobalStub : public HandlerStub {
1558 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001559 StoreGlobalStub(Isolate* isolate, PropertyCellType type,
1560 Maybe<PropertyCellConstantType> constant_type,
1561 bool check_global)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001562 : HandlerStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 PropertyCellConstantType encoded_constant_type =
1564 constant_type.FromMaybe(PropertyCellConstantType::kSmi);
1565 set_sub_minor_key(CellTypeBits::encode(type) |
1566 ConstantTypeBits::encode(encoded_constant_type) |
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001567 CheckGlobalBits::encode(check_global));
1568 }
1569
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001570 static Handle<HeapObject> property_cell_placeholder(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001571 return isolate->factory()->uninitialized_value();
1572 }
1573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001574 static Handle<HeapObject> global_map_placeholder(Isolate* isolate) {
1575 return isolate->factory()->termination_exception();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001576 }
1577
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001578 Handle<Code> GetCodeCopyFromTemplate(Handle<JSGlobalObject> global,
1579 Handle<PropertyCell> cell) {
1580 Code::FindAndReplacePattern pattern;
1581 if (check_global()) {
1582 pattern.Add(handle(global_map_placeholder(isolate())->map()),
1583 Map::WeakCellForMap(Handle<Map>(global->map())));
1584 }
1585 pattern.Add(handle(property_cell_placeholder(isolate())->map()),
1586 isolate()->factory()->NewWeakCell(cell));
1587 return CodeStub::GetCodeCopy(pattern);
1588 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001589
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001590 Code::Kind kind() const override { return Code::STORE_IC; }
1591
1592 PropertyCellType cell_type() const {
1593 return CellTypeBits::decode(sub_minor_key());
1594 }
1595
1596 PropertyCellConstantType constant_type() const {
1597 DCHECK(PropertyCellType::kConstantType == cell_type());
1598 return ConstantTypeBits::decode(sub_minor_key());
1599 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001600
1601 bool check_global() const { return CheckGlobalBits::decode(sub_minor_key()); }
1602
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001603 Representation representation() {
1604 return Representation::FromKind(
1605 RepresentationBits::decode(sub_minor_key()));
1606 }
1607
1608 void set_representation(Representation r) {
1609 set_sub_minor_key(RepresentationBits::update(sub_minor_key(), r.kind()));
1610 }
1611
1612 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001613 class CellTypeBits : public BitField<PropertyCellType, 0, 2> {};
1614 class ConstantTypeBits : public BitField<PropertyCellConstantType, 2, 2> {};
1615 class RepresentationBits : public BitField<Representation::Kind, 4, 8> {};
1616 class CheckGlobalBits : public BitField<bool, 12, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001617
1618 DEFINE_HANDLER_CODE_STUB(StoreGlobal, HandlerStub);
1619};
1620
1621
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001622class LoadGlobalViaContextStub final : public PlatformCodeStub {
1623 public:
1624 static const int kMaximumDepth = 15;
1625
1626 LoadGlobalViaContextStub(Isolate* isolate, int depth)
1627 : PlatformCodeStub(isolate) {
1628 minor_key_ = DepthBits::encode(depth);
1629 }
1630
1631 int depth() const { return DepthBits::decode(minor_key_); }
1632
1633 private:
1634 class DepthBits : public BitField<int, 0, 4> {};
1635 STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
1636
1637 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadGlobalViaContext);
1638 DEFINE_PLATFORM_CODE_STUB(LoadGlobalViaContext, PlatformCodeStub);
1639};
1640
1641
1642class StoreGlobalViaContextStub final : public PlatformCodeStub {
1643 public:
1644 static const int kMaximumDepth = 15;
1645
1646 StoreGlobalViaContextStub(Isolate* isolate, int depth,
1647 LanguageMode language_mode)
1648 : PlatformCodeStub(isolate) {
1649 minor_key_ =
1650 DepthBits::encode(depth) | LanguageModeBits::encode(language_mode);
1651 }
1652
1653 int depth() const { return DepthBits::decode(minor_key_); }
1654 LanguageMode language_mode() const {
1655 return LanguageModeBits::decode(minor_key_);
1656 }
1657
1658 private:
1659 class DepthBits : public BitField<int, 0, 4> {};
1660 STATIC_ASSERT(DepthBits::kMax == kMaximumDepth);
1661 class LanguageModeBits : public BitField<LanguageMode, 4, 2> {};
1662 STATIC_ASSERT(LANGUAGE_END == 3);
1663
1664 DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreGlobalViaContext);
1665 DEFINE_PLATFORM_CODE_STUB(StoreGlobalViaContext, PlatformCodeStub);
1666};
1667
Ben Murdochda12d292016-06-02 14:46:10 +01001668class CallApiCallbackStub : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001669 public:
Ben Murdochda12d292016-06-02 14:46:10 +01001670 static const int kArgBits = 3;
1671 static const int kArgMax = (1 << kArgBits) - 1;
1672
1673 // CallApiCallbackStub for regular setters and getters.
1674 CallApiCallbackStub(Isolate* isolate, bool is_store, bool call_data_undefined,
1675 bool is_lazy)
1676 : CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store,
1677 call_data_undefined, is_lazy) {}
1678
1679 // CallApiCallbackStub for callback functions.
1680 CallApiCallbackStub(Isolate* isolate, int argc, bool call_data_undefined)
1681 : CallApiCallbackStub(isolate, argc, false, call_data_undefined, false) {}
1682
1683 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
1684 return ApiCallbackDescriptorBase::ForArgs(isolate(), argc());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001685 }
1686
1687 private:
Ben Murdochda12d292016-06-02 14:46:10 +01001688 CallApiCallbackStub(Isolate* isolate, int argc, bool is_store,
1689 bool call_data_undefined, bool is_lazy)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001690 : PlatformCodeStub(isolate) {
Ben Murdochda12d292016-06-02 14:46:10 +01001691 CHECK(0 <= argc && argc <= kArgMax);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001692 minor_key_ = IsStoreBits::encode(is_store) |
1693 CallDataUndefinedBits::encode(call_data_undefined) |
Ben Murdochda12d292016-06-02 14:46:10 +01001694 ArgumentBits::encode(argc) |
Ben Murdoch097c5b22016-05-18 11:27:45 +01001695 IsLazyAccessorBits::encode(is_lazy);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001696 }
1697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001698 bool is_store() const { return IsStoreBits::decode(minor_key_); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001699 bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001700 bool call_data_undefined() const {
1701 return CallDataUndefinedBits::decode(minor_key_);
1702 }
1703 int argc() const { return ArgumentBits::decode(minor_key_); }
1704
1705 class IsStoreBits: public BitField<bool, 0, 1> {};
1706 class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001707 class ArgumentBits : public BitField<int, 2, kArgBits> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001708 class IsLazyAccessorBits : public BitField<bool, 3 + kArgBits, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001709
Ben Murdochda12d292016-06-02 14:46:10 +01001710 DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001711};
1712
1713
1714class CallApiGetterStub : public PlatformCodeStub {
1715 public:
1716 explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1717
1718 DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
1719 DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
1720};
1721
1722
1723class BinaryOpICStub : public HydrogenCodeStub {
1724 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001725 BinaryOpICStub(Isolate* isolate, Token::Value op)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001726 : HydrogenCodeStub(isolate, UNINITIALIZED) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001727 BinaryOpICState state(isolate, op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001728 set_sub_minor_key(state.GetExtraICState());
1729 }
1730
1731 BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
1732 : HydrogenCodeStub(isolate) {
1733 set_sub_minor_key(state.GetExtraICState());
1734 }
1735
1736 static void GenerateAheadOfTime(Isolate* isolate);
1737
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001738 Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001739
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001740 InlineCacheState GetICState() const final { return state().GetICState(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001741
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001742 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001743 return static_cast<ExtraICState>(sub_minor_key());
1744 }
1745
1746 BinaryOpICState state() const {
1747 return BinaryOpICState(isolate(), GetExtraICState());
1748 }
1749
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001750 void PrintState(std::ostream& os) const final; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001751
1752 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1753 static const int kLeft = 0;
1754 static const int kRight = 1;
1755
1756 private:
1757 static void GenerateAheadOfTime(Isolate* isolate,
1758 const BinaryOpICState& state);
1759
1760 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1761 DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
1762};
1763
1764
1765// TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
1766// call support for stubs in Hydrogen.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001767class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001768 public:
1769 BinaryOpICWithAllocationSiteStub(Isolate* isolate,
1770 const BinaryOpICState& state)
1771 : PlatformCodeStub(isolate) {
1772 minor_key_ = state.GetExtraICState();
1773 }
1774
1775 static void GenerateAheadOfTime(Isolate* isolate);
1776
1777 Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
1778 Code::FindAndReplacePattern pattern;
1779 pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
1780 return CodeStub::GetCodeCopy(pattern);
1781 }
1782
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783 Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001784
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001785 InlineCacheState GetICState() const override { return state().GetICState(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001786
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001787 ExtraICState GetExtraICState() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001788 return static_cast<ExtraICState>(minor_key_);
1789 }
1790
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001791 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001792
1793 private:
1794 BinaryOpICState state() const {
1795 return BinaryOpICState(isolate(), static_cast<ExtraICState>(minor_key_));
1796 }
1797
1798 static void GenerateAheadOfTime(Isolate* isolate,
1799 const BinaryOpICState& state);
1800
1801 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1802 DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
1803};
1804
1805
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001806class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001807 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001808 BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
1809 : BinaryOpICStub(isolate, op) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001810
1811 BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
1812 : BinaryOpICStub(isolate, state) {}
1813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001814 Code::Kind GetCodeKind() const final { return Code::STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001815
1816 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1817 static const int kAllocationSite = 0;
1818 static const int kLeft = 1;
1819 static const int kRight = 2;
1820
1821 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1822 DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub);
1823};
1824
1825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001826class StringAddStub final : public HydrogenCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001827 public:
1828 StringAddStub(Isolate* isolate, StringAddFlags flags,
1829 PretenureFlag pretenure_flag)
1830 : HydrogenCodeStub(isolate) {
1831 set_sub_minor_key(StringAddFlagsBits::encode(flags) |
1832 PretenureFlagBits::encode(pretenure_flag));
1833 }
1834
1835 StringAddFlags flags() const {
1836 return StringAddFlagsBits::decode(sub_minor_key());
1837 }
1838
1839 PretenureFlag pretenure_flag() const {
1840 return PretenureFlagBits::decode(sub_minor_key());
1841 }
1842
1843 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1844 static const int kLeft = 0;
1845 static const int kRight = 1;
1846
1847 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001848 class StringAddFlagsBits : public BitField<StringAddFlags, 0, 3> {};
1849 class PretenureFlagBits : public BitField<PretenureFlag, 3, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001850
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001851 void PrintBaseName(std::ostream& os) const override; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001852
1853 DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
1854 DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub);
1855};
1856
1857
1858class CompareICStub : public PlatformCodeStub {
1859 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01001860 CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
1861 CompareICState::State right, CompareICState::State state)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001862 : PlatformCodeStub(isolate) {
1863 DCHECK(Token::IsCompareOp(op));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001864 minor_key_ = OpBits::encode(op - Token::EQ) |
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001865 LeftStateBits::encode(left) | RightStateBits::encode(right) |
1866 StateBits::encode(state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001867 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001868
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001869 void set_known_map(Handle<Map> map) { known_map_ = map; }
1870
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001871 InlineCacheState GetICState() const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001872
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001873 Token::Value op() const {
1874 return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001875 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001876
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001877 CompareICState::State left() const {
1878 return LeftStateBits::decode(minor_key_);
1879 }
1880 CompareICState::State right() const {
1881 return RightStateBits::decode(minor_key_);
1882 }
1883 CompareICState::State state() const { return StateBits::decode(minor_key_); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001884
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001885 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001886 Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001887
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001888 void GenerateBooleans(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001889 void GenerateSmis(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001890 void GenerateNumbers(MacroAssembler* masm);
1891 void GenerateInternalizedStrings(MacroAssembler* masm);
Ben Murdoch257744e2011-11-30 15:57:28 +00001892 void GenerateStrings(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001893 void GenerateUniqueNames(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001894 void GenerateReceivers(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001895 void GenerateMiss(MacroAssembler* masm);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001896 void GenerateKnownReceivers(MacroAssembler* masm);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001897 void GenerateGeneric(MacroAssembler* masm);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001898
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001899 bool strict() const { return op() == Token::EQ_STRICT; }
1900 Condition GetCondition() const;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001901
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001902 void AddToSpecialCache(Handle<Code> new_object) override;
1903 bool FindCodeInSpecialCache(Code** code_out) override;
1904 bool UseSpecialCache() override {
1905 return state() == CompareICState::KNOWN_RECEIVER;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001906 }
1907
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001908 class OpBits : public BitField<int, 0, 3> {};
Ben Murdoch097c5b22016-05-18 11:27:45 +01001909 class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
1910 class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
1911 class StateBits : public BitField<CompareICState::State, 11, 4> {};
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001912
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001913 Handle<Map> known_map_;
1914
1915 DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1916 DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001917};
1918
1919
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001920class CEntryStub : public PlatformCodeStub {
1921 public:
1922 CEntryStub(Isolate* isolate, int result_size,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001923 SaveFPRegsMode save_doubles = kDontSaveFPRegs,
1924 ArgvMode argv_mode = kArgvOnStack)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001925 : PlatformCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001926 minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) |
1927 ArgvMode::encode(argv_mode == kArgvInRegister);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001928 DCHECK(result_size == 1 || result_size == 2 || result_size == 3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001929 minor_key_ = ResultSizeBits::update(minor_key_, result_size);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001930 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001931
1932 // The version of this stub that doesn't save doubles is generated ahead of
1933 // time, so it's OK to call it from other stubs that can't cope with GC during
1934 // their code generation. On machines that always have gp registers (x64) we
1935 // can generate both variants ahead of time.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001936 static void GenerateAheadOfTime(Isolate* isolate);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001937
1938 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001939 bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001940 bool argv_in_register() const { return ArgvMode::decode(minor_key_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001941 int result_size() const { return ResultSizeBits::decode(minor_key_); }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001942
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001943 bool NeedsImmovableCode() override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001944
1945 class SaveDoublesBits : public BitField<bool, 0, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001946 class ArgvMode : public BitField<bool, 1, 1> {};
1947 class ResultSizeBits : public BitField<int, 2, 3> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001948
1949 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1950 DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001951};
1952
1953
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001954class JSEntryStub : public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001955 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001956 JSEntryStub(Isolate* isolate, StackFrame::Type type)
1957 : PlatformCodeStub(isolate) {
1958 DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT);
1959 minor_key_ = StackFrameTypeBits::encode(type);
1960 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001961
1962 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001963 void FinishCode(Handle<Code> code) override;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001964
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001965 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001966 os << (type() == StackFrame::ENTRY ? "JSEntryStub"
1967 : "JSConstructEntryStub");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001968 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001969
1970 StackFrame::Type type() const {
1971 return StackFrameTypeBits::decode(minor_key_);
1972 }
1973
1974 class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {};
1975
1976 int handler_offset_;
1977
1978 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1979 DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001980};
1981
1982
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001983class RegExpExecStub: public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001984 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001985 explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001986
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001987 DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
1988 DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001989};
1990
1991
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001992class RegExpConstructResultStub final : public HydrogenCodeStub {
Ben Murdochb0fe1622011-05-05 13:52:32 +01001993 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001994 explicit RegExpConstructResultStub(Isolate* isolate)
1995 : HydrogenCodeStub(isolate) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001996
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001997 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1998 static const int kLength = 0;
1999 static const int kIndex = 1;
2000 static const int kInput = 2;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002001
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002002 DEFINE_CALL_INTERFACE_DESCRIPTOR(RegExpConstructResult);
2003 DEFINE_HYDROGEN_CODE_STUB(RegExpConstructResult, HydrogenCodeStub);
Ben Murdochb0fe1622011-05-05 13:52:32 +01002004};
2005
2006
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002007// TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
2008class CallConstructStub final : public PlatformCodeStub {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002009 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002010 explicit CallConstructStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002011
2012 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
2013 DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002014};
2015
2016
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002017enum StringIndexFlags {
2018 // Accepts smis or heap numbers.
2019 STRING_INDEX_IS_NUMBER,
2020
2021 // Accepts smis or heap numbers that are valid array indices
2022 // (ECMA-262 15.4). Invalid indices are reported as being out of
2023 // range.
2024 STRING_INDEX_IS_ARRAY_INDEX
2025};
2026
2027
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002028enum ReceiverCheckMode {
2029 // We don't know anything about the receiver.
2030 RECEIVER_IS_UNKNOWN,
2031
2032 // We know the receiver is a string.
2033 RECEIVER_IS_STRING
2034};
2035
2036
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002037enum EmbedMode {
2038 // The code being generated is part of an IC handler, which may MISS
2039 // to an IC in failure cases.
2040 PART_OF_IC_HANDLER,
2041
2042 NOT_PART_OF_IC_HANDLER
2043};
2044
2045
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002046// Generates code implementing String.prototype.charCodeAt.
2047//
2048// Only supports the case when the receiver is a string and the index
2049// is a number (smi or heap number) that is a valid index into the
2050// string. Additional index constraints are specified by the
2051// flags. Otherwise, bails out to the provided labels.
2052//
2053// Register usage: |object| may be changed to another string in a way
2054// that doesn't affect charCodeAt/charAt semantics, |index| is
2055// preserved, |scratch| and |result| are clobbered.
2056class StringCharCodeAtGenerator {
2057 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002058 StringCharCodeAtGenerator(Register object, Register index, Register result,
2059 Label* receiver_not_string, Label* index_not_number,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002060 Label* index_out_of_range,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002061 StringIndexFlags index_flags,
2062 ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002063 : object_(object),
2064 index_(index),
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002065 result_(result),
2066 receiver_not_string_(receiver_not_string),
2067 index_not_number_(index_not_number),
2068 index_out_of_range_(index_out_of_range),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002069 index_flags_(index_flags),
2070 check_mode_(check_mode) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002071 DCHECK(!result_.is(object_));
2072 DCHECK(!result_.is(index_));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002073 }
2074
2075 // Generates the fast case code. On the fallthrough path |result|
2076 // register contains the result.
2077 void GenerateFast(MacroAssembler* masm);
2078
2079 // Generates the slow case code. Must not be naturally
2080 // reachable. Expected to be put after a ret instruction (e.g., in
2081 // deferred code). Always jumps back to the fast case.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002082 void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002083 const RuntimeCallHelper& call_helper);
2084
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002085 // Skip handling slow case and directly jump to bailout.
2086 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2087 masm->bind(&index_not_smi_);
2088 masm->bind(&call_runtime_);
2089 masm->jmp(bailout);
2090 }
2091
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002092 private:
2093 Register object_;
2094 Register index_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002095 Register result_;
2096
2097 Label* receiver_not_string_;
2098 Label* index_not_number_;
2099 Label* index_out_of_range_;
2100
2101 StringIndexFlags index_flags_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002102 ReceiverCheckMode check_mode_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002103
2104 Label call_runtime_;
2105 Label index_not_smi_;
2106 Label got_smi_index_;
2107 Label exit_;
2108
2109 DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
2110};
2111
2112
2113// Generates code for creating a one-char string from a char code.
2114class StringCharFromCodeGenerator {
2115 public:
2116 StringCharFromCodeGenerator(Register code,
2117 Register result)
2118 : code_(code),
2119 result_(result) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002120 DCHECK(!code_.is(result_));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002121 }
2122
2123 // Generates the fast case code. On the fallthrough path |result|
2124 // register contains the result.
2125 void GenerateFast(MacroAssembler* masm);
2126
2127 // Generates the slow case code. Must not be naturally
2128 // reachable. Expected to be put after a ret instruction (e.g., in
2129 // deferred code). Always jumps back to the fast case.
2130 void GenerateSlow(MacroAssembler* masm,
2131 const RuntimeCallHelper& call_helper);
2132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002133 // Skip handling slow case and directly jump to bailout.
2134 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2135 masm->bind(&slow_case_);
2136 masm->jmp(bailout);
2137 }
2138
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002139 private:
2140 Register code_;
2141 Register result_;
2142
2143 Label slow_case_;
2144 Label exit_;
2145
2146 DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator);
2147};
2148
2149
2150// Generates code implementing String.prototype.charAt.
2151//
2152// Only supports the case when the receiver is a string and the index
2153// is a number (smi or heap number) that is a valid index into the
2154// string. Additional index constraints are specified by the
2155// flags. Otherwise, bails out to the provided labels.
2156//
2157// Register usage: |object| may be changed to another string in a way
2158// that doesn't affect charCodeAt/charAt semantics, |index| is
2159// preserved, |scratch1|, |scratch2|, and |result| are clobbered.
2160class StringCharAtGenerator {
2161 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002162 StringCharAtGenerator(Register object, Register index, Register scratch,
2163 Register result, Label* receiver_not_string,
2164 Label* index_not_number, Label* index_out_of_range,
2165 StringIndexFlags index_flags,
2166 ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
2167 : char_code_at_generator_(object, index, scratch, receiver_not_string,
2168 index_not_number, index_out_of_range,
2169 index_flags, check_mode),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002170 char_from_code_generator_(scratch, result) {}
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002171
2172 // Generates the fast case code. On the fallthrough path |result|
2173 // register contains the result.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002174 void GenerateFast(MacroAssembler* masm) {
2175 char_code_at_generator_.GenerateFast(masm);
2176 char_from_code_generator_.GenerateFast(masm);
2177 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002178
2179 // Generates the slow case code. Must not be naturally
2180 // reachable. Expected to be put after a ret instruction (e.g., in
2181 // deferred code). Always jumps back to the fast case.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002182 void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002183 const RuntimeCallHelper& call_helper) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002184 char_code_at_generator_.GenerateSlow(masm, embed_mode, call_helper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002185 char_from_code_generator_.GenerateSlow(masm, call_helper);
2186 }
2187
2188 // Skip handling slow case and directly jump to bailout.
2189 void SkipSlow(MacroAssembler* masm, Label* bailout) {
2190 char_code_at_generator_.SkipSlow(masm, bailout);
2191 char_from_code_generator_.SkipSlow(masm, bailout);
2192 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002193
2194 private:
2195 StringCharCodeAtGenerator char_code_at_generator_;
2196 StringCharFromCodeGenerator char_from_code_generator_;
2197
2198 DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator);
2199};
2200
Ben Murdoch086aeea2011-05-13 15:57:08 +01002201
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002202class LoadDictionaryElementStub : public HydrogenCodeStub {
Ben Murdoch086aeea2011-05-13 15:57:08 +01002203 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002204 explicit LoadDictionaryElementStub(Isolate* isolate, const LoadICState& state)
2205 : HydrogenCodeStub(isolate) {
2206 minor_key_ = state.GetExtraICState();
2207 }
Ben Murdoch086aeea2011-05-13 15:57:08 +01002208
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002209 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
2210 return LoadWithVectorDescriptor(isolate());
2211 }
2212
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002213 DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
Ben Murdoch086aeea2011-05-13 15:57:08 +01002214};
2215
Ben Murdoch257744e2011-11-30 15:57:28 +00002216
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002217class KeyedLoadGenericStub : public HydrogenCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00002218 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002219 explicit KeyedLoadGenericStub(Isolate* isolate, const LoadICState& state)
2220 : HydrogenCodeStub(isolate) {
2221 minor_key_ = state.GetExtraICState();
2222 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002224 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2225 InlineCacheState GetICState() const override { return GENERIC; }
Ben Murdoch257744e2011-11-30 15:57:28 +00002226
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002227 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002228
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002229 DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
Ben Murdoch257744e2011-11-30 15:57:28 +00002230};
2231
2232
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002233class LoadICTrampolineStub : public PlatformCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00002234 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002235 LoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
2236 : PlatformCodeStub(isolate) {
2237 minor_key_ = state.GetExtraICState();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002238 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002239
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002240 Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002241
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002242 InlineCacheState GetICState() const final { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002244 ExtraICState GetExtraICState() const final {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002245 return static_cast<ExtraICState>(minor_key_);
2246 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002247
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002248 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002249 LoadICState state() const {
2250 return LoadICState(static_cast<ExtraICState>(minor_key_));
2251 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002252
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002253 DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002254 DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub);
Ben Murdoch257744e2011-11-30 15:57:28 +00002255};
2256
2257
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002258class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
2259 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002260 explicit KeyedLoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
2261 : LoadICTrampolineStub(isolate, state) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002262
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002263 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002264
2265 DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub);
2266};
2267
2268
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002269class VectorStoreICTrampolineStub : public PlatformCodeStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002270 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002271 VectorStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2272 : PlatformCodeStub(isolate) {
2273 minor_key_ = state.GetExtraICState();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002274 }
2275
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002276 Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002277
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002278 InlineCacheState GetICState() const final { return GENERIC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002279
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002280 ExtraICState GetExtraICState() const final {
2281 return static_cast<ExtraICState>(minor_key_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002282 }
2283
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002284 protected:
2285 StoreICState state() const {
2286 return StoreICState(static_cast<ExtraICState>(minor_key_));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002287 }
2288
2289 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002290 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreICTrampoline);
2291 DEFINE_PLATFORM_CODE_STUB(VectorStoreICTrampoline, PlatformCodeStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002292};
2293
2294
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002295class VectorKeyedStoreICTrampolineStub : public VectorStoreICTrampolineStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002296 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002297 VectorKeyedStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2298 : VectorStoreICTrampolineStub(isolate, state) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002299
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002300 Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002301
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002302 DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreICTrampoline,
2303 VectorStoreICTrampolineStub);
2304};
2305
2306
2307class CallICTrampolineStub : public PlatformCodeStub {
2308 public:
2309 CallICTrampolineStub(Isolate* isolate, const CallICState& state)
2310 : PlatformCodeStub(isolate) {
2311 minor_key_ = state.GetExtraICState();
2312 }
2313
2314 Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
2315
2316 InlineCacheState GetICState() const final { return GENERIC; }
2317
2318 ExtraICState GetExtraICState() const final {
2319 return static_cast<ExtraICState>(minor_key_);
2320 }
2321
2322 protected:
2323 CallICState state() const {
2324 return CallICState(static_cast<ExtraICState>(minor_key_));
2325 }
2326
2327 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
2328 DEFINE_PLATFORM_CODE_STUB(CallICTrampoline, PlatformCodeStub);
2329};
2330
2331
2332class LoadICStub : public PlatformCodeStub {
2333 public:
2334 explicit LoadICStub(Isolate* isolate, const LoadICState& state)
2335 : PlatformCodeStub(isolate) {
2336 minor_key_ = state.GetExtraICState();
2337 }
2338
2339 void GenerateForTrampoline(MacroAssembler* masm);
2340
2341 Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
2342 InlineCacheState GetICState() const final { return GENERIC; }
2343 ExtraICState GetExtraICState() const final {
2344 return static_cast<ExtraICState>(minor_key_);
2345 }
2346
2347 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2348 DEFINE_PLATFORM_CODE_STUB(LoadIC, PlatformCodeStub);
2349
2350 protected:
2351 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2352};
2353
2354
2355class KeyedLoadICStub : public PlatformCodeStub {
2356 public:
2357 explicit KeyedLoadICStub(Isolate* isolate, const LoadICState& state)
2358 : PlatformCodeStub(isolate) {
2359 minor_key_ = state.GetExtraICState();
2360 }
2361
2362 void GenerateForTrampoline(MacroAssembler* masm);
2363
2364 Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2365 InlineCacheState GetICState() const final { return GENERIC; }
2366 ExtraICState GetExtraICState() const final {
2367 return static_cast<ExtraICState>(minor_key_);
2368 }
2369
2370 DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2371 DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
2372
2373 protected:
2374 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2375};
2376
2377
2378class VectorStoreICStub : public PlatformCodeStub {
2379 public:
2380 VectorStoreICStub(Isolate* isolate, const StoreICState& state)
2381 : PlatformCodeStub(isolate) {
2382 minor_key_ = state.GetExtraICState();
2383 }
2384
2385 void GenerateForTrampoline(MacroAssembler* masm);
2386
2387 Code::Kind GetCodeKind() const final { return Code::STORE_IC; }
2388 InlineCacheState GetICState() const final { return GENERIC; }
2389 ExtraICState GetExtraICState() const final {
2390 return static_cast<ExtraICState>(minor_key_);
2391 }
2392
2393 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2394 DEFINE_PLATFORM_CODE_STUB(VectorStoreIC, PlatformCodeStub);
2395
2396 protected:
2397 void GenerateImpl(MacroAssembler* masm, bool in_frame);
2398};
2399
2400
2401class VectorKeyedStoreICStub : public PlatformCodeStub {
2402 public:
2403 VectorKeyedStoreICStub(Isolate* isolate, const StoreICState& state)
2404 : PlatformCodeStub(isolate) {
2405 minor_key_ = state.GetExtraICState();
2406 }
2407
2408 void GenerateForTrampoline(MacroAssembler* masm);
2409
2410 Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
2411 InlineCacheState GetICState() const final { return GENERIC; }
2412 ExtraICState GetExtraICState() const final {
2413 return static_cast<ExtraICState>(minor_key_);
2414 }
2415
2416 DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2417 DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);
2418
2419 protected:
2420 void GenerateImpl(MacroAssembler* masm, bool in_frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002421};
2422
2423
2424class DoubleToIStub : public PlatformCodeStub {
2425 public:
2426 DoubleToIStub(Isolate* isolate, Register source, Register destination,
2427 int offset, bool is_truncating, bool skip_fastpath = false)
2428 : PlatformCodeStub(isolate) {
2429 minor_key_ = SourceRegisterBits::encode(source.code()) |
2430 DestinationRegisterBits::encode(destination.code()) |
2431 OffsetBits::encode(offset) |
2432 IsTruncatingBits::encode(is_truncating) |
2433 SkipFastPathBits::encode(skip_fastpath) |
2434 SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
2435 }
2436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002437 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002438
2439 private:
2440 Register source() const {
2441 return Register::from_code(SourceRegisterBits::decode(minor_key_));
2442 }
2443 Register destination() const {
2444 return Register::from_code(DestinationRegisterBits::decode(minor_key_));
2445 }
2446 bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); }
2447 bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); }
2448 int offset() const { return OffsetBits::decode(minor_key_); }
2449
2450 static const int kBitsPerRegisterNumber = 6;
2451 STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
2452 class SourceRegisterBits:
2453 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT
2454 class DestinationRegisterBits:
2455 public BitField<int, kBitsPerRegisterNumber,
2456 kBitsPerRegisterNumber> {}; // NOLINT
2457 class IsTruncatingBits:
2458 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT
2459 class OffsetBits:
2460 public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT
2461 class SkipFastPathBits:
2462 public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT
2463 class SSE3Bits:
2464 public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {}; // NOLINT
2465
2466 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2467 DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
2468};
2469
2470
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002471class ScriptContextFieldStub : public HandlerStub {
2472 public:
2473 ScriptContextFieldStub(Isolate* isolate,
2474 const ScriptContextTable::LookupResult* lookup_result)
2475 : HandlerStub(isolate) {
2476 DCHECK(Accepted(lookup_result));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002477 STATIC_ASSERT(kContextIndexBits + kSlotIndexBits <= kSubMinorKeyBits);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002478 set_sub_minor_key(ContextIndexBits::encode(lookup_result->context_index) |
2479 SlotIndexBits::encode(lookup_result->slot_index));
2480 }
2481
2482 int context_index() const {
2483 return ContextIndexBits::decode(sub_minor_key());
2484 }
2485
2486 int slot_index() const { return SlotIndexBits::decode(sub_minor_key()); }
2487
2488 static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
2489 return ContextIndexBits::is_valid(lookup_result->context_index) &&
2490 SlotIndexBits::is_valid(lookup_result->slot_index);
2491 }
2492
2493 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002494 static const int kContextIndexBits = 9;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002495 static const int kSlotIndexBits = 13;
2496 class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
2497 class SlotIndexBits
2498 : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
2499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002500 Code::StubType GetStubType() const override { return Code::FAST; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002501
2502 DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, HandlerStub);
2503};
2504
2505
2506class LoadScriptContextFieldStub : public ScriptContextFieldStub {
2507 public:
2508 LoadScriptContextFieldStub(
2509 Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2510 : ScriptContextFieldStub(isolate, lookup_result) {}
2511
2512 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002513 Code::Kind kind() const override { return Code::LOAD_IC; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002514
2515 DEFINE_HANDLER_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
2516};
2517
2518
2519class StoreScriptContextFieldStub : public ScriptContextFieldStub {
2520 public:
2521 StoreScriptContextFieldStub(
2522 Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2523 : ScriptContextFieldStub(isolate, lookup_result) {}
2524
2525 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002526 Code::Kind kind() const override { return Code::STORE_IC; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002527
2528 DEFINE_HANDLER_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
2529};
2530
2531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002532class LoadFastElementStub : public HandlerStub {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002533 public:
2534 LoadFastElementStub(Isolate* isolate, bool is_js_array,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002535 ElementsKind elements_kind,
2536 bool convert_hole_to_undefined = false)
2537 : HandlerStub(isolate) {
2538 set_sub_minor_key(
2539 ElementsKindBits::encode(elements_kind) |
2540 IsJSArrayBits::encode(is_js_array) |
2541 CanConvertHoleToUndefined::encode(convert_hole_to_undefined));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002542 }
2543
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002544 Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
2545
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002546 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002547 bool convert_hole_to_undefined() const {
2548 return CanConvertHoleToUndefined::decode(sub_minor_key());
2549 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002550
2551 ElementsKind elements_kind() const {
2552 return ElementsKindBits::decode(sub_minor_key());
2553 }
2554
2555 private:
2556 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2557 class IsJSArrayBits: public BitField<bool, 8, 1> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002558 class CanConvertHoleToUndefined : public BitField<bool, 9, 1> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002560 DEFINE_HANDLER_CODE_STUB(LoadFastElement, HandlerStub);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002561};
2562
2563
2564class StoreFastElementStub : public HydrogenCodeStub {
2565 public:
2566 StoreFastElementStub(Isolate* isolate, bool is_js_array,
2567 ElementsKind elements_kind, KeyedAccessStoreMode mode)
2568 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002569 set_sub_minor_key(CommonStoreModeBits::encode(mode) |
2570 ElementsKindBits::encode(elements_kind) |
2571 IsJSArrayBits::encode(is_js_array));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002572 }
2573
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002574 static void GenerateAheadOfTime(Isolate* isolate);
2575
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002576 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2577
2578 ElementsKind elements_kind() const {
2579 return ElementsKindBits::decode(sub_minor_key());
2580 }
2581
2582 KeyedAccessStoreMode store_mode() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002583 return CommonStoreModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002584 }
2585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002586 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
2587 return VectorStoreICDescriptor(isolate());
2588 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002589
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002590 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
2591
2592 private:
2593 class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
2594 class IsJSArrayBits : public BitField<bool, 11, 1> {};
2595
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002596 DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub);
2597};
2598
2599
2600class TransitionElementsKindStub : public HydrogenCodeStub {
2601 public:
2602 TransitionElementsKindStub(Isolate* isolate,
2603 ElementsKind from_kind,
2604 ElementsKind to_kind,
2605 bool is_js_array) : HydrogenCodeStub(isolate) {
2606 set_sub_minor_key(FromKindBits::encode(from_kind) |
2607 ToKindBits::encode(to_kind) |
2608 IsJSArrayBits::encode(is_js_array));
2609 }
2610
2611 ElementsKind from_kind() const {
2612 return FromKindBits::decode(sub_minor_key());
2613 }
2614
2615 ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); }
2616
2617 bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2618
2619 private:
2620 class FromKindBits: public BitField<ElementsKind, 8, 8> {};
2621 class ToKindBits: public BitField<ElementsKind, 0, 8> {};
2622 class IsJSArrayBits: public BitField<bool, 16, 1> {};
2623
2624 DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind);
2625 DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub);
2626};
2627
Ben Murdochda12d292016-06-02 14:46:10 +01002628class AllocateHeapNumberStub : public TurboFanCodeStub {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002629 public:
2630 explicit AllocateHeapNumberStub(Isolate* isolate)
Ben Murdochda12d292016-06-02 14:46:10 +01002631 : TurboFanCodeStub(isolate) {}
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002632
Ben Murdochda12d292016-06-02 14:46:10 +01002633 void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
2634 void GenerateAssembly(compiler::CodeStubAssembler* assembler) const override;
2635
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002636 DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
Ben Murdochda12d292016-06-02 14:46:10 +01002637 DEFINE_CODE_STUB(AllocateHeapNumber, TurboFanCodeStub);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002638};
2639
Ben Murdochda12d292016-06-02 14:46:10 +01002640class AllocateMutableHeapNumberStub : public TurboFanCodeStub {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002641 public:
2642 explicit AllocateMutableHeapNumberStub(Isolate* isolate)
Ben Murdochda12d292016-06-02 14:46:10 +01002643 : TurboFanCodeStub(isolate) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002644
Ben Murdochda12d292016-06-02 14:46:10 +01002645 void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
2646 void GenerateAssembly(compiler::CodeStubAssembler* assembler) const override;
2647
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002648 DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateMutableHeapNumber);
Ben Murdochda12d292016-06-02 14:46:10 +01002649 DEFINE_CODE_STUB(AllocateMutableHeapNumber, TurboFanCodeStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002650};
2651
Ben Murdochda12d292016-06-02 14:46:10 +01002652#define SIMD128_ALLOC_STUB(TYPE, Type, type, lane_count, lane_type) \
2653 class Allocate##Type##Stub : public TurboFanCodeStub { \
2654 public: \
2655 explicit Allocate##Type##Stub(Isolate* isolate) \
2656 : TurboFanCodeStub(isolate) {} \
2657 \
2658 void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
2659 void GenerateAssembly( \
2660 compiler::CodeStubAssembler* assembler) const override; \
2661 \
2662 DEFINE_CALL_INTERFACE_DESCRIPTOR(Allocate##Type); \
2663 DEFINE_CODE_STUB(Allocate##Type, TurboFanCodeStub); \
2664 };
2665SIMD128_TYPES(SIMD128_ALLOC_STUB)
2666#undef SIMD128_ALLOC_STUB
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002667
2668class AllocateInNewSpaceStub final : public HydrogenCodeStub {
2669 public:
2670 explicit AllocateInNewSpaceStub(Isolate* isolate)
2671 : HydrogenCodeStub(isolate) {}
2672
2673 private:
2674 DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateInNewSpace);
2675 DEFINE_HYDROGEN_CODE_STUB(AllocateInNewSpace, HydrogenCodeStub);
2676};
2677
2678
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002679class ArrayConstructorStubBase : public HydrogenCodeStub {
2680 public:
2681 ArrayConstructorStubBase(Isolate* isolate,
2682 ElementsKind kind,
2683 AllocationSiteOverrideMode override_mode)
2684 : HydrogenCodeStub(isolate) {
2685 // It only makes sense to override local allocation site behavior
2686 // if there is a difference between the global allocation site policy
2687 // for an ElementsKind and the desired usage of the stub.
2688 DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
2689 AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
2690 set_sub_minor_key(ElementsKindBits::encode(kind) |
2691 AllocationSiteOverrideModeBits::encode(override_mode));
2692 }
2693
2694 ElementsKind elements_kind() const {
2695 return ElementsKindBits::decode(sub_minor_key());
2696 }
2697
2698 AllocationSiteOverrideMode override_mode() const {
2699 return AllocationSiteOverrideModeBits::decode(sub_minor_key());
2700 }
2701
2702 static void GenerateStubsAheadOfTime(Isolate* isolate);
2703
2704 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2705 static const int kConstructor = 0;
2706 static const int kAllocationSite = 1;
2707
2708 protected:
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002709 std::ostream& BasePrintName(std::ostream& os,
2710 const char* name) const; // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002711
2712 private:
2713 // Ensure data fits within available bits.
2714 STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
2715
2716 class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2717 class AllocationSiteOverrideModeBits: public
2718 BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
2719
2720 DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub);
2721};
2722
2723
2724class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
2725 public:
2726 ArrayNoArgumentConstructorStub(
2727 Isolate* isolate,
2728 ElementsKind kind,
2729 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2730 : ArrayConstructorStubBase(isolate, kind, override_mode) {
2731 }
2732
2733 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002734 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002735 BasePrintName(os, "ArrayNoArgumentConstructorStub");
2736 }
2737
2738 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructorConstantArgCount);
2739 DEFINE_HYDROGEN_CODE_STUB(ArrayNoArgumentConstructor,
2740 ArrayConstructorStubBase);
2741};
2742
2743
2744class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
2745 public:
2746 ArraySingleArgumentConstructorStub(
2747 Isolate* isolate,
2748 ElementsKind kind,
2749 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2750 : ArrayConstructorStubBase(isolate, kind, override_mode) {
2751 }
2752
2753 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002754 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002755 BasePrintName(os, "ArraySingleArgumentConstructorStub");
2756 }
2757
2758 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2759 DEFINE_HYDROGEN_CODE_STUB(ArraySingleArgumentConstructor,
2760 ArrayConstructorStubBase);
2761};
2762
2763
2764class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
2765 public:
2766 ArrayNArgumentsConstructorStub(
2767 Isolate* isolate,
2768 ElementsKind kind,
2769 AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2770 : ArrayConstructorStubBase(isolate, kind, override_mode) {
2771 }
2772
2773 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002774 void PrintName(std::ostream& os) const override { // NOLINT
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002775 BasePrintName(os, "ArrayNArgumentsConstructorStub");
2776 }
2777
2778 DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2779 DEFINE_HYDROGEN_CODE_STUB(ArrayNArgumentsConstructor,
2780 ArrayConstructorStubBase);
2781};
2782
2783
2784class InternalArrayConstructorStubBase : public HydrogenCodeStub {
2785 public:
2786 InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind)
2787 : HydrogenCodeStub(isolate) {
2788 set_sub_minor_key(ElementsKindBits::encode(kind));
2789 }
2790
2791 static void GenerateStubsAheadOfTime(Isolate* isolate);
2792
2793 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2794 static const int kConstructor = 0;
2795
2796 ElementsKind elements_kind() const {
2797 return ElementsKindBits::decode(sub_minor_key());
2798 }
2799
2800 private:
2801 class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
2802
2803 DEFINE_CODE_STUB_BASE(InternalArrayConstructorStubBase, HydrogenCodeStub);
2804};
2805
2806
2807class InternalArrayNoArgumentConstructorStub : public
2808 InternalArrayConstructorStubBase {
2809 public:
2810 InternalArrayNoArgumentConstructorStub(Isolate* isolate,
2811 ElementsKind kind)
2812 : InternalArrayConstructorStubBase(isolate, kind) { }
2813
2814 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructorConstantArgCount);
2815 DEFINE_HYDROGEN_CODE_STUB(InternalArrayNoArgumentConstructor,
2816 InternalArrayConstructorStubBase);
2817};
2818
2819
2820class InternalArraySingleArgumentConstructorStub : public
2821 InternalArrayConstructorStubBase {
2822 public:
2823 InternalArraySingleArgumentConstructorStub(Isolate* isolate,
2824 ElementsKind kind)
2825 : InternalArrayConstructorStubBase(isolate, kind) { }
2826
2827 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2828 DEFINE_HYDROGEN_CODE_STUB(InternalArraySingleArgumentConstructor,
2829 InternalArrayConstructorStubBase);
2830};
2831
2832
2833class InternalArrayNArgumentsConstructorStub : public
2834 InternalArrayConstructorStubBase {
2835 public:
2836 InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind)
2837 : InternalArrayConstructorStubBase(isolate, kind) { }
2838
2839 DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2840 DEFINE_HYDROGEN_CODE_STUB(InternalArrayNArgumentsConstructor,
2841 InternalArrayConstructorStubBase);
2842};
2843
2844
2845class StoreElementStub : public PlatformCodeStub {
2846 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002847 StoreElementStub(Isolate* isolate, ElementsKind elements_kind,
2848 KeyedAccessStoreMode mode)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002849 : PlatformCodeStub(isolate) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01002850 // TODO(jkummerow): Rename this stub to StoreSlowElementStub,
2851 // drop elements_kind parameter.
2852 DCHECK_EQ(DICTIONARY_ELEMENTS, elements_kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002853 minor_key_ = ElementsKindBits::encode(elements_kind) |
2854 CommonStoreModeBits::encode(mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002855 }
2856
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002857 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
2858 return VectorStoreICDescriptor(isolate());
2859 }
2860
2861 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
2862
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002863 private:
2864 ElementsKind elements_kind() const {
2865 return ElementsKindBits::decode(minor_key_);
2866 }
2867
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002868 class ElementsKindBits : public BitField<ElementsKind, 3, 8> {};
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002869
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002870 DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
2871};
2872
Ben Murdochda12d292016-06-02 14:46:10 +01002873class ToBooleanICStub : public HydrogenCodeStub {
Ben Murdoch257744e2011-11-30 15:57:28 +00002874 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002875 enum Type {
2876 UNDEFINED,
2877 BOOLEAN,
2878 NULL_TYPE,
2879 SMI,
2880 SPEC_OBJECT,
2881 STRING,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002882 SYMBOL,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002883 HEAP_NUMBER,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002884 SIMD_VALUE,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002885 NUMBER_OF_TYPES
2886 };
2887
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002888 // At most 16 different types can be distinguished, because the Code object
2889 // only has room for two bytes to hold a set of these types. :-P
2890 STATIC_ASSERT(NUMBER_OF_TYPES <= 16);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002891
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002892 class Types : public EnumSet<Type, uint16_t> {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002893 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002894 Types() : EnumSet<Type, uint16_t>(0) {}
2895 explicit Types(uint16_t bits) : EnumSet<Type, uint16_t>(bits) {}
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002896
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002897 bool UpdateStatus(Handle<Object> object);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002898 bool NeedsMap() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002899 bool CanBeUndetectable() const {
Ben Murdochda12d292016-06-02 14:46:10 +01002900 return Contains(ToBooleanICStub::SPEC_OBJECT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002901 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002902 bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002903
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002904 static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002905 };
2906
Ben Murdochda12d292016-06-02 14:46:10 +01002907 ToBooleanICStub(Isolate* isolate, ExtraICState state)
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002908 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002909 set_sub_minor_key(TypesBits::encode(static_cast<uint16_t>(state)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002910 }
Ben Murdoch257744e2011-11-30 15:57:28 +00002911
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002912 bool UpdateStatus(Handle<Object> object);
2913 Types types() const { return Types(TypesBits::decode(sub_minor_key())); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002914
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002915 Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
2916 void PrintState(std::ostream& os) const override; // NOLINT
Ben Murdoch257744e2011-11-30 15:57:28 +00002917
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002918 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002919
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002920 static Handle<Code> GetUninitialized(Isolate* isolate) {
Ben Murdochda12d292016-06-02 14:46:10 +01002921 return ToBooleanICStub(isolate, UNINITIALIZED).GetCode();
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002922 }
2923
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002924 ExtraICState GetExtraICState() const override { return types().ToIntegral(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002925
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002926 InlineCacheState GetICState() const override {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002927 if (types().IsEmpty()) {
2928 return ::v8::internal::UNINITIALIZED;
2929 } else {
2930 return MONOMORPHIC;
2931 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002932 }
2933
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002934 private:
Ben Murdochda12d292016-06-02 14:46:10 +01002935 ToBooleanICStub(Isolate* isolate, InitializationState init_state)
2936 : HydrogenCodeStub(isolate, init_state) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002937
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002938 class TypesBits : public BitField<uint16_t, 0, NUMBER_OF_TYPES> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002939
Ben Murdochda12d292016-06-02 14:46:10 +01002940 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
2941 DEFINE_HYDROGEN_CODE_STUB(ToBooleanIC, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002942};
2943
Ben Murdochda12d292016-06-02 14:46:10 +01002944std::ostream& operator<<(std::ostream& os, const ToBooleanICStub::Types& t);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002945
2946class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002947 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002948 ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
2949 ElementsKind to_kind, bool is_jsarray,
2950 KeyedAccessStoreMode store_mode)
2951 : HydrogenCodeStub(isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002952 set_sub_minor_key(CommonStoreModeBits::encode(store_mode) |
2953 FromBits::encode(from_kind) | ToBits::encode(to_kind) |
2954 IsJSArrayBits::encode(is_jsarray));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002955 }
2956
2957 ElementsKind from_kind() const { return FromBits::decode(sub_minor_key()); }
2958 ElementsKind to_kind() const { return ToBits::decode(sub_minor_key()); }
2959 bool is_jsarray() const { return IsJSArrayBits::decode(sub_minor_key()); }
2960 KeyedAccessStoreMode store_mode() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002961 return CommonStoreModeBits::decode(sub_minor_key());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002962 }
2963
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002964 CallInterfaceDescriptor GetCallInterfaceDescriptor() const override;
2965 Code::Kind GetCodeKind() const override { return Code::HANDLER; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002966
2967 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002968 class FromBits : public BitField<ElementsKind, 3, 8> {};
2969 class ToBits : public BitField<ElementsKind, 11, 8> {};
2970 class IsJSArrayBits : public BitField<bool, 19, 1> {};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002971
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002972 DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002973};
2974
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002975
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002976class StubFailureTrampolineStub : public PlatformCodeStub {
2977 public:
2978 StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
2979 : PlatformCodeStub(isolate) {
2980 minor_key_ = FunctionModeField::encode(function_mode);
2981 }
2982
2983 static void GenerateAheadOfTime(Isolate* isolate);
2984
2985 private:
2986 StubFunctionMode function_mode() const {
2987 return FunctionModeField::decode(minor_key_);
2988 }
2989
2990 class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
2991
2992 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2993 DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub);
2994};
2995
2996
2997class ProfileEntryHookStub : public PlatformCodeStub {
2998 public:
2999 explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3000
3001 // The profile entry hook function is not allowed to cause a GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003002 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003003
3004 // Generates a call to the entry hook if it's enabled.
3005 static void MaybeCallEntryHook(MacroAssembler* masm);
3006
3007 private:
3008 static void EntryHookTrampoline(intptr_t function,
3009 intptr_t stack_pointer,
3010 Isolate* isolate);
3011
3012 // ProfileEntryHookStub is called at the start of a function, so it has the
3013 // same register set.
3014 DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction)
3015 DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub);
3016};
3017
3018
3019class StoreBufferOverflowStub : public PlatformCodeStub {
3020 public:
3021 StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
3022 : PlatformCodeStub(isolate) {
3023 minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs);
3024 }
3025
3026 static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003027 bool SometimesSetsUpAFrame() override { return false; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003028
3029 private:
3030 bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
3031
3032 class SaveDoublesBits : public BitField<bool, 0, 1> {};
3033
3034 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
3035 DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
3036};
3037
3038
3039class SubStringStub : public PlatformCodeStub {
3040 public:
3041 explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3042
3043 DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
3044 DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub);
3045};
3046
3047
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003048class ToNumberStub final : public PlatformCodeStub {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003049 public:
3050 explicit ToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3051
Ben Murdochda12d292016-06-02 14:46:10 +01003052 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003053 DEFINE_PLATFORM_CODE_STUB(ToNumber, PlatformCodeStub);
3054};
3055
Ben Murdochda12d292016-06-02 14:46:10 +01003056class NonNumberToNumberStub final : public PlatformCodeStub {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003057 public:
Ben Murdochda12d292016-06-02 14:46:10 +01003058 explicit NonNumberToNumberStub(Isolate* isolate)
3059 : PlatformCodeStub(isolate) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003060
Ben Murdochda12d292016-06-02 14:46:10 +01003061 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
3062 DEFINE_PLATFORM_CODE_STUB(NonNumberToNumber, PlatformCodeStub);
3063};
3064
3065class StringToNumberStub final : public PlatformCodeStub {
3066 public:
3067 explicit StringToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3068
3069 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
3070 DEFINE_PLATFORM_CODE_STUB(StringToNumber, PlatformCodeStub);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003071};
3072
3073
3074class ToStringStub final : public PlatformCodeStub {
3075 public:
3076 explicit ToStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3077
Ben Murdochda12d292016-06-02 14:46:10 +01003078 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003079 DEFINE_PLATFORM_CODE_STUB(ToString, PlatformCodeStub);
3080};
3081
3082
Ben Murdoch097c5b22016-05-18 11:27:45 +01003083class ToNameStub final : public PlatformCodeStub {
3084 public:
3085 explicit ToNameStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
3086
Ben Murdochda12d292016-06-02 14:46:10 +01003087 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003088 DEFINE_PLATFORM_CODE_STUB(ToName, PlatformCodeStub);
3089};
3090
3091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003092class ToObjectStub final : public HydrogenCodeStub {
3093 public:
3094 explicit ToObjectStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
3095
Ben Murdochda12d292016-06-02 14:46:10 +01003096 DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003097 DEFINE_HYDROGEN_CODE_STUB(ToObject, HydrogenCodeStub);
3098};
3099
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003100#undef DEFINE_CALL_INTERFACE_DESCRIPTOR
3101#undef DEFINE_PLATFORM_CODE_STUB
3102#undef DEFINE_HANDLER_CODE_STUB
3103#undef DEFINE_HYDROGEN_CODE_STUB
3104#undef DEFINE_CODE_STUB
3105#undef DEFINE_CODE_STUB_BASE
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003106
3107extern Representation RepresentationFromType(Type* type);
3108
3109} // namespace internal
3110} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00003111
3112#endif // V8_CODE_STUBS_H_