77a2f8bba329faf769b7bc1fff5fa0c94adfed4c
[platform/upstream/v8.git] / src / code-stubs.h
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_CODE_STUBS_H_
6 #define V8_CODE_STUBS_H_
7
8 #include "src/allocation.h"
9 #include "src/assembler.h"
10 #include "src/codegen.h"
11 #include "src/globals.h"
12 #include "src/ic/ic-state.h"
13 #include "src/interface-descriptors.h"
14 #include "src/macro-assembler.h"
15 #include "src/ostreams.h"
16
17 namespace v8 {
18 namespace internal {
19
20 // List of code stubs used on all platforms.
21 #define CODE_STUB_LIST_ALL_PLATFORMS(V)     \
22   /* PlatformCodeStubs */                   \
23   V(ArgumentsAccess)                        \
24   V(ArrayConstructor)                       \
25   V(BinaryOpICWithAllocationSite)           \
26   V(CallApiFunction)                        \
27   V(CallApiAccessor)                        \
28   V(CallApiGetter)                          \
29   V(CallConstruct)                          \
30   V(CallFunction)                           \
31   V(CallIC)                                 \
32   V(CallIC_Array)                           \
33   V(CEntry)                                 \
34   V(CompareIC)                              \
35   V(DoubleToI)                              \
36   V(FunctionPrototype)                      \
37   V(Instanceof)                             \
38   V(InternalArrayConstructor)               \
39   V(JSEntry)                                \
40   V(KeyedLoadICTrampoline)                  \
41   V(LoadICTrampoline)                       \
42   V(CallICTrampoline)                       \
43   V(CallIC_ArrayTrampoline)                 \
44   V(LoadIndexedInterceptor)                 \
45   V(LoadIndexedString)                      \
46   V(MathPow)                                \
47   V(ProfileEntryHook)                       \
48   V(RecordWrite)                            \
49   V(RegExpExec)                             \
50   V(StoreArrayLiteralElement)               \
51   V(StoreBufferOverflow)                    \
52   V(StoreElement)                           \
53   V(StringCompare)                          \
54   V(StubFailureTrampoline)                  \
55   V(SubString)                              \
56   V(ToNumber)                               \
57   V(VectorStoreICTrampoline)                \
58   V(VectorKeyedStoreICTrampoline)           \
59   V(VectorStoreIC)                          \
60   V(VectorKeyedStoreIC)                     \
61   /* HydrogenCodeStubs */                   \
62   V(AllocateHeapNumber)                     \
63   V(ArrayNArgumentsConstructor)             \
64   V(ArrayNoArgumentConstructor)             \
65   V(ArraySingleArgumentConstructor)         \
66   V(BinaryOpIC)                             \
67   V(BinaryOpWithAllocationSite)             \
68   V(CompareNilIC)                           \
69   V(CreateAllocationSite)                   \
70   V(CreateWeakCell)                         \
71   V(ElementsTransitionAndStore)             \
72   V(FastCloneShallowArray)                  \
73   V(FastCloneShallowObject)                 \
74   V(FastNewClosure)                         \
75   V(FastNewContext)                         \
76   V(GrowArrayElements)                      \
77   V(InternalArrayNArgumentsConstructor)     \
78   V(InternalArrayNoArgumentConstructor)     \
79   V(InternalArraySingleArgumentConstructor) \
80   V(KeyedLoadGeneric)                       \
81   V(LoadScriptContextField)                 \
82   V(LoadDictionaryElement)                  \
83   V(NameDictionaryLookup)                   \
84   V(NumberToString)                         \
85   V(Typeof)                                 \
86   V(RegExpConstructResult)                  \
87   V(StoreFastElement)                       \
88   V(StoreScriptContextField)                \
89   V(StringAdd)                              \
90   V(ToBoolean)                              \
91   V(TransitionElementsKind)                 \
92   V(KeyedLoadIC)                            \
93   V(LoadIC)                                 \
94   /* TurboFanCodeStubs */                   \
95   V(StringLengthTF)                         \
96   V(StringAddTF)                            \
97   V(MathFloor)                              \
98   /* IC Handler stubs */                    \
99   V(ArrayBufferViewLoadField)               \
100   V(LoadConstant)                           \
101   V(LoadFastElement)                        \
102   V(LoadField)                              \
103   V(KeyedLoadSloppyArguments)               \
104   V(KeyedStoreSloppyArguments)              \
105   V(StoreField)                             \
106   V(StoreGlobal)                            \
107   V(StoreTransition)                        \
108   V(StringLength)                           \
109   V(RestParamAccess)
110
111 // List of code stubs only used on ARM 32 bits platforms.
112 #if V8_TARGET_ARCH_ARM
113 #define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
114
115 #else
116 #define CODE_STUB_LIST_ARM(V)
117 #endif
118
119 // List of code stubs only used on ARM 64 bits platforms.
120 #if V8_TARGET_ARCH_ARM64
121 #define CODE_STUB_LIST_ARM64(V) \
122   V(DirectCEntry)               \
123   V(RestoreRegistersState)      \
124   V(StoreRegistersState)
125
126 #else
127 #define CODE_STUB_LIST_ARM64(V)
128 #endif
129
130 // List of code stubs only used on PPC platforms.
131 #ifdef V8_TARGET_ARCH_PPC
132 #define CODE_STUB_LIST_PPC(V) \
133   V(DirectCEntry)             \
134   V(StoreRegistersState)      \
135   V(RestoreRegistersState)
136 #else
137 #define CODE_STUB_LIST_PPC(V)
138 #endif
139
140 // List of code stubs only used on MIPS platforms.
141 #if V8_TARGET_ARCH_MIPS
142 #define CODE_STUB_LIST_MIPS(V) \
143   V(DirectCEntry)              \
144   V(RestoreRegistersState)     \
145   V(StoreRegistersState)
146 #elif V8_TARGET_ARCH_MIPS64
147 #define CODE_STUB_LIST_MIPS(V) \
148   V(DirectCEntry)              \
149   V(RestoreRegistersState)     \
150   V(StoreRegistersState)
151 #else
152 #define CODE_STUB_LIST_MIPS(V)
153 #endif
154
155 // Combined list of code stubs.
156 #define CODE_STUB_LIST(V)         \
157   CODE_STUB_LIST_ALL_PLATFORMS(V) \
158   CODE_STUB_LIST_ARM(V)           \
159   CODE_STUB_LIST_ARM64(V)         \
160   CODE_STUB_LIST_PPC(V)           \
161   CODE_STUB_LIST_MIPS(V)
162
163 static const int kHasReturnedMinusZeroSentinel = 1;
164
165 // Stub is base classes of all stubs.
166 class CodeStub BASE_EMBEDDED {
167  public:
168   enum Major {
169     // TODO(mvstanton): eliminate the NoCache key by getting rid
170     //                  of the non-monomorphic-cache.
171     NoCache = 0,  // marker for stubs that do custom caching]
172 #define DEF_ENUM(name) name,
173     CODE_STUB_LIST(DEF_ENUM)
174 #undef DEF_ENUM
175     NUMBER_OF_IDS
176   };
177
178   // Retrieve the code for the stub. Generate the code if needed.
179   Handle<Code> GetCode();
180
181   // Retrieve the code for the stub, make and return a copy of the code.
182   Handle<Code> GetCodeCopy(const Code::FindAndReplacePattern& pattern);
183
184   static Major MajorKeyFromKey(uint32_t key) {
185     return static_cast<Major>(MajorKeyBits::decode(key));
186   }
187   static uint32_t MinorKeyFromKey(uint32_t key) {
188     return MinorKeyBits::decode(key);
189   }
190
191   // Gets the major key from a code object that is a code stub or binary op IC.
192   static Major GetMajorKey(Code* code_stub) {
193     return MajorKeyFromKey(code_stub->stub_key());
194   }
195
196   static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
197
198   static const char* MajorName(Major major_key, bool allow_unknown_keys);
199
200   explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
201   virtual ~CodeStub() {}
202
203   static void GenerateStubsAheadOfTime(Isolate* isolate);
204   static void GenerateFPStubs(Isolate* isolate);
205
206   // Some stubs put untagged junk on the stack that cannot be scanned by the
207   // GC.  This means that we must be statically sure that no GC can occur while
208   // they are running.  If that is the case they should override this to return
209   // true, which will cause an assertion if we try to call something that can
210   // GC or if we try to put a stack frame on top of the junk, which would not
211   // result in a traversable stack.
212   virtual bool SometimesSetsUpAFrame() { return true; }
213
214   // Lookup the code in the (possibly custom) cache.
215   bool FindCodeInCache(Code** code_out);
216
217   virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() = 0;
218
219   virtual int GetStackParameterCount() const { return 0; }
220
221   virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
222
223   static void InitializeDescriptor(Isolate* isolate, uint32_t key,
224                                    CodeStubDescriptor* desc);
225
226   static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key);
227
228   // Returns information for computing the number key.
229   virtual Major MajorKey() const = 0;
230   uint32_t MinorKey() const { return minor_key_; }
231
232   // BinaryOpStub needs to override this.
233   virtual Code::Kind GetCodeKind() const;
234
235   virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
236   virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
237   virtual Code::StubType GetStubType() const { return Code::NORMAL; }
238
239   friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
240     s.PrintName(os);
241     return os;
242   }
243
244   Isolate* isolate() const { return isolate_; }
245
246  protected:
247   CodeStub(uint32_t key, Isolate* isolate)
248       : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
249
250   // Generates the assembler code for the stub.
251   virtual Handle<Code> GenerateCode() = 0;
252
253   // Returns whether the code generated for this stub needs to be allocated as
254   // a fixed (non-moveable) code object.
255   virtual bool NeedsImmovableCode() { return false; }
256
257   virtual void PrintName(std::ostream& os) const;        // NOLINT
258   virtual void PrintBaseName(std::ostream& os) const;    // NOLINT
259   virtual void PrintState(std::ostream& os) const { ; }  // NOLINT
260
261   // Computes the key based on major and minor.
262   uint32_t GetKey() {
263     DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
264     return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
265   }
266
267   uint32_t minor_key_;
268
269  private:
270   // Perform bookkeeping required after code generation when stub code is
271   // initially generated.
272   void RecordCodeGeneration(Handle<Code> code);
273
274   // Finish the code object after it has been generated.
275   virtual void FinishCode(Handle<Code> code) { }
276
277   // Activate newly generated stub. Is called after
278   // registering stub in the stub cache.
279   virtual void Activate(Code* code) { }
280
281   // Add the code to a specialized cache, specific to an individual
282   // stub type. Please note, this method must add the code object to a
283   // roots object, otherwise we will remove the code during GC.
284   virtual void AddToSpecialCache(Handle<Code> new_object) { }
285
286   // Find code in a specialized cache, work is delegated to the specific stub.
287   virtual bool FindCodeInSpecialCache(Code** code_out) {
288     return false;
289   }
290
291   // If a stub uses a special cache override this.
292   virtual bool UseSpecialCache() { return false; }
293
294   // We use this dispatch to statically instantiate the correct code stub for
295   // the given stub key and call the passed function with that code stub.
296   typedef void (*DispatchedCall)(CodeStub* stub, void** value_out);
297   static void Dispatch(Isolate* isolate, uint32_t key, void** value_out,
298                        DispatchedCall call);
299
300   static void GetCodeDispatchCall(CodeStub* stub, void** value_out);
301
302   STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
303   class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
304   class MinorKeyBits: public BitField<uint32_t,
305       kStubMajorKeyBits, kStubMinorKeyBits> {};  // NOLINT
306
307   friend class BreakPointIterator;
308
309   Isolate* isolate_;
310 };
311
312
313 // TODO(svenpanne) This class is only used to construct a more or less sensible
314 // CompilationInfo for testing purposes, basically pretending that we are
315 // currently compiling some kind of code stub. Remove this when the pipeline and
316 // testing machinery is restructured in such a way that we don't have to come up
317 // with a CompilationInfo out of thin air, although we only need a few parts of
318 // it.
319 struct FakeStubForTesting : public CodeStub {
320   explicit FakeStubForTesting(Isolate* isolate) : CodeStub(isolate) {}
321
322   // Only used by pipeline.cc's GetDebugName in DEBUG mode.
323   Major MajorKey() const override { return CodeStub::NoCache; }
324
325   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
326     UNREACHABLE();
327     return CallInterfaceDescriptor();
328   }
329
330   Handle<Code> GenerateCode() override {
331     UNREACHABLE();
332     return Handle<Code>();
333   }
334 };
335
336
337 #define DEFINE_CODE_STUB_BASE(NAME, SUPER)                      \
338  public:                                                        \
339   NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \
340                                                                 \
341  private:                                                       \
342   DISALLOW_COPY_AND_ASSIGN(NAME)
343
344
345 #define DEFINE_CODE_STUB(NAME, SUPER)                      \
346  protected:                                                \
347   inline Major MajorKey() const override { return NAME; }; \
348   DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
349
350
351 #define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER)  \
352  private:                                       \
353   void Generate(MacroAssembler* masm) override; \
354   DEFINE_CODE_STUB(NAME, SUPER)
355
356
357 #define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER)                        \
358  public:                                                              \
359   void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
360   Handle<Code> GenerateCode() override;                               \
361   DEFINE_CODE_STUB(NAME, SUPER)
362
363 #define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
364  public:                                      \
365   Handle<Code> GenerateCode() override;       \
366   DEFINE_CODE_STUB(NAME, SUPER)
367
368 #define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME)                    \
369  public:                                                          \
370   CallInterfaceDescriptor GetCallInterfaceDescriptor() override { \
371     return NAME##Descriptor(isolate());                           \
372   }
373
374 // There are some code stubs we just can't describe right now with a
375 // CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
376 // An attempt to retrieve a descriptor will fail.
377 #define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR()                   \
378  public:                                                          \
379   CallInterfaceDescriptor GetCallInterfaceDescriptor() override { \
380     UNREACHABLE();                                                \
381     return CallInterfaceDescriptor();                             \
382   }
383
384
385 class PlatformCodeStub : public CodeStub {
386  public:
387   // Retrieve the code for the stub. Generate the code if needed.
388   Handle<Code> GenerateCode() override;
389
390  protected:
391   explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
392
393   // Generates the assembler code for the stub.
394   virtual void Generate(MacroAssembler* masm) = 0;
395
396   DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub);
397 };
398
399
400 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
401 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
402
403
404 class CodeStubDescriptor {
405  public:
406   explicit CodeStubDescriptor(CodeStub* stub);
407
408   CodeStubDescriptor(Isolate* isolate, uint32_t stub_key);
409
410   void Initialize(Address deoptimization_handler = NULL,
411                   int hint_stack_parameter_count = -1,
412                   StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
413   void Initialize(Register stack_parameter_count,
414                   Address deoptimization_handler = NULL,
415                   int hint_stack_parameter_count = -1,
416                   StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE,
417                   HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS);
418
419   void SetMissHandler(ExternalReference handler) {
420     miss_handler_ = handler;
421     has_miss_handler_ = true;
422     // Our miss handler infrastructure doesn't currently support
423     // variable stack parameter counts.
424     DCHECK(!stack_parameter_count_.is_valid());
425   }
426
427   void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
428   CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
429
430   int GetEnvironmentParameterCount() const {
431     return call_descriptor().GetEnvironmentParameterCount();
432   }
433
434   Representation GetEnvironmentParameterRepresentation(int index) const {
435     return call_descriptor().GetEnvironmentParameterRepresentation(index);
436   }
437
438   ExternalReference miss_handler() const {
439     DCHECK(has_miss_handler_);
440     return miss_handler_;
441   }
442
443   bool has_miss_handler() const {
444     return has_miss_handler_;
445   }
446
447   bool IsEnvironmentParameterCountRegister(int index) const {
448     return call_descriptor().GetEnvironmentParameterRegister(index).is(
449         stack_parameter_count_);
450   }
451
452   int GetHandlerParameterCount() const {
453     int params = call_descriptor().GetEnvironmentParameterCount();
454     if (handler_arguments_mode_ == PASS_ARGUMENTS) {
455       params += 1;
456     }
457     return params;
458   }
459
460   int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
461   Register stack_parameter_count() const { return stack_parameter_count_; }
462   StubFunctionMode function_mode() const { return function_mode_; }
463   Address deoptimization_handler() const { return deoptimization_handler_; }
464
465  private:
466   CallInterfaceDescriptor call_descriptor_;
467   Register stack_parameter_count_;
468   // If hint_stack_parameter_count_ > 0, the code stub can optimize the
469   // return sequence. Default value is -1, which means it is ignored.
470   int hint_stack_parameter_count_;
471   StubFunctionMode function_mode_;
472
473   Address deoptimization_handler_;
474   HandlerArgumentsMode handler_arguments_mode_;
475
476   ExternalReference miss_handler_;
477   bool has_miss_handler_;
478 };
479
480
481 class HydrogenCodeStub : public CodeStub {
482  public:
483   enum InitializationState {
484     UNINITIALIZED,
485     INITIALIZED
486   };
487
488   template<class SubClass>
489   static Handle<Code> GetUninitialized(Isolate* isolate) {
490     SubClass::GenerateAheadOfTime(isolate);
491     return SubClass().GetCode(isolate);
492   }
493
494   // Retrieve the code for the stub. Generate the code if needed.
495   Handle<Code> GenerateCode() override = 0;
496
497   bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
498
499   Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
500
501   template<class StateType>
502   void TraceTransition(StateType from, StateType to);
503
504  protected:
505   explicit HydrogenCodeStub(Isolate* isolate,
506                             InitializationState state = INITIALIZED)
507       : CodeStub(isolate) {
508     minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
509   }
510
511   void set_sub_minor_key(uint32_t key) {
512     minor_key_ = SubMinorKeyBits::update(minor_key_, key);
513   }
514
515   uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
516
517   static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
518
519  private:
520   class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};
521   class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
522
523   void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss);
524
525   DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub);
526 };
527
528
529 class TurboFanCodeStub : public CodeStub {
530  public:
531   // Retrieve the code for the stub. Generate the code if needed.
532   Handle<Code> GenerateCode() override;
533
534   Code::StubType GetStubType() const override { return Code::FAST; }
535
536  protected:
537   explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
538
539  private:
540   DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
541 };
542
543
544 // Helper interface to prepare to/restore after making runtime calls.
545 class RuntimeCallHelper {
546  public:
547   virtual ~RuntimeCallHelper() {}
548
549   virtual void BeforeCall(MacroAssembler* masm) const = 0;
550
551   virtual void AfterCall(MacroAssembler* masm) const = 0;
552
553  protected:
554   RuntimeCallHelper() {}
555
556  private:
557   DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
558 };
559
560
561 } }  // namespace v8::internal
562
563 #if V8_TARGET_ARCH_IA32
564 #include "src/ia32/code-stubs-ia32.h"
565 #elif V8_TARGET_ARCH_X64
566 #include "src/x64/code-stubs-x64.h"
567 #elif V8_TARGET_ARCH_ARM64
568 #include "src/arm64/code-stubs-arm64.h"
569 #elif V8_TARGET_ARCH_ARM
570 #include "src/arm/code-stubs-arm.h"
571 #elif V8_TARGET_ARCH_PPC
572 #include "src/ppc/code-stubs-ppc.h"
573 #elif V8_TARGET_ARCH_MIPS
574 #include "src/mips/code-stubs-mips.h"
575 #elif V8_TARGET_ARCH_MIPS64
576 #include "src/mips64/code-stubs-mips64.h"
577 #elif V8_TARGET_ARCH_X87
578 #include "src/x87/code-stubs-x87.h"
579 #else
580 #error Unsupported target architecture.
581 #endif
582
583 namespace v8 {
584 namespace internal {
585
586
587 // RuntimeCallHelper implementation used in stubs: enters/leaves a
588 // newly created internal frame before/after the runtime call.
589 class StubRuntimeCallHelper : public RuntimeCallHelper {
590  public:
591   StubRuntimeCallHelper() {}
592
593   virtual void BeforeCall(MacroAssembler* masm) const;
594
595   virtual void AfterCall(MacroAssembler* masm) const;
596 };
597
598
599 // Trivial RuntimeCallHelper implementation.
600 class NopRuntimeCallHelper : public RuntimeCallHelper {
601  public:
602   NopRuntimeCallHelper() {}
603
604   virtual void BeforeCall(MacroAssembler* masm) const {}
605
606   virtual void AfterCall(MacroAssembler* masm) const {}
607 };
608
609
610 class MathFloorStub : public TurboFanCodeStub {
611  public:
612   explicit MathFloorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
613   int GetStackParameterCount() const override { return 1; }
614
615   DEFINE_CALL_INTERFACE_DESCRIPTOR(MathRoundVariant);
616   DEFINE_CODE_STUB(MathFloor, TurboFanCodeStub);
617 };
618
619
620 class StringLengthTFStub : public TurboFanCodeStub {
621  public:
622   explicit StringLengthTFStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
623
624   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
625   InlineCacheState GetICState() const override { return MONOMORPHIC; }
626   ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
627
628   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
629   DEFINE_CODE_STUB(StringLengthTF, TurboFanCodeStub);
630 };
631
632
633 enum StringAddFlags {
634   // Omit both parameter checks.
635   STRING_ADD_CHECK_NONE = 0,
636   // Check left parameter.
637   STRING_ADD_CHECK_LEFT = 1 << 0,
638   // Check right parameter.
639   STRING_ADD_CHECK_RIGHT = 1 << 1,
640   // Check both parameters.
641   STRING_ADD_CHECK_BOTH = STRING_ADD_CHECK_LEFT | STRING_ADD_CHECK_RIGHT
642 };
643
644
645 std::ostream& operator<<(std::ostream& os, const StringAddFlags& flags);
646
647
648 class StringAddTFStub : public TurboFanCodeStub {
649  public:
650   StringAddTFStub(Isolate* isolate, StringAddFlags flags,
651                   PretenureFlag pretenure_flag)
652       : TurboFanCodeStub(isolate) {
653     minor_key_ = StringAddFlagsBits::encode(flags) |
654                  PretenureFlagBits::encode(pretenure_flag);
655   }
656
657   StringAddFlags flags() const {
658     return StringAddFlagsBits::decode(MinorKey());
659   }
660
661   PretenureFlag pretenure_flag() const {
662     return PretenureFlagBits::decode(MinorKey());
663   }
664
665  private:
666   class StringAddFlagsBits : public BitField<StringAddFlags, 0, 2> {};
667   class PretenureFlagBits : public BitField<PretenureFlag, 2, 1> {};
668
669   void PrintBaseName(std::ostream& os) const override;  // NOLINT
670
671   DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
672   DEFINE_CODE_STUB(StringAddTF, TurboFanCodeStub);
673 };
674
675
676 class NumberToStringStub final : public HydrogenCodeStub {
677  public:
678   explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
679
680   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
681   static const int kNumber = 0;
682
683   DEFINE_CALL_INTERFACE_DESCRIPTOR(NumberToString);
684   DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub);
685 };
686
687
688 class TypeofStub final : public HydrogenCodeStub {
689  public:
690   explicit TypeofStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
691
692   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
693   static const int kObject = 0;
694
695   static void GenerateAheadOfTime(Isolate* isolate);
696
697   DEFINE_CALL_INTERFACE_DESCRIPTOR(Typeof);
698   DEFINE_HYDROGEN_CODE_STUB(Typeof, HydrogenCodeStub);
699 };
700
701
702 class FastNewClosureStub : public HydrogenCodeStub {
703  public:
704   FastNewClosureStub(Isolate* isolate, LanguageMode language_mode,
705                      FunctionKind kind)
706       : HydrogenCodeStub(isolate) {
707     DCHECK(IsValidFunctionKind(kind));
708     set_sub_minor_key(LanguageModeBits::encode(language_mode) |
709                       FunctionKindBits::encode(kind));
710   }
711
712   LanguageMode language_mode() const {
713     return LanguageModeBits::decode(sub_minor_key());
714   }
715
716   FunctionKind kind() const {
717     return FunctionKindBits::decode(sub_minor_key());
718   }
719
720  private:
721   STATIC_ASSERT(LANGUAGE_END == 3);
722   class LanguageModeBits : public BitField<LanguageMode, 0, 2> {};
723   class FunctionKindBits : public BitField<FunctionKind, 2, 8> {};
724
725   DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
726   DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
727 };
728
729
730 class FastNewContextStub final : public HydrogenCodeStub {
731  public:
732   static const int kMaximumSlots = 64;
733
734   FastNewContextStub(Isolate* isolate, int slots) : HydrogenCodeStub(isolate) {
735     DCHECK(slots >= 0 && slots <= kMaximumSlots);
736     set_sub_minor_key(SlotsBits::encode(slots));
737   }
738
739   int slots() const { return SlotsBits::decode(sub_minor_key()); }
740
741   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
742   static const int kFunction = 0;
743
744  private:
745   class SlotsBits : public BitField<int, 0, 8> {};
746
747   DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewContext);
748   DEFINE_HYDROGEN_CODE_STUB(FastNewContext, HydrogenCodeStub);
749 };
750
751
752 class FastCloneShallowArrayStub : public HydrogenCodeStub {
753  public:
754   FastCloneShallowArrayStub(Isolate* isolate,
755                             AllocationSiteMode allocation_site_mode)
756       : HydrogenCodeStub(isolate) {
757     set_sub_minor_key(AllocationSiteModeBits::encode(allocation_site_mode));
758   }
759
760   AllocationSiteMode allocation_site_mode() const {
761     return AllocationSiteModeBits::decode(sub_minor_key());
762   }
763
764  private:
765   class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
766
767   DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowArray);
768   DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowArray, HydrogenCodeStub);
769 };
770
771
772 class FastCloneShallowObjectStub : public HydrogenCodeStub {
773  public:
774   // Maximum number of properties in copied object.
775   static const int kMaximumClonedProperties = 6;
776
777   FastCloneShallowObjectStub(Isolate* isolate, int length)
778       : HydrogenCodeStub(isolate) {
779     DCHECK_GE(length, 0);
780     DCHECK_LE(length, kMaximumClonedProperties);
781     set_sub_minor_key(LengthBits::encode(length));
782   }
783
784   int length() const { return LengthBits::decode(sub_minor_key()); }
785
786  private:
787   class LengthBits : public BitField<int, 0, 4> {};
788
789   DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowObject);
790   DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowObject, HydrogenCodeStub);
791 };
792
793
794 class CreateAllocationSiteStub : public HydrogenCodeStub {
795  public:
796   explicit CreateAllocationSiteStub(Isolate* isolate)
797       : HydrogenCodeStub(isolate) { }
798
799   static void GenerateAheadOfTime(Isolate* isolate);
800
801   DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite);
802   DEFINE_HYDROGEN_CODE_STUB(CreateAllocationSite, HydrogenCodeStub);
803 };
804
805
806 class CreateWeakCellStub : public HydrogenCodeStub {
807  public:
808   explicit CreateWeakCellStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
809
810   static void GenerateAheadOfTime(Isolate* isolate);
811
812   DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
813   DEFINE_HYDROGEN_CODE_STUB(CreateWeakCell, HydrogenCodeStub);
814 };
815
816
817 class GrowArrayElementsStub : public HydrogenCodeStub {
818  public:
819   GrowArrayElementsStub(Isolate* isolate, bool is_js_array, ElementsKind kind)
820       : HydrogenCodeStub(isolate) {
821     set_sub_minor_key(ElementsKindBits::encode(kind) |
822                       IsJsArrayBits::encode(is_js_array));
823   }
824
825   ElementsKind elements_kind() const {
826     return ElementsKindBits::decode(sub_minor_key());
827   }
828
829   bool is_js_array() const { return IsJsArrayBits::decode(sub_minor_key()); }
830
831  private:
832   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
833   class IsJsArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
834
835   DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
836   DEFINE_HYDROGEN_CODE_STUB(GrowArrayElements, HydrogenCodeStub);
837 };
838
839 class InstanceofStub: public PlatformCodeStub {
840  public:
841   enum Flags {
842     kNoFlags = 0,
843     kArgsInRegisters = 1 << 0,
844     kCallSiteInlineCheck = 1 << 1,
845     kReturnTrueFalseObject = 1 << 2
846   };
847
848   InstanceofStub(Isolate* isolate, Flags flags) : PlatformCodeStub(isolate) {
849     minor_key_ = FlagBits::encode(flags);
850   }
851
852   static Register left() { return InstanceofDescriptor::left(); }
853   static Register right() { return InstanceofDescriptor::right(); }
854
855   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
856     if (HasArgsInRegisters()) {
857       return InstanceofDescriptor(isolate());
858     }
859     return ContextOnlyDescriptor(isolate());
860   }
861
862  private:
863   Flags flags() const { return FlagBits::decode(minor_key_); }
864
865   bool HasArgsInRegisters() const { return (flags() & kArgsInRegisters) != 0; }
866
867   bool HasCallSiteInlineCheck() const {
868     return (flags() & kCallSiteInlineCheck) != 0;
869   }
870
871   bool ReturnTrueFalseObject() const {
872     return (flags() & kReturnTrueFalseObject) != 0;
873   }
874
875   void PrintName(std::ostream& os) const override;  // NOLINT
876
877   class FlagBits : public BitField<Flags, 0, 3> {};
878
879   DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub);
880 };
881
882
883 enum AllocationSiteOverrideMode {
884   DONT_OVERRIDE,
885   DISABLE_ALLOCATION_SITES,
886   LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
887 };
888
889
890 class ArrayConstructorStub: public PlatformCodeStub {
891  public:
892   enum ArgumentCountKey { ANY, NONE, ONE, MORE_THAN_ONE };
893
894   ArrayConstructorStub(Isolate* isolate, int argument_count);
895
896   explicit ArrayConstructorStub(Isolate* isolate);
897
898  private:
899   ArgumentCountKey argument_count() const {
900     return ArgumentCountBits::decode(minor_key_);
901   }
902
903   void GenerateDispatchToArrayStub(MacroAssembler* masm,
904                                    AllocationSiteOverrideMode mode);
905
906   void PrintName(std::ostream& os) const override;  // NOLINT
907
908   class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
909
910   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
911   DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
912 };
913
914
915 class InternalArrayConstructorStub: public PlatformCodeStub {
916  public:
917   explicit InternalArrayConstructorStub(Isolate* isolate);
918
919  private:
920   void GenerateCase(MacroAssembler* masm, ElementsKind kind);
921
922   DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
923   DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
924 };
925
926
927 class MathPowStub: public PlatformCodeStub {
928  public:
929   enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK };
930
931   MathPowStub(Isolate* isolate, ExponentType exponent_type)
932       : PlatformCodeStub(isolate) {
933     minor_key_ = ExponentTypeBits::encode(exponent_type);
934   }
935
936   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
937     if (exponent_type() == TAGGED) {
938       return MathPowTaggedDescriptor(isolate());
939     } else if (exponent_type() == INTEGER) {
940       return MathPowIntegerDescriptor(isolate());
941     }
942     // A CallInterfaceDescriptor doesn't specify double registers (yet).
943     return ContextOnlyDescriptor(isolate());
944   }
945
946  private:
947   ExponentType exponent_type() const {
948     return ExponentTypeBits::decode(minor_key_);
949   }
950
951   class ExponentTypeBits : public BitField<ExponentType, 0, 2> {};
952
953   DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub);
954 };
955
956
957 class CallICStub: public PlatformCodeStub {
958  public:
959   CallICStub(Isolate* isolate, const CallICState& state)
960       : PlatformCodeStub(isolate) {
961     minor_key_ = state.GetExtraICState();
962   }
963
964   static int ExtractArgcFromMinorKey(int minor_key) {
965     CallICState state(static_cast<ExtraICState>(minor_key));
966     return state.arg_count();
967   }
968
969   Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
970
971   InlineCacheState GetICState() const override { return DEFAULT; }
972
973   ExtraICState GetExtraICState() const final {
974     return static_cast<ExtraICState>(minor_key_);
975   }
976
977  protected:
978   bool CallAsMethod() const {
979     return state().call_type() == CallICState::METHOD;
980   }
981
982   int arg_count() const { return state().arg_count(); }
983
984   CallICState state() const {
985     return CallICState(static_cast<ExtraICState>(minor_key_));
986   }
987
988   // Code generation helpers.
989   void GenerateMiss(MacroAssembler* masm);
990
991  private:
992   void PrintState(std::ostream& os) const override;  // NOLINT
993
994   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedbackAndVector);
995   DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
996 };
997
998
999 class CallIC_ArrayStub: public CallICStub {
1000  public:
1001   CallIC_ArrayStub(Isolate* isolate, const CallICState& state_in)
1002       : CallICStub(isolate, state_in) {}
1003
1004   InlineCacheState GetICState() const final { return MONOMORPHIC; }
1005
1006  private:
1007   void PrintState(std::ostream& os) const override;  // NOLINT
1008
1009   DEFINE_PLATFORM_CODE_STUB(CallIC_Array, CallICStub);
1010 };
1011
1012
1013 // TODO(verwaest): Translate to hydrogen code stub.
1014 class FunctionPrototypeStub : public PlatformCodeStub {
1015  public:
1016   explicit FunctionPrototypeStub(Isolate* isolate)
1017       : PlatformCodeStub(isolate) {}
1018
1019   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1020
1021   // TODO(mvstanton): only the receiver register is accessed. When this is
1022   // translated to a hydrogen code stub, a new CallInterfaceDescriptor
1023   // should be created that just uses that register for more efficient code.
1024   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
1025     return LoadWithVectorDescriptor(isolate());
1026   }
1027
1028   DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
1029 };
1030
1031
1032 // TODO(mvstanton): Translate to hydrogen code stub.
1033 class LoadIndexedInterceptorStub : public PlatformCodeStub {
1034  public:
1035   explicit LoadIndexedInterceptorStub(Isolate* isolate)
1036       : PlatformCodeStub(isolate) {}
1037
1038   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1039   Code::StubType GetStubType() const override { return Code::FAST; }
1040
1041   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
1042   DEFINE_PLATFORM_CODE_STUB(LoadIndexedInterceptor, PlatformCodeStub);
1043 };
1044
1045
1046 class LoadIndexedStringStub : public PlatformCodeStub {
1047  public:
1048   explicit LoadIndexedStringStub(Isolate* isolate)
1049       : PlatformCodeStub(isolate) {}
1050
1051   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1052   Code::StubType GetStubType() const override { return Code::FAST; }
1053
1054   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
1055   DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
1056 };
1057
1058
1059 class HandlerStub : public HydrogenCodeStub {
1060  public:
1061   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
1062   ExtraICState GetExtraICState() const override { return kind(); }
1063   InlineCacheState GetICState() const override { return MONOMORPHIC; }
1064
1065   void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
1066
1067   CallInterfaceDescriptor GetCallInterfaceDescriptor() override;
1068
1069  protected:
1070   explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
1071
1072   virtual Code::Kind kind() const = 0;
1073
1074   DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub);
1075 };
1076
1077
1078 class LoadFieldStub: public HandlerStub {
1079  public:
1080   LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate) {
1081     int property_index_key = index.GetFieldAccessStubKey();
1082     set_sub_minor_key(LoadFieldByIndexBits::encode(property_index_key));
1083   }
1084
1085   FieldIndex index() const {
1086     int property_index_key = LoadFieldByIndexBits::decode(sub_minor_key());
1087     return FieldIndex::FromFieldAccessStubKey(property_index_key);
1088   }
1089
1090  protected:
1091   Code::Kind kind() const override { return Code::LOAD_IC; }
1092   Code::StubType GetStubType() const override { return Code::FAST; }
1093
1094  private:
1095   class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
1096
1097   DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub);
1098 };
1099
1100
1101 class ArrayBufferViewLoadFieldStub : public HandlerStub {
1102  public:
1103   ArrayBufferViewLoadFieldStub(Isolate* isolate, FieldIndex index)
1104       : HandlerStub(isolate) {
1105     int property_index_key = index.GetFieldAccessStubKey();
1106     set_sub_minor_key(
1107         ArrayBufferViewLoadFieldByIndexBits::encode(property_index_key));
1108   }
1109
1110   FieldIndex index() const {
1111     int property_index_key =
1112         ArrayBufferViewLoadFieldByIndexBits::decode(sub_minor_key());
1113     return FieldIndex::FromFieldAccessStubKey(property_index_key);
1114   }
1115
1116  protected:
1117   Code::Kind kind() const override { return Code::LOAD_IC; }
1118   Code::StubType GetStubType() const override { return Code::FAST; }
1119
1120  private:
1121   class ArrayBufferViewLoadFieldByIndexBits : public BitField<int, 0, 13> {};
1122
1123   DEFINE_HANDLER_CODE_STUB(ArrayBufferViewLoadField, HandlerStub);
1124 };
1125
1126
1127 class KeyedLoadSloppyArgumentsStub : public HandlerStub {
1128  public:
1129   explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
1130       : HandlerStub(isolate) {}
1131
1132  protected:
1133   Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
1134   Code::StubType GetStubType() const override { return Code::FAST; }
1135
1136  private:
1137   DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
1138 };
1139
1140
1141 class KeyedStoreSloppyArgumentsStub : public HandlerStub {
1142  public:
1143   explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate)
1144       : HandlerStub(isolate) {}
1145
1146  protected:
1147   Code::Kind kind() const override { return Code::KEYED_STORE_IC; }
1148   Code::StubType GetStubType() const override { return Code::FAST; }
1149
1150  private:
1151   DEFINE_HANDLER_CODE_STUB(KeyedStoreSloppyArguments, HandlerStub);
1152 };
1153
1154
1155 class LoadConstantStub : public HandlerStub {
1156  public:
1157   LoadConstantStub(Isolate* isolate, int constant_index)
1158       : HandlerStub(isolate) {
1159     set_sub_minor_key(ConstantIndexBits::encode(constant_index));
1160   }
1161
1162   int constant_index() const {
1163     return ConstantIndexBits::decode(sub_minor_key());
1164   }
1165
1166  protected:
1167   Code::Kind kind() const override { return Code::LOAD_IC; }
1168   Code::StubType GetStubType() const override { return Code::FAST; }
1169
1170  private:
1171   class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {};
1172
1173   DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub);
1174 };
1175
1176
1177 class StringLengthStub: public HandlerStub {
1178  public:
1179   explicit StringLengthStub(Isolate* isolate) : HandlerStub(isolate) {}
1180
1181  protected:
1182   Code::Kind kind() const override { return Code::LOAD_IC; }
1183   Code::StubType GetStubType() const override { return Code::FAST; }
1184
1185   DEFINE_HANDLER_CODE_STUB(StringLength, HandlerStub);
1186 };
1187
1188
1189 class StoreFieldStub : public HandlerStub {
1190  public:
1191   StoreFieldStub(Isolate* isolate, FieldIndex index,
1192                  Representation representation)
1193       : HandlerStub(isolate) {
1194     int property_index_key = index.GetFieldAccessStubKey();
1195     uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1196     set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1197                       RepresentationBits::encode(repr));
1198   }
1199
1200   FieldIndex index() const {
1201     int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1202     return FieldIndex::FromFieldAccessStubKey(property_index_key);
1203   }
1204
1205   Representation representation() {
1206     uint8_t repr = RepresentationBits::decode(sub_minor_key());
1207     return PropertyDetails::DecodeRepresentation(repr);
1208   }
1209
1210  protected:
1211   Code::Kind kind() const override { return Code::STORE_IC; }
1212   Code::StubType GetStubType() const override { return Code::FAST; }
1213
1214  private:
1215   class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1216   class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1217
1218   DEFINE_HANDLER_CODE_STUB(StoreField, HandlerStub);
1219 };
1220
1221
1222 class StoreTransitionStub : public HandlerStub {
1223  public:
1224   enum StoreMode {
1225     StoreMapOnly,
1226     StoreMapAndValue,
1227     ExtendStorageAndStoreMapAndValue
1228   };
1229
1230   explicit StoreTransitionStub(Isolate* isolate) : HandlerStub(isolate) {
1231     set_sub_minor_key(StoreModeBits::encode(StoreMapOnly));
1232   }
1233
1234   StoreTransitionStub(Isolate* isolate, FieldIndex index,
1235                       Representation representation, StoreMode store_mode)
1236       : HandlerStub(isolate) {
1237     DCHECK(store_mode != StoreMapOnly);
1238     int property_index_key = index.GetFieldAccessStubKey();
1239     uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
1240     set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
1241                       RepresentationBits::encode(repr) |
1242                       StoreModeBits::encode(store_mode));
1243   }
1244
1245   FieldIndex index() const {
1246     DCHECK(store_mode() != StoreMapOnly);
1247     int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
1248     return FieldIndex::FromFieldAccessStubKey(property_index_key);
1249   }
1250
1251   Representation representation() {
1252     DCHECK(store_mode() != StoreMapOnly);
1253     uint8_t repr = RepresentationBits::decode(sub_minor_key());
1254     return PropertyDetails::DecodeRepresentation(repr);
1255   }
1256
1257   StoreMode store_mode() const {
1258     return StoreModeBits::decode(sub_minor_key());
1259   }
1260
1261   CallInterfaceDescriptor GetCallInterfaceDescriptor() override;
1262
1263  protected:
1264   Code::Kind kind() const override { return Code::STORE_IC; }
1265   Code::StubType GetStubType() const override { return Code::FAST; }
1266
1267  private:
1268   class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
1269   class RepresentationBits : public BitField<uint8_t, 13, 4> {};
1270   class StoreModeBits : public BitField<StoreMode, 17, 2> {};
1271
1272   DEFINE_HANDLER_CODE_STUB(StoreTransition, HandlerStub);
1273 };
1274
1275
1276 class StoreGlobalStub : public HandlerStub {
1277  public:
1278   StoreGlobalStub(Isolate* isolate, PropertyCellType type,
1279                   Maybe<PropertyCellConstantType> constant_type,
1280                   bool check_global)
1281       : HandlerStub(isolate) {
1282     PropertyCellConstantType encoded_constant_type =
1283         constant_type.FromMaybe(PropertyCellConstantType::kSmi);
1284     set_sub_minor_key(CellTypeBits::encode(type) |
1285                       ConstantTypeBits::encode(encoded_constant_type) |
1286                       CheckGlobalBits::encode(check_global));
1287   }
1288
1289   static Handle<HeapObject> property_cell_placeholder(Isolate* isolate) {
1290     return isolate->factory()->uninitialized_value();
1291   }
1292
1293   static Handle<HeapObject> global_map_placeholder(Isolate* isolate) {
1294     return isolate->factory()->termination_exception();
1295   }
1296
1297   Handle<Code> GetCodeCopyFromTemplate(Handle<GlobalObject> global,
1298                                        Handle<PropertyCell> cell) {
1299     Code::FindAndReplacePattern pattern;
1300     if (check_global()) {
1301       pattern.Add(handle(global_map_placeholder(isolate())->map()),
1302                   Map::WeakCellForMap(Handle<Map>(global->map())));
1303     }
1304     pattern.Add(handle(property_cell_placeholder(isolate())->map()),
1305                 isolate()->factory()->NewWeakCell(cell));
1306     return CodeStub::GetCodeCopy(pattern);
1307   }
1308
1309   Code::Kind kind() const override { return Code::STORE_IC; }
1310
1311   PropertyCellType cell_type() const {
1312     return CellTypeBits::decode(sub_minor_key());
1313   }
1314
1315   PropertyCellConstantType constant_type() const {
1316     DCHECK(PropertyCellType::kConstantType == cell_type());
1317     return ConstantTypeBits::decode(sub_minor_key());
1318   }
1319
1320   bool check_global() const { return CheckGlobalBits::decode(sub_minor_key()); }
1321
1322   Representation representation() {
1323     return Representation::FromKind(
1324         RepresentationBits::decode(sub_minor_key()));
1325   }
1326
1327   void set_representation(Representation r) {
1328     set_sub_minor_key(RepresentationBits::update(sub_minor_key(), r.kind()));
1329   }
1330
1331  private:
1332   class CellTypeBits : public BitField<PropertyCellType, 0, 2> {};
1333   class ConstantTypeBits : public BitField<PropertyCellConstantType, 2, 2> {};
1334   class RepresentationBits : public BitField<Representation::Kind, 4, 8> {};
1335   class CheckGlobalBits : public BitField<bool, 12, 1> {};
1336
1337   DEFINE_HANDLER_CODE_STUB(StoreGlobal, HandlerStub);
1338 };
1339
1340
1341 class CallApiFunctionStub : public PlatformCodeStub {
1342  public:
1343   explicit CallApiFunctionStub(Isolate* isolate, bool call_data_undefined)
1344       : PlatformCodeStub(isolate) {
1345     minor_key_ = CallDataUndefinedBits::encode(call_data_undefined);
1346   }
1347
1348  private:
1349   bool call_data_undefined() const {
1350     return CallDataUndefinedBits::decode(minor_key_);
1351   }
1352
1353   class CallDataUndefinedBits : public BitField<bool, 0, 1> {};
1354
1355   DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction);
1356   DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub);
1357 };
1358
1359
1360 class CallApiAccessorStub : public PlatformCodeStub {
1361  public:
1362   CallApiAccessorStub(Isolate* isolate, bool is_store, bool call_data_undefined)
1363       : PlatformCodeStub(isolate) {
1364     minor_key_ = IsStoreBits::encode(is_store) |
1365                  CallDataUndefinedBits::encode(call_data_undefined) |
1366                  ArgumentBits::encode(is_store ? 1 : 0);
1367   }
1368
1369  protected:
1370   // For CallApiFunctionWithFixedArgsStub, see below.
1371   static const int kArgBits = 3;
1372   CallApiAccessorStub(Isolate* isolate, int argc, bool call_data_undefined)
1373       : PlatformCodeStub(isolate) {
1374     minor_key_ = IsStoreBits::encode(false) |
1375                  CallDataUndefinedBits::encode(call_data_undefined) |
1376                  ArgumentBits::encode(argc);
1377   }
1378
1379  private:
1380   bool is_store() const { return IsStoreBits::decode(minor_key_); }
1381   bool call_data_undefined() const {
1382     return CallDataUndefinedBits::decode(minor_key_);
1383   }
1384   int argc() const { return ArgumentBits::decode(minor_key_); }
1385
1386   class IsStoreBits: public BitField<bool, 0, 1> {};
1387   class CallDataUndefinedBits: public BitField<bool, 1, 1> {};
1388   class ArgumentBits : public BitField<int, 2, kArgBits> {};
1389
1390   DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiAccessor);
1391   DEFINE_PLATFORM_CODE_STUB(CallApiAccessor, PlatformCodeStub);
1392 };
1393
1394
1395 // TODO(dcarney): see if it's possible to remove this later without performance
1396 // degradation.
1397 // This is not a real stub, but a way of generating the CallApiAccessorStub
1398 // (which has the same abi) which makes it clear that it is not an accessor.
1399 class CallApiFunctionWithFixedArgsStub : public CallApiAccessorStub {
1400  public:
1401   static const int kMaxFixedArgs = (1 << kArgBits) - 1;
1402   CallApiFunctionWithFixedArgsStub(Isolate* isolate, int argc,
1403                                    bool call_data_undefined)
1404       : CallApiAccessorStub(isolate, argc, call_data_undefined) {
1405     DCHECK(0 <= argc && argc <= kMaxFixedArgs);
1406   }
1407 };
1408
1409
1410 typedef ApiAccessorDescriptor ApiFunctionWithFixedArgsDescriptor;
1411
1412
1413 class CallApiGetterStub : public PlatformCodeStub {
1414  public:
1415   explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
1416
1417   DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
1418   DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
1419 };
1420
1421
1422 class BinaryOpICStub : public HydrogenCodeStub {
1423  public:
1424   BinaryOpICStub(Isolate* isolate, Token::Value op, LanguageMode language_mode)
1425       : HydrogenCodeStub(isolate, UNINITIALIZED) {
1426     BinaryOpICState state(isolate, op, language_mode);
1427     set_sub_minor_key(state.GetExtraICState());
1428   }
1429
1430   BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
1431       : HydrogenCodeStub(isolate) {
1432     set_sub_minor_key(state.GetExtraICState());
1433   }
1434
1435   static void GenerateAheadOfTime(Isolate* isolate);
1436
1437   Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
1438
1439   InlineCacheState GetICState() const final { return state().GetICState(); }
1440
1441   ExtraICState GetExtraICState() const final {
1442     return static_cast<ExtraICState>(sub_minor_key());
1443   }
1444
1445   BinaryOpICState state() const {
1446     return BinaryOpICState(isolate(), GetExtraICState());
1447   }
1448
1449   void PrintState(std::ostream& os) const final;  // NOLINT
1450
1451   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1452   static const int kLeft = 0;
1453   static const int kRight = 1;
1454
1455  private:
1456   static void GenerateAheadOfTime(Isolate* isolate,
1457                                   const BinaryOpICState& state);
1458
1459   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1460   DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
1461 };
1462
1463
1464 // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
1465 // call support for stubs in Hydrogen.
1466 class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
1467  public:
1468   BinaryOpICWithAllocationSiteStub(Isolate* isolate,
1469                                    const BinaryOpICState& state)
1470       : PlatformCodeStub(isolate) {
1471     minor_key_ = state.GetExtraICState();
1472   }
1473
1474   static void GenerateAheadOfTime(Isolate* isolate);
1475
1476   Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
1477     Code::FindAndReplacePattern pattern;
1478     pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
1479     return CodeStub::GetCodeCopy(pattern);
1480   }
1481
1482   Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
1483
1484   InlineCacheState GetICState() const override { return state().GetICState(); }
1485
1486   ExtraICState GetExtraICState() const override {
1487     return static_cast<ExtraICState>(minor_key_);
1488   }
1489
1490   void PrintState(std::ostream& os) const override;  // NOLINT
1491
1492  private:
1493   BinaryOpICState state() const {
1494     return BinaryOpICState(isolate(), static_cast<ExtraICState>(minor_key_));
1495   }
1496
1497   static void GenerateAheadOfTime(Isolate* isolate,
1498                                   const BinaryOpICState& state);
1499
1500   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1501   DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
1502 };
1503
1504
1505 class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
1506  public:
1507   BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op,
1508                                  LanguageMode language_mode)
1509       : BinaryOpICStub(isolate, op, language_mode) {}
1510
1511   BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
1512       : BinaryOpICStub(isolate, state) {}
1513
1514   Code::Kind GetCodeKind() const final { return Code::STUB; }
1515
1516   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1517   static const int kAllocationSite = 0;
1518   static const int kLeft = 1;
1519   static const int kRight = 2;
1520
1521   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
1522   DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub);
1523 };
1524
1525
1526 class StringAddStub final : public HydrogenCodeStub {
1527  public:
1528   StringAddStub(Isolate* isolate, StringAddFlags flags,
1529                 PretenureFlag pretenure_flag)
1530       : HydrogenCodeStub(isolate) {
1531     set_sub_minor_key(StringAddFlagsBits::encode(flags) |
1532                       PretenureFlagBits::encode(pretenure_flag));
1533   }
1534
1535   StringAddFlags flags() const {
1536     return StringAddFlagsBits::decode(sub_minor_key());
1537   }
1538
1539   PretenureFlag pretenure_flag() const {
1540     return PretenureFlagBits::decode(sub_minor_key());
1541   }
1542
1543   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1544   static const int kLeft = 0;
1545   static const int kRight = 1;
1546
1547  private:
1548   class StringAddFlagsBits: public BitField<StringAddFlags, 0, 2> {};
1549   class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {};
1550
1551   void PrintBaseName(std::ostream& os) const override;  // NOLINT
1552
1553   DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
1554   DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub);
1555 };
1556
1557
1558 class CompareICStub : public PlatformCodeStub {
1559  public:
1560   CompareICStub(Isolate* isolate, Token::Value op, bool strong,
1561                 CompareICState::State left, CompareICState::State right,
1562                 CompareICState::State state)
1563       : PlatformCodeStub(isolate) {
1564     DCHECK(Token::IsCompareOp(op));
1565     minor_key_ = OpBits::encode(op - Token::EQ) | StrongBits::encode(strong) |
1566                  LeftStateBits::encode(left) | RightStateBits::encode(right) |
1567                  StateBits::encode(state);
1568   }
1569
1570   void set_known_map(Handle<Map> map) { known_map_ = map; }
1571
1572   InlineCacheState GetICState() const override;
1573
1574   Token::Value op() const {
1575     return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
1576   }
1577
1578   bool strong() const { return StrongBits::decode(minor_key_); }
1579
1580   CompareICState::State left() const {
1581     return LeftStateBits::decode(minor_key_);
1582   }
1583   CompareICState::State right() const {
1584     return RightStateBits::decode(minor_key_);
1585   }
1586   CompareICState::State state() const { return StateBits::decode(minor_key_); }
1587
1588  private:
1589   Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
1590
1591   void GenerateSmis(MacroAssembler* masm);
1592   void GenerateNumbers(MacroAssembler* masm);
1593   void GenerateInternalizedStrings(MacroAssembler* masm);
1594   void GenerateStrings(MacroAssembler* masm);
1595   void GenerateUniqueNames(MacroAssembler* masm);
1596   void GenerateObjects(MacroAssembler* masm);
1597   void GenerateMiss(MacroAssembler* masm);
1598   void GenerateKnownObjects(MacroAssembler* masm);
1599   void GenerateGeneric(MacroAssembler* masm);
1600
1601   bool strict() const { return op() == Token::EQ_STRICT; }
1602   Condition GetCondition() const;
1603
1604   void AddToSpecialCache(Handle<Code> new_object) override;
1605   bool FindCodeInSpecialCache(Code** code_out) override;
1606   bool UseSpecialCache() override {
1607     return state() == CompareICState::KNOWN_OBJECT;
1608   }
1609
1610   class OpBits : public BitField<int, 0, 3> {};
1611   class StrongBits : public BitField<bool, 3, 1> {};
1612   class LeftStateBits : public BitField<CompareICState::State, 4, 4> {};
1613   class RightStateBits : public BitField<CompareICState::State, 8, 4> {};
1614   class StateBits : public BitField<CompareICState::State, 12, 4> {};
1615
1616   Handle<Map> known_map_;
1617
1618   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
1619   DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub);
1620 };
1621
1622
1623 class CompareNilICStub : public HydrogenCodeStub  {
1624  public:
1625   Type* GetType(Zone* zone, Handle<Map> map = Handle<Map>());
1626   Type* GetInputType(Zone* zone, Handle<Map> map);
1627
1628   CompareNilICStub(Isolate* isolate, NilValue nil) : HydrogenCodeStub(isolate) {
1629     set_sub_minor_key(NilValueBits::encode(nil));
1630   }
1631
1632   CompareNilICStub(Isolate* isolate, ExtraICState ic_state,
1633                    InitializationState init_state = INITIALIZED)
1634       : HydrogenCodeStub(isolate, init_state) {
1635     set_sub_minor_key(ic_state);
1636   }
1637
1638   static Handle<Code> GetUninitialized(Isolate* isolate,
1639                                        NilValue nil) {
1640     return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode();
1641   }
1642
1643   InlineCacheState GetICState() const override {
1644     State state = this->state();
1645     if (state.Contains(GENERIC)) {
1646       return MEGAMORPHIC;
1647     } else if (state.Contains(MONOMORPHIC_MAP)) {
1648       return MONOMORPHIC;
1649     } else {
1650       return PREMONOMORPHIC;
1651     }
1652   }
1653
1654   Code::Kind GetCodeKind() const override { return Code::COMPARE_NIL_IC; }
1655
1656   ExtraICState GetExtraICState() const override { return sub_minor_key(); }
1657
1658   void UpdateStatus(Handle<Object> object);
1659
1660   bool IsMonomorphic() const { return state().Contains(MONOMORPHIC_MAP); }
1661
1662   NilValue nil_value() const { return NilValueBits::decode(sub_minor_key()); }
1663
1664   void ClearState() {
1665     set_sub_minor_key(TypesBits::update(sub_minor_key(), 0));
1666   }
1667
1668   void PrintState(std::ostream& os) const override;     // NOLINT
1669   void PrintBaseName(std::ostream& os) const override;  // NOLINT
1670
1671  private:
1672   CompareNilICStub(Isolate* isolate, NilValue nil,
1673                    InitializationState init_state)
1674       : HydrogenCodeStub(isolate, init_state) {
1675     set_sub_minor_key(NilValueBits::encode(nil));
1676   }
1677
1678   enum CompareNilType {
1679     UNDEFINED,
1680     NULL_TYPE,
1681     MONOMORPHIC_MAP,
1682     GENERIC,
1683     NUMBER_OF_TYPES
1684   };
1685
1686   // At most 6 different types can be distinguished, because the Code object
1687   // only has room for a single byte to hold a set and there are two more
1688   // boolean flags we need to store. :-P
1689   STATIC_ASSERT(NUMBER_OF_TYPES <= 6);
1690
1691   class State : public EnumSet<CompareNilType, byte> {
1692    public:
1693     State() : EnumSet<CompareNilType, byte>(0) { }
1694     explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { }
1695   };
1696   friend std::ostream& operator<<(std::ostream& os, const State& s);
1697
1698   State state() const { return State(TypesBits::decode(sub_minor_key())); }
1699
1700   class NilValueBits : public BitField<NilValue, 0, 1> {};
1701   class TypesBits : public BitField<byte, 1, NUMBER_OF_TYPES> {};
1702
1703   friend class CompareNilIC;
1704
1705   DEFINE_CALL_INTERFACE_DESCRIPTOR(CompareNil);
1706   DEFINE_HYDROGEN_CODE_STUB(CompareNilIC, HydrogenCodeStub);
1707 };
1708
1709
1710 std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s);
1711
1712
1713 class CEntryStub : public PlatformCodeStub {
1714  public:
1715   CEntryStub(Isolate* isolate, int result_size,
1716              SaveFPRegsMode save_doubles = kDontSaveFPRegs)
1717       : PlatformCodeStub(isolate) {
1718     minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs);
1719     DCHECK(result_size == 1 || result_size == 2);
1720 #if _WIN64 || V8_TARGET_ARCH_PPC
1721     minor_key_ = ResultSizeBits::update(minor_key_, result_size);
1722 #endif  // _WIN64
1723   }
1724
1725   // The version of this stub that doesn't save doubles is generated ahead of
1726   // time, so it's OK to call it from other stubs that can't cope with GC during
1727   // their code generation.  On machines that always have gp registers (x64) we
1728   // can generate both variants ahead of time.
1729   static void GenerateAheadOfTime(Isolate* isolate);
1730
1731  private:
1732   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
1733 #if _WIN64 || V8_TARGET_ARCH_PPC
1734   int result_size() const { return ResultSizeBits::decode(minor_key_); }
1735 #endif  // _WIN64
1736
1737   bool NeedsImmovableCode() override;
1738
1739   class SaveDoublesBits : public BitField<bool, 0, 1> {};
1740   class ResultSizeBits : public BitField<int, 1, 3> {};
1741
1742   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1743   DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
1744 };
1745
1746
1747 class JSEntryStub : public PlatformCodeStub {
1748  public:
1749   JSEntryStub(Isolate* isolate, StackFrame::Type type)
1750       : PlatformCodeStub(isolate) {
1751     DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT);
1752     minor_key_ = StackFrameTypeBits::encode(type);
1753   }
1754
1755  private:
1756   void FinishCode(Handle<Code> code) override;
1757
1758   void PrintName(std::ostream& os) const override {  // NOLINT
1759     os << (type() == StackFrame::ENTRY ? "JSEntryStub"
1760                                        : "JSConstructEntryStub");
1761   }
1762
1763   StackFrame::Type type() const {
1764     return StackFrameTypeBits::decode(minor_key_);
1765   }
1766
1767   class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {};
1768
1769   int handler_offset_;
1770
1771   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
1772   DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
1773 };
1774
1775
1776 class ArgumentsAccessStub: public PlatformCodeStub {
1777  public:
1778   enum Type {
1779     READ_ELEMENT,
1780     NEW_SLOPPY_FAST,
1781     NEW_SLOPPY_SLOW,
1782     NEW_STRICT
1783   };
1784
1785   enum HasNewTarget { NO_NEW_TARGET, HAS_NEW_TARGET };
1786
1787   ArgumentsAccessStub(Isolate* isolate, Type type,
1788                       HasNewTarget has_new_target = NO_NEW_TARGET)
1789       : PlatformCodeStub(isolate) {
1790     minor_key_ =
1791         TypeBits::encode(type) | HasNewTargetBits::encode(has_new_target);
1792   }
1793
1794   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
1795     if (type() == READ_ELEMENT) {
1796       return ArgumentsAccessReadDescriptor(isolate());
1797     }
1798     return ContextOnlyDescriptor(isolate());
1799   }
1800
1801  private:
1802   Type type() const { return TypeBits::decode(minor_key_); }
1803   bool has_new_target() const {
1804     return HasNewTargetBits::decode(minor_key_) == HAS_NEW_TARGET;
1805   }
1806
1807   void GenerateReadElement(MacroAssembler* masm);
1808   void GenerateNewStrict(MacroAssembler* masm);
1809   void GenerateNewSloppyFast(MacroAssembler* masm);
1810   void GenerateNewSloppySlow(MacroAssembler* masm);
1811
1812   void PrintName(std::ostream& os) const override;  // NOLINT
1813
1814   class TypeBits : public BitField<Type, 0, 2> {};
1815   class HasNewTargetBits : public BitField<HasNewTarget, 2, 1> {};
1816
1817   DEFINE_PLATFORM_CODE_STUB(ArgumentsAccess, PlatformCodeStub);
1818 };
1819
1820
1821 class RestParamAccessStub: public PlatformCodeStub {
1822  public:
1823   explicit RestParamAccessStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
1824
1825   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
1826     return ContextOnlyDescriptor(isolate());
1827   }
1828
1829  private:
1830   void GenerateNew(MacroAssembler* masm);
1831
1832   void PrintName(std::ostream& os) const override;  // NOLINT
1833
1834   DEFINE_PLATFORM_CODE_STUB(RestParamAccess, PlatformCodeStub);
1835 };
1836
1837
1838 class RegExpExecStub: public PlatformCodeStub {
1839  public:
1840   explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
1841
1842   DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
1843   DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub);
1844 };
1845
1846
1847 class RegExpConstructResultStub final : public HydrogenCodeStub {
1848  public:
1849   explicit RegExpConstructResultStub(Isolate* isolate)
1850       : HydrogenCodeStub(isolate) { }
1851
1852   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1853   static const int kLength = 0;
1854   static const int kIndex = 1;
1855   static const int kInput = 2;
1856
1857   DEFINE_CALL_INTERFACE_DESCRIPTOR(RegExpConstructResult);
1858   DEFINE_HYDROGEN_CODE_STUB(RegExpConstructResult, HydrogenCodeStub);
1859 };
1860
1861
1862 class CallFunctionStub: public PlatformCodeStub {
1863  public:
1864   CallFunctionStub(Isolate* isolate, int argc, CallFunctionFlags flags)
1865       : PlatformCodeStub(isolate) {
1866     DCHECK(argc >= 0 && argc <= Code::kMaxArguments);
1867     minor_key_ = ArgcBits::encode(argc) | FlagBits::encode(flags);
1868   }
1869
1870   static int ExtractArgcFromMinorKey(int minor_key) {
1871     return ArgcBits::decode(minor_key);
1872   }
1873
1874  private:
1875   int argc() const { return ArgcBits::decode(minor_key_); }
1876   int flags() const { return FlagBits::decode(minor_key_); }
1877
1878   bool CallAsMethod() const {
1879     return flags() == CALL_AS_METHOD || flags() == WRAP_AND_CALL;
1880   }
1881
1882   bool NeedsChecks() const { return flags() != WRAP_AND_CALL; }
1883
1884   void PrintName(std::ostream& os) const override;  // NOLINT
1885
1886   // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
1887   class FlagBits : public BitField<CallFunctionFlags, 0, 2> {};
1888   class ArgcBits : public BitField<unsigned, 2, Code::kArgumentsBits> {};
1889   STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits);
1890
1891   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction);
1892   DEFINE_PLATFORM_CODE_STUB(CallFunction, PlatformCodeStub);
1893 };
1894
1895
1896 class CallConstructStub: public PlatformCodeStub {
1897  public:
1898   CallConstructStub(Isolate* isolate, CallConstructorFlags flags)
1899       : PlatformCodeStub(isolate) {
1900     minor_key_ = FlagBits::encode(flags);
1901   }
1902
1903   void FinishCode(Handle<Code> code) override {
1904     code->set_has_function_cache(RecordCallTarget());
1905   }
1906
1907  private:
1908   CallConstructorFlags flags() const { return FlagBits::decode(minor_key_); }
1909
1910   bool RecordCallTarget() const {
1911     return (flags() & RECORD_CONSTRUCTOR_TARGET) != 0;
1912   }
1913
1914   bool IsSuperConstructorCall() const {
1915     return (flags() & SUPER_CONSTRUCTOR_CALL) != 0;
1916   }
1917
1918   void PrintName(std::ostream& os) const override;  // NOLINT
1919
1920   class FlagBits : public BitField<CallConstructorFlags, 0, 2> {};
1921
1922   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
1923   DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
1924 };
1925
1926
1927 enum StringIndexFlags {
1928   // Accepts smis or heap numbers.
1929   STRING_INDEX_IS_NUMBER,
1930
1931   // Accepts smis or heap numbers that are valid array indices
1932   // (ECMA-262 15.4). Invalid indices are reported as being out of
1933   // range.
1934   STRING_INDEX_IS_ARRAY_INDEX
1935 };
1936
1937
1938 enum ReceiverCheckMode {
1939   // We don't know anything about the receiver.
1940   RECEIVER_IS_UNKNOWN,
1941
1942   // We know the receiver is a string.
1943   RECEIVER_IS_STRING
1944 };
1945
1946
1947 enum EmbedMode {
1948   // The code being generated is part of an IC handler, which may MISS
1949   // to an IC in failure cases.
1950   PART_OF_IC_HANDLER,
1951
1952   NOT_PART_OF_IC_HANDLER
1953 };
1954
1955
1956 // Generates code implementing String.prototype.charCodeAt.
1957 //
1958 // Only supports the case when the receiver is a string and the index
1959 // is a number (smi or heap number) that is a valid index into the
1960 // string. Additional index constraints are specified by the
1961 // flags. Otherwise, bails out to the provided labels.
1962 //
1963 // Register usage: |object| may be changed to another string in a way
1964 // that doesn't affect charCodeAt/charAt semantics, |index| is
1965 // preserved, |scratch| and |result| are clobbered.
1966 class StringCharCodeAtGenerator {
1967  public:
1968   StringCharCodeAtGenerator(Register object, Register index, Register result,
1969                             Label* receiver_not_string, Label* index_not_number,
1970                             Label* index_out_of_range,
1971                             StringIndexFlags index_flags,
1972                             ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
1973       : object_(object),
1974         index_(index),
1975         result_(result),
1976         receiver_not_string_(receiver_not_string),
1977         index_not_number_(index_not_number),
1978         index_out_of_range_(index_out_of_range),
1979         index_flags_(index_flags),
1980         check_mode_(check_mode) {
1981     DCHECK(!result_.is(object_));
1982     DCHECK(!result_.is(index_));
1983   }
1984
1985   // Generates the fast case code. On the fallthrough path |result|
1986   // register contains the result.
1987   void GenerateFast(MacroAssembler* masm);
1988
1989   // Generates the slow case code. Must not be naturally
1990   // reachable. Expected to be put after a ret instruction (e.g., in
1991   // deferred code). Always jumps back to the fast case.
1992   void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
1993                     const RuntimeCallHelper& call_helper);
1994
1995   // Skip handling slow case and directly jump to bailout.
1996   void SkipSlow(MacroAssembler* masm, Label* bailout) {
1997     masm->bind(&index_not_smi_);
1998     masm->bind(&call_runtime_);
1999     masm->jmp(bailout);
2000   }
2001
2002  private:
2003   Register object_;
2004   Register index_;
2005   Register result_;
2006
2007   Label* receiver_not_string_;
2008   Label* index_not_number_;
2009   Label* index_out_of_range_;
2010
2011   StringIndexFlags index_flags_;
2012   ReceiverCheckMode check_mode_;
2013
2014   Label call_runtime_;
2015   Label index_not_smi_;
2016   Label got_smi_index_;
2017   Label exit_;
2018
2019   DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
2020 };
2021
2022
2023 // Generates code for creating a one-char string from a char code.
2024 class StringCharFromCodeGenerator {
2025  public:
2026   StringCharFromCodeGenerator(Register code,
2027                               Register result)
2028       : code_(code),
2029         result_(result) {
2030     DCHECK(!code_.is(result_));
2031   }
2032
2033   // Generates the fast case code. On the fallthrough path |result|
2034   // register contains the result.
2035   void GenerateFast(MacroAssembler* masm);
2036
2037   // Generates the slow case code. Must not be naturally
2038   // reachable. Expected to be put after a ret instruction (e.g., in
2039   // deferred code). Always jumps back to the fast case.
2040   void GenerateSlow(MacroAssembler* masm,
2041                     const RuntimeCallHelper& call_helper);
2042
2043   // Skip handling slow case and directly jump to bailout.
2044   void SkipSlow(MacroAssembler* masm, Label* bailout) {
2045     masm->bind(&slow_case_);
2046     masm->jmp(bailout);
2047   }
2048
2049  private:
2050   Register code_;
2051   Register result_;
2052
2053   Label slow_case_;
2054   Label exit_;
2055
2056   DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator);
2057 };
2058
2059
2060 // Generates code implementing String.prototype.charAt.
2061 //
2062 // Only supports the case when the receiver is a string and the index
2063 // is a number (smi or heap number) that is a valid index into the
2064 // string. Additional index constraints are specified by the
2065 // flags. Otherwise, bails out to the provided labels.
2066 //
2067 // Register usage: |object| may be changed to another string in a way
2068 // that doesn't affect charCodeAt/charAt semantics, |index| is
2069 // preserved, |scratch1|, |scratch2|, and |result| are clobbered.
2070 class StringCharAtGenerator {
2071  public:
2072   StringCharAtGenerator(Register object, Register index, Register scratch,
2073                         Register result, Label* receiver_not_string,
2074                         Label* index_not_number, Label* index_out_of_range,
2075                         StringIndexFlags index_flags,
2076                         ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
2077       : char_code_at_generator_(object, index, scratch, receiver_not_string,
2078                                 index_not_number, index_out_of_range,
2079                                 index_flags, check_mode),
2080         char_from_code_generator_(scratch, result) {}
2081
2082   // Generates the fast case code. On the fallthrough path |result|
2083   // register contains the result.
2084   void GenerateFast(MacroAssembler* masm) {
2085     char_code_at_generator_.GenerateFast(masm);
2086     char_from_code_generator_.GenerateFast(masm);
2087   }
2088
2089   // Generates the slow case code. Must not be naturally
2090   // reachable. Expected to be put after a ret instruction (e.g., in
2091   // deferred code). Always jumps back to the fast case.
2092   void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
2093                     const RuntimeCallHelper& call_helper) {
2094     char_code_at_generator_.GenerateSlow(masm, embed_mode, call_helper);
2095     char_from_code_generator_.GenerateSlow(masm, call_helper);
2096   }
2097
2098   // Skip handling slow case and directly jump to bailout.
2099   void SkipSlow(MacroAssembler* masm, Label* bailout) {
2100     char_code_at_generator_.SkipSlow(masm, bailout);
2101     char_from_code_generator_.SkipSlow(masm, bailout);
2102   }
2103
2104  private:
2105   StringCharCodeAtGenerator char_code_at_generator_;
2106   StringCharFromCodeGenerator char_from_code_generator_;
2107
2108   DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator);
2109 };
2110
2111
2112 class LoadDictionaryElementStub : public HydrogenCodeStub {
2113  public:
2114   explicit LoadDictionaryElementStub(Isolate* isolate)
2115       : HydrogenCodeStub(isolate) {}
2116
2117   CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
2118     return LoadWithVectorDescriptor(isolate());
2119   }
2120
2121   DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
2122 };
2123
2124
2125 class KeyedLoadGenericStub : public HydrogenCodeStub {
2126  public:
2127   explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
2128
2129   Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2130   InlineCacheState GetICState() const override { return GENERIC; }
2131
2132   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
2133
2134   DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
2135 };
2136
2137
2138 class LoadICTrampolineStub : public PlatformCodeStub {
2139  public:
2140   LoadICTrampolineStub(Isolate* isolate, const LoadICState& state)
2141       : PlatformCodeStub(isolate) {
2142     minor_key_ = state.GetExtraICState();
2143   }
2144
2145   Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
2146
2147   InlineCacheState GetICState() const final { return DEFAULT; }
2148
2149   ExtraICState GetExtraICState() const final {
2150     return static_cast<ExtraICState>(minor_key_);
2151   }
2152
2153  private:
2154   LoadICState state() const {
2155     return LoadICState(static_cast<ExtraICState>(minor_key_));
2156   }
2157
2158   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
2159   DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub);
2160 };
2161
2162
2163 class KeyedLoadICTrampolineStub : public LoadICTrampolineStub {
2164  public:
2165   explicit KeyedLoadICTrampolineStub(Isolate* isolate)
2166       : LoadICTrampolineStub(isolate, LoadICState(0)) {}
2167
2168   Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2169
2170   DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub);
2171 };
2172
2173
2174 class VectorStoreICTrampolineStub : public PlatformCodeStub {
2175  public:
2176   VectorStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2177       : PlatformCodeStub(isolate) {
2178     minor_key_ = state.GetExtraICState();
2179   }
2180
2181   Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
2182
2183   InlineCacheState GetICState() const final { return DEFAULT; }
2184
2185   ExtraICState GetExtraICState() const final {
2186     return static_cast<ExtraICState>(minor_key_);
2187   }
2188
2189  protected:
2190   StoreICState state() const {
2191     return StoreICState(static_cast<ExtraICState>(minor_key_));
2192   }
2193
2194  private:
2195   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreICTrampoline);
2196   DEFINE_PLATFORM_CODE_STUB(VectorStoreICTrampoline, PlatformCodeStub);
2197 };
2198
2199
2200 class VectorKeyedStoreICTrampolineStub : public VectorStoreICTrampolineStub {
2201  public:
2202   VectorKeyedStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
2203       : VectorStoreICTrampolineStub(isolate, state) {}
2204
2205   Code::Kind GetCodeKind() const override { return Code::KEYED_STORE_IC; }
2206
2207   DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreICTrampoline,
2208                             VectorStoreICTrampolineStub);
2209 };
2210
2211
2212 class CallICTrampolineStub : public PlatformCodeStub {
2213  public:
2214   CallICTrampolineStub(Isolate* isolate, const CallICState& state)
2215       : PlatformCodeStub(isolate) {
2216     minor_key_ = state.GetExtraICState();
2217   }
2218
2219   Code::Kind GetCodeKind() const override { return Code::CALL_IC; }
2220
2221   InlineCacheState GetICState() const final { return DEFAULT; }
2222
2223   ExtraICState GetExtraICState() const final {
2224     return static_cast<ExtraICState>(minor_key_);
2225   }
2226
2227  protected:
2228   CallICState state() const {
2229     return CallICState(static_cast<ExtraICState>(minor_key_));
2230   }
2231
2232   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
2233   DEFINE_PLATFORM_CODE_STUB(CallICTrampoline, PlatformCodeStub);
2234 };
2235
2236
2237 class CallIC_ArrayTrampolineStub : public CallICTrampolineStub {
2238  public:
2239   CallIC_ArrayTrampolineStub(Isolate* isolate, const CallICState& state)
2240       : CallICTrampolineStub(isolate, state) {}
2241
2242  private:
2243   DEFINE_PLATFORM_CODE_STUB(CallIC_ArrayTrampoline, CallICTrampolineStub);
2244 };
2245
2246
2247 class LoadICStub : public PlatformCodeStub {
2248  public:
2249   explicit LoadICStub(Isolate* isolate, const LoadICState& state)
2250       : PlatformCodeStub(isolate) {
2251     minor_key_ = state.GetExtraICState();
2252   }
2253
2254   void GenerateForTrampoline(MacroAssembler* masm);
2255
2256   Code::Kind GetCodeKind() const override { return Code::LOAD_IC; }
2257   InlineCacheState GetICState() const final { return DEFAULT; }
2258   ExtraICState GetExtraICState() const final {
2259     return static_cast<ExtraICState>(minor_key_);
2260   }
2261
2262   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2263   DEFINE_PLATFORM_CODE_STUB(LoadIC, PlatformCodeStub);
2264
2265  protected:
2266   void GenerateImpl(MacroAssembler* masm, bool in_frame);
2267 };
2268
2269
2270 class KeyedLoadICStub : public PlatformCodeStub {
2271  public:
2272   explicit KeyedLoadICStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
2273
2274   void GenerateForTrampoline(MacroAssembler* masm);
2275
2276   Code::Kind GetCodeKind() const override { return Code::KEYED_LOAD_IC; }
2277   InlineCacheState GetICState() const final { return DEFAULT; }
2278
2279   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
2280   DEFINE_PLATFORM_CODE_STUB(KeyedLoadIC, PlatformCodeStub);
2281
2282  protected:
2283   void GenerateImpl(MacroAssembler* masm, bool in_frame);
2284 };
2285
2286
2287 class VectorStoreICStub : public PlatformCodeStub {
2288  public:
2289   VectorStoreICStub(Isolate* isolate, const StoreICState& state)
2290       : PlatformCodeStub(isolate) {
2291     minor_key_ = state.GetExtraICState();
2292   }
2293
2294   void GenerateForTrampoline(MacroAssembler* masm);
2295
2296   Code::Kind GetCodeKind() const final { return Code::STORE_IC; }
2297   InlineCacheState GetICState() const final { return DEFAULT; }
2298   ExtraICState GetExtraICState() const final {
2299     return static_cast<ExtraICState>(minor_key_);
2300   }
2301
2302   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2303   DEFINE_PLATFORM_CODE_STUB(VectorStoreIC, PlatformCodeStub);
2304
2305  protected:
2306   void GenerateImpl(MacroAssembler* masm, bool in_frame);
2307 };
2308
2309
2310 class VectorKeyedStoreICStub : public PlatformCodeStub {
2311  public:
2312   VectorKeyedStoreICStub(Isolate* isolate, const StoreICState& state)
2313       : PlatformCodeStub(isolate) {
2314     minor_key_ = state.GetExtraICState();
2315   }
2316
2317   void GenerateForTrampoline(MacroAssembler* masm);
2318
2319   Code::Kind GetCodeKind() const final { return Code::KEYED_STORE_IC; }
2320   InlineCacheState GetICState() const final { return DEFAULT; }
2321
2322   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorStoreIC);
2323   DEFINE_PLATFORM_CODE_STUB(VectorKeyedStoreIC, PlatformCodeStub);
2324
2325  protected:
2326   void GenerateImpl(MacroAssembler* masm, bool in_frame);
2327 };
2328
2329
2330 class DoubleToIStub : public PlatformCodeStub {
2331  public:
2332   DoubleToIStub(Isolate* isolate, Register source, Register destination,
2333                 int offset, bool is_truncating, bool skip_fastpath = false)
2334       : PlatformCodeStub(isolate) {
2335     minor_key_ = SourceRegisterBits::encode(source.code()) |
2336                  DestinationRegisterBits::encode(destination.code()) |
2337                  OffsetBits::encode(offset) |
2338                  IsTruncatingBits::encode(is_truncating) |
2339                  SkipFastPathBits::encode(skip_fastpath) |
2340                  SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
2341   }
2342
2343   bool SometimesSetsUpAFrame() override { return false; }
2344
2345  private:
2346   Register source() const {
2347     return Register::from_code(SourceRegisterBits::decode(minor_key_));
2348   }
2349   Register destination() const {
2350     return Register::from_code(DestinationRegisterBits::decode(minor_key_));
2351   }
2352   bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); }
2353   bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); }
2354   int offset() const { return OffsetBits::decode(minor_key_); }
2355
2356   static const int kBitsPerRegisterNumber = 6;
2357   STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
2358   class SourceRegisterBits:
2359       public BitField<int, 0, kBitsPerRegisterNumber> {};  // NOLINT
2360   class DestinationRegisterBits:
2361       public BitField<int, kBitsPerRegisterNumber,
2362         kBitsPerRegisterNumber> {};  // NOLINT
2363   class IsTruncatingBits:
2364       public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {};  // NOLINT
2365   class OffsetBits:
2366       public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {};  // NOLINT
2367   class SkipFastPathBits:
2368       public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {};  // NOLINT
2369   class SSE3Bits:
2370       public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {};  // NOLINT
2371
2372   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2373   DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
2374 };
2375
2376
2377 class ScriptContextFieldStub : public HandlerStub {
2378  public:
2379   ScriptContextFieldStub(Isolate* isolate,
2380                          const ScriptContextTable::LookupResult* lookup_result)
2381       : HandlerStub(isolate) {
2382     DCHECK(Accepted(lookup_result));
2383     set_sub_minor_key(ContextIndexBits::encode(lookup_result->context_index) |
2384                       SlotIndexBits::encode(lookup_result->slot_index));
2385   }
2386
2387   int context_index() const {
2388     return ContextIndexBits::decode(sub_minor_key());
2389   }
2390
2391   int slot_index() const { return SlotIndexBits::decode(sub_minor_key()); }
2392
2393   static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
2394     return ContextIndexBits::is_valid(lookup_result->context_index) &&
2395            SlotIndexBits::is_valid(lookup_result->slot_index);
2396   }
2397
2398  private:
2399   static const int kContextIndexBits = 13;
2400   static const int kSlotIndexBits = 13;
2401   class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
2402   class SlotIndexBits
2403       : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
2404
2405   Code::StubType GetStubType() const override { return Code::FAST; }
2406
2407   DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, HandlerStub);
2408 };
2409
2410
2411 class LoadScriptContextFieldStub : public ScriptContextFieldStub {
2412  public:
2413   LoadScriptContextFieldStub(
2414       Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2415       : ScriptContextFieldStub(isolate, lookup_result) {}
2416
2417  private:
2418   Code::Kind kind() const override { return Code::LOAD_IC; }
2419
2420   DEFINE_HANDLER_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
2421 };
2422
2423
2424 class StoreScriptContextFieldStub : public ScriptContextFieldStub {
2425  public:
2426   StoreScriptContextFieldStub(
2427       Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
2428       : ScriptContextFieldStub(isolate, lookup_result) {}
2429
2430  private:
2431   Code::Kind kind() const override { return Code::STORE_IC; }
2432
2433   DEFINE_HANDLER_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
2434 };
2435
2436
2437 class LoadFastElementStub : public HandlerStub {
2438  public:
2439   LoadFastElementStub(Isolate* isolate, bool is_js_array,
2440                       ElementsKind elements_kind,
2441                       bool convert_hole_to_undefined = false)
2442       : HandlerStub(isolate) {
2443     set_sub_minor_key(
2444         ElementsKindBits::encode(elements_kind) |
2445         IsJSArrayBits::encode(is_js_array) |
2446         CanConvertHoleToUndefined::encode(convert_hole_to_undefined));
2447   }
2448
2449   Code::Kind kind() const override { return Code::KEYED_LOAD_IC; }
2450
2451   bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2452   bool convert_hole_to_undefined() const {
2453     return CanConvertHoleToUndefined::decode(sub_minor_key());
2454   }
2455
2456   ElementsKind elements_kind() const {
2457     return ElementsKindBits::decode(sub_minor_key());
2458   }
2459
2460  private:
2461   class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2462   class IsJSArrayBits: public BitField<bool, 8, 1> {};
2463   class CanConvertHoleToUndefined : public BitField<bool, 9, 1> {};
2464
2465   DEFINE_HANDLER_CODE_STUB(LoadFastElement, HandlerStub);
2466 };
2467
2468
2469 class StoreFastElementStub : public HydrogenCodeStub {
2470  public:
2471   StoreFastElementStub(Isolate* isolate, bool is_js_array,
2472                        ElementsKind elements_kind, KeyedAccessStoreMode mode)
2473       : HydrogenCodeStub(isolate) {
2474     set_sub_minor_key(ElementsKindBits::encode(elements_kind) |
2475                       IsJSArrayBits::encode(is_js_array) |
2476                       StoreModeBits::encode(mode));
2477   }
2478
2479   static void GenerateAheadOfTime(Isolate* isolate);
2480
2481   bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2482
2483   ElementsKind elements_kind() const {
2484     return ElementsKindBits::decode(sub_minor_key());
2485   }
2486
2487   KeyedAccessStoreMode store_mode() const {
2488     return StoreModeBits::decode(sub_minor_key());
2489   }
2490
2491  private:
2492   class ElementsKindBits: public BitField<ElementsKind,      0, 8> {};
2493   class StoreModeBits: public BitField<KeyedAccessStoreMode, 8, 4> {};
2494   class IsJSArrayBits: public BitField<bool,                12, 1> {};
2495
2496   DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
2497   DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub);
2498 };
2499
2500
2501 class TransitionElementsKindStub : public HydrogenCodeStub {
2502  public:
2503   TransitionElementsKindStub(Isolate* isolate,
2504                              ElementsKind from_kind,
2505                              ElementsKind to_kind,
2506                              bool is_js_array) : HydrogenCodeStub(isolate) {
2507     set_sub_minor_key(FromKindBits::encode(from_kind) |
2508                       ToKindBits::encode(to_kind) |
2509                       IsJSArrayBits::encode(is_js_array));
2510   }
2511
2512   ElementsKind from_kind() const {
2513     return FromKindBits::decode(sub_minor_key());
2514   }
2515
2516   ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); }
2517
2518   bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); }
2519
2520  private:
2521   class FromKindBits: public BitField<ElementsKind, 8, 8> {};
2522   class ToKindBits: public BitField<ElementsKind, 0, 8> {};
2523   class IsJSArrayBits: public BitField<bool, 16, 1> {};
2524
2525   DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind);
2526   DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub);
2527 };
2528
2529
2530 class AllocateHeapNumberStub final : public HydrogenCodeStub {
2531  public:
2532   explicit AllocateHeapNumberStub(Isolate* isolate)
2533       : HydrogenCodeStub(isolate) {}
2534
2535  private:
2536   DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
2537   DEFINE_HYDROGEN_CODE_STUB(AllocateHeapNumber, HydrogenCodeStub);
2538 };
2539
2540
2541 class ArrayConstructorStubBase : public HydrogenCodeStub {
2542  public:
2543   ArrayConstructorStubBase(Isolate* isolate,
2544                            ElementsKind kind,
2545                            AllocationSiteOverrideMode override_mode)
2546       : HydrogenCodeStub(isolate) {
2547     // It only makes sense to override local allocation site behavior
2548     // if there is a difference between the global allocation site policy
2549     // for an ElementsKind and the desired usage of the stub.
2550     DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
2551            AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
2552     set_sub_minor_key(ElementsKindBits::encode(kind) |
2553                       AllocationSiteOverrideModeBits::encode(override_mode));
2554   }
2555
2556   ElementsKind elements_kind() const {
2557     return ElementsKindBits::decode(sub_minor_key());
2558   }
2559
2560   AllocationSiteOverrideMode override_mode() const {
2561     return AllocationSiteOverrideModeBits::decode(sub_minor_key());
2562   }
2563
2564   static void GenerateStubsAheadOfTime(Isolate* isolate);
2565
2566   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2567   static const int kConstructor = 0;
2568   static const int kAllocationSite = 1;
2569
2570  protected:
2571   std::ostream& BasePrintName(std::ostream& os,
2572                               const char* name) const;  // NOLINT
2573
2574  private:
2575   // Ensure data fits within available bits.
2576   STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
2577
2578   class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
2579   class AllocationSiteOverrideModeBits: public
2580       BitField<AllocationSiteOverrideMode, 8, 1> {};  // NOLINT
2581
2582   DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub);
2583 };
2584
2585
2586 class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
2587  public:
2588   ArrayNoArgumentConstructorStub(
2589       Isolate* isolate,
2590       ElementsKind kind,
2591       AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2592       : ArrayConstructorStubBase(isolate, kind, override_mode) {
2593   }
2594
2595  private:
2596   void PrintName(std::ostream& os) const override {  // NOLINT
2597     BasePrintName(os, "ArrayNoArgumentConstructorStub");
2598   }
2599
2600   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructorConstantArgCount);
2601   DEFINE_HYDROGEN_CODE_STUB(ArrayNoArgumentConstructor,
2602                             ArrayConstructorStubBase);
2603 };
2604
2605
2606 class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
2607  public:
2608   ArraySingleArgumentConstructorStub(
2609       Isolate* isolate,
2610       ElementsKind kind,
2611       AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2612       : ArrayConstructorStubBase(isolate, kind, override_mode) {
2613   }
2614
2615  private:
2616   void PrintName(std::ostream& os) const override {  // NOLINT
2617     BasePrintName(os, "ArraySingleArgumentConstructorStub");
2618   }
2619
2620   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2621   DEFINE_HYDROGEN_CODE_STUB(ArraySingleArgumentConstructor,
2622                             ArrayConstructorStubBase);
2623 };
2624
2625
2626 class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
2627  public:
2628   ArrayNArgumentsConstructorStub(
2629       Isolate* isolate,
2630       ElementsKind kind,
2631       AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
2632       : ArrayConstructorStubBase(isolate, kind, override_mode) {
2633   }
2634
2635  private:
2636   void PrintName(std::ostream& os) const override {  // NOLINT
2637     BasePrintName(os, "ArrayNArgumentsConstructorStub");
2638   }
2639
2640   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
2641   DEFINE_HYDROGEN_CODE_STUB(ArrayNArgumentsConstructor,
2642                             ArrayConstructorStubBase);
2643 };
2644
2645
2646 class InternalArrayConstructorStubBase : public HydrogenCodeStub {
2647  public:
2648   InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind)
2649       : HydrogenCodeStub(isolate) {
2650     set_sub_minor_key(ElementsKindBits::encode(kind));
2651   }
2652
2653   static void GenerateStubsAheadOfTime(Isolate* isolate);
2654
2655   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2656   static const int kConstructor = 0;
2657
2658   ElementsKind elements_kind() const {
2659     return ElementsKindBits::decode(sub_minor_key());
2660   }
2661
2662  private:
2663   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
2664
2665   DEFINE_CODE_STUB_BASE(InternalArrayConstructorStubBase, HydrogenCodeStub);
2666 };
2667
2668
2669 class InternalArrayNoArgumentConstructorStub : public
2670     InternalArrayConstructorStubBase {
2671  public:
2672   InternalArrayNoArgumentConstructorStub(Isolate* isolate,
2673                                          ElementsKind kind)
2674       : InternalArrayConstructorStubBase(isolate, kind) { }
2675
2676   DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructorConstantArgCount);
2677   DEFINE_HYDROGEN_CODE_STUB(InternalArrayNoArgumentConstructor,
2678                             InternalArrayConstructorStubBase);
2679 };
2680
2681
2682 class InternalArraySingleArgumentConstructorStub : public
2683     InternalArrayConstructorStubBase {
2684  public:
2685   InternalArraySingleArgumentConstructorStub(Isolate* isolate,
2686                                              ElementsKind kind)
2687       : InternalArrayConstructorStubBase(isolate, kind) { }
2688
2689   DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2690   DEFINE_HYDROGEN_CODE_STUB(InternalArraySingleArgumentConstructor,
2691                             InternalArrayConstructorStubBase);
2692 };
2693
2694
2695 class InternalArrayNArgumentsConstructorStub : public
2696     InternalArrayConstructorStubBase {
2697  public:
2698   InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind)
2699       : InternalArrayConstructorStubBase(isolate, kind) { }
2700
2701   DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
2702   DEFINE_HYDROGEN_CODE_STUB(InternalArrayNArgumentsConstructor,
2703                             InternalArrayConstructorStubBase);
2704 };
2705
2706
2707 class StoreElementStub : public PlatformCodeStub {
2708  public:
2709   StoreElementStub(Isolate* isolate, ElementsKind elements_kind)
2710       : PlatformCodeStub(isolate) {
2711     minor_key_ = ElementsKindBits::encode(elements_kind);
2712   }
2713
2714  private:
2715   ElementsKind elements_kind() const {
2716     return ElementsKindBits::decode(minor_key_);
2717   }
2718
2719   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
2720
2721   DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
2722   DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
2723 };
2724
2725
2726 class ToBooleanStub: public HydrogenCodeStub {
2727  public:
2728   enum Type {
2729     UNDEFINED,
2730     BOOLEAN,
2731     NULL_TYPE,
2732     SMI,
2733     SPEC_OBJECT,
2734     STRING,
2735     SYMBOL,
2736     HEAP_NUMBER,
2737     NUMBER_OF_TYPES
2738   };
2739
2740   enum ResultMode {
2741     RESULT_AS_SMI,             // For Smi(1) on truthy value, Smi(0) otherwise.
2742     RESULT_AS_ODDBALL,         // For {true} on truthy value, {false} otherwise.
2743     RESULT_AS_INVERSE_ODDBALL  // For {false} on truthy value, {true} otherwise.
2744   };
2745
2746   // At most 8 different types can be distinguished, because the Code object
2747   // only has room for a single byte to hold a set of these types. :-P
2748   STATIC_ASSERT(NUMBER_OF_TYPES <= 8);
2749
2750   class Types : public EnumSet<Type, byte> {
2751    public:
2752     Types() : EnumSet<Type, byte>(0) {}
2753     explicit Types(byte bits) : EnumSet<Type, byte>(bits) {}
2754
2755     byte ToByte() const { return ToIntegral(); }
2756     bool UpdateStatus(Handle<Object> object);
2757     bool NeedsMap() const;
2758     bool CanBeUndetectable() const;
2759     bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
2760
2761     static Types Generic() { return Types((1 << NUMBER_OF_TYPES) - 1); }
2762   };
2763
2764   ToBooleanStub(Isolate* isolate, ResultMode mode, Types types = Types())
2765       : HydrogenCodeStub(isolate) {
2766     set_sub_minor_key(TypesBits::encode(types.ToByte()) |
2767                       ResultModeBits::encode(mode));
2768   }
2769
2770   ToBooleanStub(Isolate* isolate, ExtraICState state)
2771       : HydrogenCodeStub(isolate) {
2772     set_sub_minor_key(TypesBits::encode(static_cast<byte>(state)) |
2773                       ResultModeBits::encode(RESULT_AS_SMI));
2774   }
2775
2776   bool UpdateStatus(Handle<Object> object);
2777   Types types() const { return Types(TypesBits::decode(sub_minor_key())); }
2778   ResultMode mode() const { return ResultModeBits::decode(sub_minor_key()); }
2779
2780   Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
2781   void PrintState(std::ostream& os) const override;  // NOLINT
2782
2783   bool SometimesSetsUpAFrame() override { return false; }
2784
2785   static Handle<Code> GetUninitialized(Isolate* isolate) {
2786     return ToBooleanStub(isolate, UNINITIALIZED).GetCode();
2787   }
2788
2789   ExtraICState GetExtraICState() const override { return types().ToIntegral(); }
2790
2791   InlineCacheState GetICState() const override {
2792     if (types().IsEmpty()) {
2793       return ::v8::internal::UNINITIALIZED;
2794     } else {
2795       return MONOMORPHIC;
2796     }
2797   }
2798
2799  private:
2800   ToBooleanStub(Isolate* isolate, InitializationState init_state)
2801       : HydrogenCodeStub(isolate, init_state) {
2802     set_sub_minor_key(ResultModeBits::encode(RESULT_AS_SMI));
2803   }
2804
2805   class TypesBits : public BitField<byte, 0, NUMBER_OF_TYPES> {};
2806   class ResultModeBits : public BitField<ResultMode, NUMBER_OF_TYPES, 2> {};
2807
2808   DEFINE_CALL_INTERFACE_DESCRIPTOR(ToBoolean);
2809   DEFINE_HYDROGEN_CODE_STUB(ToBoolean, HydrogenCodeStub);
2810 };
2811
2812
2813 std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& t);
2814
2815
2816 class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
2817  public:
2818   ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
2819                                  ElementsKind to_kind, bool is_jsarray,
2820                                  KeyedAccessStoreMode store_mode)
2821       : HydrogenCodeStub(isolate) {
2822     set_sub_minor_key(FromBits::encode(from_kind) | ToBits::encode(to_kind) |
2823                       IsJSArrayBits::encode(is_jsarray) |
2824                       StoreModeBits::encode(store_mode));
2825   }
2826
2827   ElementsKind from_kind() const { return FromBits::decode(sub_minor_key()); }
2828   ElementsKind to_kind() const { return ToBits::decode(sub_minor_key()); }
2829   bool is_jsarray() const { return IsJSArrayBits::decode(sub_minor_key()); }
2830   KeyedAccessStoreMode store_mode() const {
2831     return StoreModeBits::decode(sub_minor_key());
2832   }
2833
2834   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
2835   enum ParameterIndices {
2836     kValueIndex,
2837     kMapIndex,
2838     kKeyIndex,
2839     kObjectIndex,
2840     kParameterCount
2841   };
2842
2843   static const Register ValueRegister() {
2844     return ElementTransitionAndStoreDescriptor::ValueRegister();
2845   }
2846   static const Register MapRegister() {
2847     return ElementTransitionAndStoreDescriptor::MapRegister();
2848   }
2849   static const Register KeyRegister() {
2850     return ElementTransitionAndStoreDescriptor::NameRegister();
2851   }
2852   static const Register ObjectRegister() {
2853     return ElementTransitionAndStoreDescriptor::ReceiverRegister();
2854   }
2855
2856  private:
2857   class FromBits : public BitField<ElementsKind, 0, 8> {};
2858   class ToBits : public BitField<ElementsKind, 8, 8> {};
2859   class IsJSArrayBits : public BitField<bool, 16, 1> {};
2860   class StoreModeBits : public BitField<KeyedAccessStoreMode, 17, 4> {};
2861
2862   DEFINE_CALL_INTERFACE_DESCRIPTOR(ElementTransitionAndStore);
2863   DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub);
2864 };
2865
2866
2867 class StoreArrayLiteralElementStub : public PlatformCodeStub {
2868  public:
2869   explicit StoreArrayLiteralElementStub(Isolate* isolate)
2870       : PlatformCodeStub(isolate) { }
2871
2872   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreArrayLiteralElement);
2873   DEFINE_PLATFORM_CODE_STUB(StoreArrayLiteralElement, PlatformCodeStub);
2874 };
2875
2876
2877 class StubFailureTrampolineStub : public PlatformCodeStub {
2878  public:
2879   StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
2880       : PlatformCodeStub(isolate) {
2881     minor_key_ = FunctionModeField::encode(function_mode);
2882   }
2883
2884   static void GenerateAheadOfTime(Isolate* isolate);
2885
2886  private:
2887   StubFunctionMode function_mode() const {
2888     return FunctionModeField::decode(minor_key_);
2889   }
2890
2891   class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
2892
2893   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2894   DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub);
2895 };
2896
2897
2898 class ProfileEntryHookStub : public PlatformCodeStub {
2899  public:
2900   explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
2901
2902   // The profile entry hook function is not allowed to cause a GC.
2903   bool SometimesSetsUpAFrame() override { return false; }
2904
2905   // Generates a call to the entry hook if it's enabled.
2906   static void MaybeCallEntryHook(MacroAssembler* masm);
2907
2908  private:
2909   static void EntryHookTrampoline(intptr_t function,
2910                                   intptr_t stack_pointer,
2911                                   Isolate* isolate);
2912
2913   // ProfileEntryHookStub is called at the start of a function, so it has the
2914   // same register set.
2915   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction)
2916   DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub);
2917 };
2918
2919
2920 class StoreBufferOverflowStub : public PlatformCodeStub {
2921  public:
2922   StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
2923       : PlatformCodeStub(isolate) {
2924     minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs);
2925   }
2926
2927   static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
2928   bool SometimesSetsUpAFrame() override { return false; }
2929
2930  private:
2931   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
2932
2933   class SaveDoublesBits : public BitField<bool, 0, 1> {};
2934
2935   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
2936   DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
2937 };
2938
2939
2940 class SubStringStub : public PlatformCodeStub {
2941  public:
2942   explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
2943
2944   DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
2945   DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub);
2946 };
2947
2948
2949 class ToNumberStub final : public PlatformCodeStub {
2950  public:
2951   explicit ToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
2952
2953   DEFINE_CALL_INTERFACE_DESCRIPTOR(ToNumber);
2954   DEFINE_PLATFORM_CODE_STUB(ToNumber, PlatformCodeStub);
2955 };
2956
2957
2958 class StringCompareStub : public PlatformCodeStub {
2959  public:
2960   explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
2961
2962   DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
2963   DEFINE_PLATFORM_CODE_STUB(StringCompare, PlatformCodeStub);
2964 };
2965
2966
2967 #undef DEFINE_CALL_INTERFACE_DESCRIPTOR
2968 #undef DEFINE_PLATFORM_CODE_STUB
2969 #undef DEFINE_HANDLER_CODE_STUB
2970 #undef DEFINE_HYDROGEN_CODE_STUB
2971 #undef DEFINE_CODE_STUB
2972 #undef DEFINE_CODE_STUB_BASE
2973 } }  // namespace v8::internal
2974
2975 #endif  // V8_CODE_STUBS_H_