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