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