LCOV - code coverage report
Current view: top level - src - code-stubs.h (source / functions) Hit Total Coverage
Test: app.info Lines: 283 352 80.4 %
Date: 2017-04-26 Functions: 115 247 46.6 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_CODE_STUBS_H_
       6             : #define V8_CODE_STUBS_H_
       7             : 
       8             : #include "src/allocation.h"
       9             : #include "src/assembler.h"
      10             : #include "src/codegen.h"
      11             : #include "src/factory.h"
      12             : #include "src/find-and-replace-pattern.h"
      13             : #include "src/globals.h"
      14             : #include "src/ic/ic-state.h"
      15             : #include "src/interface-descriptors.h"
      16             : #include "src/macro-assembler.h"
      17             : #include "src/ostreams.h"
      18             : #include "src/type-hints.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : 
      23             : // Forward declarations.
      24             : class CodeStubAssembler;
      25             : namespace compiler {
      26             : class CodeAssemblerLabel;
      27             : class CodeAssemblerState;
      28             : class Node;
      29             : }
      30             : 
      31             : // List of code stubs used on all platforms.
      32             : #define CODE_STUB_LIST_ALL_PLATFORMS(V)       \
      33             :   /* --- PlatformCodeStubs --- */             \
      34             :   V(ArrayConstructor)                         \
      35             :   V(BinaryOpICWithAllocationSite)             \
      36             :   V(CallApiCallback)                          \
      37             :   V(CallApiGetter)                            \
      38             :   V(CallConstruct)                            \
      39             :   V(CallIC)                                   \
      40             :   V(CEntry)                                   \
      41             :   V(CompareIC)                                \
      42             :   V(DoubleToI)                                \
      43             :   V(InternalArrayConstructor)                 \
      44             :   V(JSEntry)                                  \
      45             :   V(MathPow)                                  \
      46             :   V(ProfileEntryHook)                         \
      47             :   V(RecordWrite)                              \
      48             :   V(StoreBufferOverflow)                      \
      49             :   V(StoreSlowElement)                         \
      50             :   V(SubString)                                \
      51             :   V(NameDictionaryLookup)                     \
      52             :   /* This can be removed once there are no */ \
      53             :   /* more deopting Hydrogen stubs. */         \
      54             :   V(StubFailureTrampoline)                    \
      55             :   /* These are only called from FCG */        \
      56             :   /* They can be removed when only the TF  */ \
      57             :   /* version of the corresponding stub is  */ \
      58             :   /* used universally */                      \
      59             :   V(CallICTrampoline)                         \
      60             :   /* --- HydrogenCodeStubs --- */             \
      61             :   /* These should never be ported to TF */    \
      62             :   /* because they are either used only by */  \
      63             :   /* FCG/Crankshaft or are deprecated */      \
      64             :   V(BinaryOpIC)                               \
      65             :   V(BinaryOpWithAllocationSite)               \
      66             :   V(ToBooleanIC)                              \
      67             :   V(TransitionElementsKind)                   \
      68             :   /* --- TurboFanCodeStubs --- */             \
      69             :   V(AllocateHeapNumber)                       \
      70             :   V(ArrayNoArgumentConstructor)               \
      71             :   V(ArraySingleArgumentConstructor)           \
      72             :   V(ArrayNArgumentsConstructor)               \
      73             :   V(CreateAllocationSite)                     \
      74             :   V(CreateWeakCell)                           \
      75             :   V(StringLength)                             \
      76             :   V(InternalArrayNoArgumentConstructor)       \
      77             :   V(InternalArraySingleArgumentConstructor)   \
      78             :   V(ElementsTransitionAndStore)               \
      79             :   V(KeyedLoadSloppyArguments)                 \
      80             :   V(KeyedStoreSloppyArguments)                \
      81             :   V(LoadScriptContextField)                   \
      82             :   V(StoreScriptContextField)                  \
      83             :   V(NumberToString)                           \
      84             :   V(StringAdd)                                \
      85             :   V(GetProperty)                              \
      86             :   V(StoreFastElement)                         \
      87             :   V(StoreInterceptor)                         \
      88             :   V(LoadIndexedInterceptor)                   \
      89             :   V(GrowArrayElements)
      90             : 
      91             : // List of code stubs only used on ARM 32 bits platforms.
      92             : #if V8_TARGET_ARCH_ARM
      93             : #define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
      94             : 
      95             : #else
      96             : #define CODE_STUB_LIST_ARM(V)
      97             : #endif
      98             : 
      99             : // List of code stubs only used on ARM 64 bits platforms.
     100             : #if V8_TARGET_ARCH_ARM64
     101             : #define CODE_STUB_LIST_ARM64(V) \
     102             :   V(DirectCEntry)               \
     103             :   V(RestoreRegistersState)      \
     104             :   V(StoreRegistersState)
     105             : 
     106             : #else
     107             : #define CODE_STUB_LIST_ARM64(V)
     108             : #endif
     109             : 
     110             : // List of code stubs only used on PPC platforms.
     111             : #ifdef V8_TARGET_ARCH_PPC
     112             : #define CODE_STUB_LIST_PPC(V) \
     113             :   V(DirectCEntry)             \
     114             :   V(StoreRegistersState)      \
     115             :   V(RestoreRegistersState)
     116             : #else
     117             : #define CODE_STUB_LIST_PPC(V)
     118             : #endif
     119             : 
     120             : // List of code stubs only used on MIPS platforms.
     121             : #if V8_TARGET_ARCH_MIPS
     122             : #define CODE_STUB_LIST_MIPS(V) \
     123             :   V(DirectCEntry)              \
     124             :   V(RestoreRegistersState)     \
     125             :   V(StoreRegistersState)
     126             : #elif V8_TARGET_ARCH_MIPS64
     127             : #define CODE_STUB_LIST_MIPS(V) \
     128             :   V(DirectCEntry)              \
     129             :   V(RestoreRegistersState)     \
     130             :   V(StoreRegistersState)
     131             : #else
     132             : #define CODE_STUB_LIST_MIPS(V)
     133             : #endif
     134             : 
     135             : // List of code stubs only used on S390 platforms.
     136             : #ifdef V8_TARGET_ARCH_S390
     137             : #define CODE_STUB_LIST_S390(V) \
     138             :   V(DirectCEntry)              \
     139             :   V(StoreRegistersState)       \
     140             :   V(RestoreRegistersState)
     141             : #else
     142             : #define CODE_STUB_LIST_S390(V)
     143             : #endif
     144             : 
     145             : // Combined list of code stubs.
     146             : #define CODE_STUB_LIST(V)         \
     147             :   CODE_STUB_LIST_ALL_PLATFORMS(V) \
     148             :   CODE_STUB_LIST_ARM(V)           \
     149             :   CODE_STUB_LIST_ARM64(V)         \
     150             :   CODE_STUB_LIST_PPC(V)           \
     151             :   CODE_STUB_LIST_MIPS(V)          \
     152             :   CODE_STUB_LIST_S390(V)
     153             : 
     154             : static const int kHasReturnedMinusZeroSentinel = 1;
     155             : 
     156             : // Stub is base classes of all stubs.
     157             : class CodeStub BASE_EMBEDDED {
     158             :  public:
     159             :   enum Major {
     160             :     // TODO(mvstanton): eliminate the NoCache key by getting rid
     161             :     //                  of the non-monomorphic-cache.
     162             :     NoCache = 0,  // marker for stubs that do custom caching]
     163             : #define DEF_ENUM(name) name,
     164             :     CODE_STUB_LIST(DEF_ENUM)
     165             : #undef DEF_ENUM
     166             :     NUMBER_OF_IDS
     167             :   };
     168             : 
     169             :   // Retrieve the code for the stub. Generate the code if needed.
     170             :   Handle<Code> GetCode();
     171             : 
     172             :   // Retrieve the code for the stub, make and return a copy of the code.
     173             :   Handle<Code> GetCodeCopy(const FindAndReplacePattern& pattern);
     174             : 
     175             :   static Major MajorKeyFromKey(uint32_t key) {
     176             :     return static_cast<Major>(MajorKeyBits::decode(key));
     177             :   }
     178             :   static uint32_t MinorKeyFromKey(uint32_t key) {
     179             :     return MinorKeyBits::decode(key);
     180             :   }
     181             : 
     182             :   // Gets the major key from a code object that is a code stub or binary op IC.
     183             :   static Major GetMajorKey(Code* code_stub) {
     184             :     return MajorKeyFromKey(code_stub->stub_key());
     185             :   }
     186             : 
     187             :   static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
     188             : 
     189             :   static const char* MajorName(Major major_key);
     190             : 
     191    10839428 :   explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {}
     192     1014662 :   virtual ~CodeStub() {}
     193             : 
     194             :   static void GenerateStubsAheadOfTime(Isolate* isolate);
     195             :   static void GenerateFPStubs(Isolate* isolate);
     196             : 
     197             :   // Some stubs put untagged junk on the stack that cannot be scanned by the
     198             :   // GC.  This means that we must be statically sure that no GC can occur while
     199             :   // they are running.  If that is the case they should override this to return
     200             :   // true, which will cause an assertion if we try to call something that can
     201             :   // GC or if we try to put a stack frame on top of the junk, which would not
     202             :   // result in a traversable stack.
     203           0 :   virtual bool SometimesSetsUpAFrame() { return true; }
     204             : 
     205             :   // Lookup the code in the (possibly custom) cache.
     206             :   bool FindCodeInCache(Code** code_out);
     207             : 
     208             :   virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() const = 0;
     209             : 
     210           0 :   virtual int GetStackParameterCount() const {
     211           0 :     return GetCallInterfaceDescriptor().GetStackParameterCount();
     212             :   }
     213             : 
     214           0 :   virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {}
     215             : 
     216             :   static void InitializeDescriptor(Isolate* isolate, uint32_t key,
     217             :                                    CodeStubDescriptor* desc);
     218             : 
     219             :   static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key);
     220             : 
     221             :   // Returns information for computing the number key.
     222             :   virtual Major MajorKey() const = 0;
     223             :   uint32_t MinorKey() const { return minor_key_; }
     224             : 
     225             :   // BinaryOpStub needs to override this.
     226             :   virtual Code::Kind GetCodeKind() const;
     227             : 
     228       95221 :   virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
     229             : 
     230             :   Code::Flags GetCodeFlags() const;
     231             : 
     232             :   friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
     233      286632 :     s.PrintName(os);
     234             :     return os;
     235             :   }
     236             : 
     237             :   Isolate* isolate() const { return isolate_; }
     238             : 
     239             :   void DeleteStubFromCacheForTesting();
     240             : 
     241             :  protected:
     242             :   CodeStub(uint32_t key, Isolate* isolate)
     243       53856 :       : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {}
     244             : 
     245             :   // Generates the assembler code for the stub.
     246             :   virtual Handle<Code> GenerateCode() = 0;
     247             : 
     248             :   // Returns whether the code generated for this stub needs to be allocated as
     249             :   // a fixed (non-moveable) code object.
     250      108142 :   virtual bool NeedsImmovableCode() { return false; }
     251             : 
     252             :   virtual void PrintName(std::ostream& os) const;        // NOLINT
     253             :   virtual void PrintBaseName(std::ostream& os) const;    // NOLINT
     254      129074 :   virtual void PrintState(std::ostream& os) const { ; }  // NOLINT
     255             : 
     256             :   // Computes the key based on major and minor.
     257    10496773 :   uint32_t GetKey() {
     258             :     DCHECK(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
     259    10496773 :     return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey());
     260             :   }
     261             : 
     262             :   uint32_t minor_key_;
     263             : 
     264             :  private:
     265             :   // Perform bookkeeping required after code generation when stub code is
     266             :   // initially generated.
     267             :   void RecordCodeGeneration(Handle<Code> code);
     268             : 
     269             :   // Finish the code object after it has been generated.
     270      208611 :   virtual void FinishCode(Handle<Code> code) { }
     271             : 
     272             :   // Activate newly generated stub. Is called after
     273             :   // registering stub in the stub cache.
     274      191489 :   virtual void Activate(Code* code) { }
     275             : 
     276             :   // Add the code to a specialized cache, specific to an individual
     277             :   // stub type. Please note, this method must add the code object to a
     278             :   // roots object, otherwise we will remove the code during GC.
     279        2072 :   virtual void AddToSpecialCache(Handle<Code> new_object) { }
     280             : 
     281             :   // Find code in a specialized cache, work is delegated to the specific stub.
     282        2072 :   virtual bool FindCodeInSpecialCache(Code** code_out) {
     283        2072 :     return false;
     284             :   }
     285             : 
     286             :   // If a stub uses a special cache override this.
     287     8409786 :   virtual bool UseSpecialCache() { return false; }
     288             : 
     289             :   // We use this dispatch to statically instantiate the correct code stub for
     290             :   // the given stub key and call the passed function with that code stub.
     291             :   typedef void (*DispatchedCall)(CodeStub* stub, void** value_out);
     292             :   static void Dispatch(Isolate* isolate, uint32_t key, void** value_out,
     293             :                        DispatchedCall call);
     294             : 
     295             :   static void GetCodeDispatchCall(CodeStub* stub, void** value_out);
     296             : 
     297             :   STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
     298             :   class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
     299             :   class MinorKeyBits: public BitField<uint32_t,
     300             :       kStubMajorKeyBits, kStubMinorKeyBits> {};  // NOLINT
     301             : 
     302             :   friend class BreakPointIterator;
     303             : 
     304             :   Isolate* isolate_;
     305             : };
     306             : 
     307             : 
     308             : #define DEFINE_CODE_STUB_BASE(NAME, SUPER)                      \
     309             :  public:                                                        \
     310             :   NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \
     311             :                                                                 \
     312             :  private:                                                       \
     313             :   DISALLOW_COPY_AND_ASSIGN(NAME)
     314             : 
     315             : 
     316             : #define DEFINE_CODE_STUB(NAME, SUPER)                      \
     317             :  public:                                                   \
     318             :   inline Major MajorKey() const override { return NAME; }; \
     319             :                                                            \
     320             :   DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
     321             : 
     322             : 
     323             : #define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER)  \
     324             :  private:                                       \
     325             :   void Generate(MacroAssembler* masm) override; \
     326             :   DEFINE_CODE_STUB(NAME, SUPER)
     327             : 
     328             : 
     329             : #define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER)                        \
     330             :  public:                                                              \
     331             :   void InitializeDescriptor(CodeStubDescriptor* descriptor) override; \
     332             :   Handle<Code> GenerateCode() override;                               \
     333             :   DEFINE_CODE_STUB(NAME, SUPER)
     334             : 
     335             : #define DEFINE_TURBOFAN_CODE_STUB(NAME, SUPER)                               \
     336             :  public:                                                                     \
     337             :   void GenerateAssembly(compiler::CodeAssemblerState* state) const override; \
     338             :   DEFINE_CODE_STUB(NAME, SUPER)
     339             : 
     340             : #define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
     341             :  public:                                      \
     342             :   Handle<Code> GenerateCode() override;       \
     343             :   DEFINE_CODE_STUB(NAME, SUPER)
     344             : 
     345             : #define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME)                          \
     346             :  public:                                                                \
     347             :   typedef NAME##Descriptor Descriptor;                                  \
     348             :   CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
     349             :     return Descriptor(isolate());                                       \
     350             :   }
     351             : 
     352             : // There are some code stubs we just can't describe right now with a
     353             : // CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
     354             : // An attempt to retrieve a descriptor will fail.
     355             : #define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR()                         \
     356             :  public:                                                                \
     357             :   CallInterfaceDescriptor GetCallInterfaceDescriptor() const override { \
     358             :     UNREACHABLE();                                                      \
     359             :     return CallInterfaceDescriptor();                                   \
     360             :   }
     361             : 
     362             : 
     363      357668 : class PlatformCodeStub : public CodeStub {
     364             :  public:
     365             :   // Retrieve the code for the stub. Generate the code if needed.
     366             :   Handle<Code> GenerateCode() override;
     367             : 
     368             :  protected:
     369     7064475 :   explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
     370             : 
     371             :   // Generates the assembler code for the stub.
     372             :   virtual void Generate(MacroAssembler* masm) = 0;
     373             : 
     374         179 :   DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub);
     375             : };
     376             : 
     377             : 
     378             : enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
     379             : 
     380             : 
     381             : class CodeStubDescriptor {
     382             :  public:
     383             :   explicit CodeStubDescriptor(CodeStub* stub);
     384             : 
     385             :   CodeStubDescriptor(Isolate* isolate, uint32_t stub_key);
     386             : 
     387             :   void Initialize(Address deoptimization_handler = NULL,
     388             :                   int hint_stack_parameter_count = -1,
     389             :                   StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
     390             :   void Initialize(Register stack_parameter_count,
     391             :                   Address deoptimization_handler = NULL,
     392             :                   int hint_stack_parameter_count = -1,
     393             :                   StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
     394             : 
     395       73400 :   void SetMissHandler(Runtime::FunctionId id) {
     396       73400 :     miss_handler_id_ = id;
     397       73400 :     miss_handler_ = ExternalReference(Runtime::FunctionForId(id), isolate_);
     398       73400 :     has_miss_handler_ = true;
     399             :     // Our miss handler infrastructure doesn't currently support
     400             :     // variable stack parameter counts.
     401             :     DCHECK(!stack_parameter_count_.is_valid());
     402       73400 :   }
     403             : 
     404       26647 :   void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; }
     405             :   CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; }
     406             : 
     407             :   int GetRegisterParameterCount() const {
     408             :     return call_descriptor().GetRegisterParameterCount();
     409             :   }
     410             : 
     411             :   int GetStackParameterCount() const {
     412             :     return call_descriptor().GetStackParameterCount();
     413             :   }
     414             : 
     415             :   int GetParameterCount() const {
     416             :     return call_descriptor().GetParameterCount();
     417             :   }
     418             : 
     419             :   Register GetRegisterParameter(int index) const {
     420             :     return call_descriptor().GetRegisterParameter(index);
     421             :   }
     422             : 
     423             :   MachineType GetParameterType(int index) const {
     424             :     return call_descriptor().GetParameterType(index);
     425             :   }
     426             : 
     427             :   ExternalReference miss_handler() const {
     428             :     DCHECK(has_miss_handler_);
     429             :     return miss_handler_;
     430             :   }
     431             : 
     432             :   Runtime::FunctionId miss_handler_id() const {
     433             :     DCHECK(has_miss_handler_);
     434             :     return miss_handler_id_;
     435             :   }
     436             : 
     437             :   bool has_miss_handler() const {
     438             :     return has_miss_handler_;
     439             :   }
     440             : 
     441             :   int GetHandlerParameterCount() const {
     442             :     int params = GetParameterCount();
     443       26647 :     if (PassesArgumentsToDeoptimizationHandler()) {
     444           0 :       params += 1;
     445             :     }
     446             :     return params;
     447             :   }
     448             : 
     449             :   int hint_stack_parameter_count() const { return hint_stack_parameter_count_; }
     450             :   Register stack_parameter_count() const { return stack_parameter_count_; }
     451             :   StubFunctionMode function_mode() const { return function_mode_; }
     452             :   Address deoptimization_handler() const { return deoptimization_handler_; }
     453             : 
     454             :  private:
     455             :   bool PassesArgumentsToDeoptimizationHandler() const {
     456             :     return stack_parameter_count_.is_valid();
     457             :   }
     458             : 
     459             :   Isolate* isolate_;
     460             :   CallInterfaceDescriptor call_descriptor_;
     461             :   Register stack_parameter_count_;
     462             :   // If hint_stack_parameter_count_ > 0, the code stub can optimize the
     463             :   // return sequence. Default value is -1, which means it is ignored.
     464             :   int hint_stack_parameter_count_;
     465             :   StubFunctionMode function_mode_;
     466             : 
     467             :   Address deoptimization_handler_;
     468             : 
     469             :   ExternalReference miss_handler_;
     470             :   Runtime::FunctionId miss_handler_id_;
     471             :   bool has_miss_handler_;
     472             : };
     473             : 
     474             : 
     475      387899 : class HydrogenCodeStub : public CodeStub {
     476             :  public:
     477             :   enum InitializationState {
     478             :     UNINITIALIZED,
     479             :     INITIALIZED
     480             :   };
     481             : 
     482             :   template<class SubClass>
     483             :   static Handle<Code> GetUninitialized(Isolate* isolate) {
     484             :     SubClass::GenerateAheadOfTime(isolate);
     485             :     return SubClass().GetCode(isolate);
     486             :   }
     487             : 
     488             :   // Retrieve the code for the stub. Generate the code if needed.
     489             :   Handle<Code> GenerateCode() override = 0;
     490             : 
     491             :   bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
     492             : 
     493             :   Handle<Code> GenerateLightweightMissCode(ExternalReference miss);
     494             : 
     495             :   Handle<Code> GenerateRuntimeTailCall(CodeStubDescriptor* descriptor);
     496             : 
     497             :   template<class StateType>
     498             :   void TraceTransition(StateType from, StateType to);
     499             : 
     500             :  protected:
     501             :   explicit HydrogenCodeStub(Isolate* isolate,
     502             :                             InitializationState state = INITIALIZED)
     503     1592643 :       : CodeStub(isolate) {
     504     1066486 :     minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
     505             :   }
     506             : 
     507             :   void set_sub_minor_key(uint32_t key) {
     508     2721466 :     minor_key_ = SubMinorKeyBits::update(minor_key_, key);
     509             :   }
     510             : 
     511      130747 :   uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
     512             : 
     513             :   static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
     514             : 
     515             :  private:
     516             :   class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};
     517             :   class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
     518             : 
     519             :   void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss);
     520             : 
     521       26671 :   DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub);
     522             : };
     523             : 
     524             : 
     525      269095 : class TurboFanCodeStub : public CodeStub {
     526             :  public:
     527             :   // Retrieve the code for the stub. Generate the code if needed.
     528             :   Handle<Code> GenerateCode() override;
     529             : 
     530           0 :   int GetStackParameterCount() const override {
     531           0 :     return GetCallInterfaceDescriptor().GetStackParameterCount();
     532             :   }
     533             : 
     534             :  protected:
     535     2182310 :   explicit TurboFanCodeStub(Isolate* isolate) : CodeStub(isolate) {}
     536             : 
     537             :   virtual void GenerateAssembly(compiler::CodeAssemblerState* state) const = 0;
     538             : 
     539             :  private:
     540          78 :   DEFINE_CODE_STUB_BASE(TurboFanCodeStub, CodeStub);
     541             : };
     542             : 
     543             : 
     544             : // Helper interface to prepare to/restore after making runtime calls.
     545             : class RuntimeCallHelper {
     546             :  public:
     547           0 :   virtual ~RuntimeCallHelper() {}
     548             : 
     549             :   virtual void BeforeCall(MacroAssembler* masm) const = 0;
     550             : 
     551             :   virtual void AfterCall(MacroAssembler* masm) const = 0;
     552             : 
     553             :  protected:
     554          64 :   RuntimeCallHelper() {}
     555             : 
     556             :  private:
     557             :   DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
     558             : };
     559             : 
     560             : 
     561             : }  // namespace internal
     562             : }  // namespace v8
     563             : 
     564             : #if V8_TARGET_ARCH_IA32
     565             : #include "src/ia32/code-stubs-ia32.h"
     566             : #elif V8_TARGET_ARCH_X64
     567             : #include "src/x64/code-stubs-x64.h"
     568             : #elif V8_TARGET_ARCH_ARM64
     569             : #include "src/arm64/code-stubs-arm64.h"
     570             : #elif V8_TARGET_ARCH_ARM
     571             : #include "src/arm/code-stubs-arm.h"
     572             : #elif V8_TARGET_ARCH_PPC
     573             : #include "src/ppc/code-stubs-ppc.h"
     574             : #elif V8_TARGET_ARCH_MIPS
     575             : #include "src/mips/code-stubs-mips.h"
     576             : #elif V8_TARGET_ARCH_MIPS64
     577             : #include "src/mips64/code-stubs-mips64.h"
     578             : #elif V8_TARGET_ARCH_S390
     579             : #include "src/s390/code-stubs-s390.h"
     580             : #elif V8_TARGET_ARCH_X87
     581             : #include "src/x87/code-stubs-x87.h"
     582             : #else
     583             : #error Unsupported target architecture.
     584             : #endif
     585             : 
     586             : namespace v8 {
     587             : namespace internal {
     588             : 
     589             : 
     590             : // RuntimeCallHelper implementation used in stubs: enters/leaves a
     591             : // newly created internal frame before/after the runtime call.
     592           0 : class StubRuntimeCallHelper : public RuntimeCallHelper {
     593             :  public:
     594             :   StubRuntimeCallHelper() {}
     595             : 
     596             :   void BeforeCall(MacroAssembler* masm) const override;
     597             : 
     598             :   void AfterCall(MacroAssembler* masm) const override;
     599             : };
     600             : 
     601             : 
     602             : // Trivial RuntimeCallHelper implementation.
     603           0 : class NopRuntimeCallHelper : public RuntimeCallHelper {
     604             :  public:
     605          64 :   NopRuntimeCallHelper() {}
     606             : 
     607         128 :   void BeforeCall(MacroAssembler* masm) const override {}
     608             : 
     609         128 :   void AfterCall(MacroAssembler* masm) const override {}
     610             : };
     611             : 
     612             : 
     613           0 : class StringLengthStub : public TurboFanCodeStub {
     614             :  public:
     615         248 :   explicit StringLengthStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
     616             : 
     617          76 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
     618          76 :   ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
     619             : 
     620         166 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
     621         531 :   DEFINE_TURBOFAN_CODE_STUB(StringLength, TurboFanCodeStub);
     622             : };
     623             : 
     624           0 : class StoreInterceptorStub : public TurboFanCodeStub {
     625             :  public:
     626         153 :   explicit StoreInterceptorStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
     627             : 
     628          98 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
     629          98 :   ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
     630             : 
     631         196 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
     632         545 :   DEFINE_TURBOFAN_CODE_STUB(StoreInterceptor, TurboFanCodeStub);
     633             : };
     634             : 
     635           0 : class LoadIndexedInterceptorStub : public TurboFanCodeStub {
     636             :  public:
     637             :   explicit LoadIndexedInterceptorStub(Isolate* isolate)
     638          97 :       : TurboFanCodeStub(isolate) {}
     639             : 
     640          68 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
     641          68 :   ExtraICState GetExtraICState() const override { return Code::KEYED_LOAD_IC; }
     642             : 
     643         136 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
     644         369 :   DEFINE_TURBOFAN_CODE_STUB(LoadIndexedInterceptor, TurboFanCodeStub);
     645             : };
     646             : 
     647             : // ES6 [[Get]] operation.
     648          43 : class GetPropertyStub : public TurboFanCodeStub {
     649             :  public:
     650        3232 :   explicit GetPropertyStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
     651             : 
     652         172 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(GetProperty);
     653        3404 :   DEFINE_TURBOFAN_CODE_STUB(GetProperty, TurboFanCodeStub);
     654             : };
     655             : 
     656           0 : class NumberToStringStub final : public TurboFanCodeStub {
     657             :  public:
     658         430 :   explicit NumberToStringStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
     659             : 
     660          86 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
     661         602 :   DEFINE_TURBOFAN_CODE_STUB(NumberToString, TurboFanCodeStub);
     662             : };
     663             : 
     664           0 : class CreateAllocationSiteStub : public TurboFanCodeStub {
     665             :  public:
     666             :   explicit CreateAllocationSiteStub(Isolate* isolate)
     667        4653 :       : TurboFanCodeStub(isolate) {}
     668             :   static void GenerateAheadOfTime(Isolate* isolate);
     669             : 
     670          86 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite);
     671        4825 :   DEFINE_TURBOFAN_CODE_STUB(CreateAllocationSite, TurboFanCodeStub);
     672             : };
     673             : 
     674           0 : class CreateWeakCellStub : public TurboFanCodeStub {
     675             :  public:
     676        4653 :   explicit CreateWeakCellStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
     677             : 
     678             :   static void GenerateAheadOfTime(Isolate* isolate);
     679             : 
     680          86 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateWeakCell);
     681        4825 :   DEFINE_TURBOFAN_CODE_STUB(CreateWeakCell, TurboFanCodeStub);
     682             : };
     683             : 
     684        2539 : class GrowArrayElementsStub : public TurboFanCodeStub {
     685             :  public:
     686             :   GrowArrayElementsStub(Isolate* isolate, ElementsKind kind)
     687        2539 :       : TurboFanCodeStub(isolate) {
     688        2539 :     minor_key_ = ElementsKindBits::encode(GetHoleyElementsKind(kind));
     689             :   }
     690             : 
     691             :   ElementsKind elements_kind() const {
     692             :     return ElementsKindBits::decode(minor_key_);
     693             :   }
     694             : 
     695             :  private:
     696             :   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
     697             : 
     698         618 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(GrowArrayElements);
     699        3775 :   DEFINE_TURBOFAN_CODE_STUB(GrowArrayElements, TurboFanCodeStub);
     700             : };
     701             : 
     702             : enum AllocationSiteOverrideMode {
     703             :   DONT_OVERRIDE,
     704             :   DISABLE_ALLOCATION_SITES,
     705             :   LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
     706             : };
     707             : 
     708             : 
     709          79 : class ArrayConstructorStub: public PlatformCodeStub {
     710             :  public:
     711             :   explicit ArrayConstructorStub(Isolate* isolate);
     712             : 
     713             :  private:
     714             :   void GenerateDispatchToArrayStub(MacroAssembler* masm,
     715             :                                    AllocationSiteOverrideMode mode);
     716             : 
     717           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
     718       28442 :   DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
     719             : };
     720             : 
     721             : 
     722           0 : class InternalArrayConstructorStub: public PlatformCodeStub {
     723             :  public:
     724             :   explicit InternalArrayConstructorStub(Isolate* isolate);
     725             : 
     726             :  private:
     727             :   void GenerateCase(MacroAssembler* masm, ElementsKind kind);
     728             : 
     729           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNArgumentsConstructor);
     730         409 :   DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub);
     731             : };
     732             : 
     733             : 
     734           0 : class MathPowStub: public PlatformCodeStub {
     735             :  public:
     736             :   enum ExponentType { INTEGER, DOUBLE, TAGGED };
     737             : 
     738             :   MathPowStub(Isolate* isolate, ExponentType exponent_type)
     739         932 :       : PlatformCodeStub(isolate) {
     740         572 :     minor_key_ = ExponentTypeBits::encode(exponent_type);
     741             :   }
     742             : 
     743           0 :   CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
     744           0 :     if (exponent_type() == TAGGED) {
     745           0 :       return MathPowTaggedDescriptor(isolate());
     746           0 :     } else if (exponent_type() == INTEGER) {
     747           0 :       return MathPowIntegerDescriptor(isolate());
     748             :     } else {
     749             :       // A CallInterfaceDescriptor doesn't specify double registers (yet).
     750             :       DCHECK_EQ(DOUBLE, exponent_type());
     751           0 :       return ContextOnlyDescriptor(isolate());
     752             :     }
     753             :   }
     754             : 
     755             :  private:
     756             :   ExponentType exponent_type() const {
     757             :     return ExponentTypeBits::decode(minor_key_);
     758             :   }
     759             : 
     760             :   class ExponentTypeBits : public BitField<ExponentType, 0, 2> {};
     761             : 
     762        1268 :   DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub);
     763             : };
     764             : 
     765           0 : class CallICStub : public TurboFanCodeStub {
     766             :  public:
     767             :   CallICStub(Isolate* isolate, ConvertReceiverMode convert_mode,
     768             :              TailCallMode tail_call_mode)
     769     1733854 :       : TurboFanCodeStub(isolate) {
     770     1733854 :     minor_key_ = ConvertModeBits::encode(convert_mode) |
     771     1733854 :                  TailCallModeBits::encode(tail_call_mode);
     772             :   }
     773             : 
     774             :   ConvertReceiverMode convert_mode() const {
     775             :     return ConvertModeBits::decode(minor_key_);
     776             :   }
     777             :   TailCallMode tail_call_mode() const {
     778             :     return TailCallModeBits::decode(minor_key_);
     779             :   }
     780             : 
     781             :  protected:
     782             :   typedef BitField<ConvertReceiverMode, 0, 2> ConvertModeBits;
     783             :   typedef BitField<TailCallMode, ConvertModeBits::kNext, 1> TailCallModeBits;
     784             : 
     785             :  private:
     786             :   void PrintState(std::ostream& os) const final;  // NOLINT
     787             : 
     788       56296 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallIC);
     789      741151 :   DEFINE_TURBOFAN_CODE_STUB(CallIC, TurboFanCodeStub);
     790             : };
     791             : 
     792           0 : class KeyedLoadSloppyArgumentsStub : public TurboFanCodeStub {
     793             :  public:
     794             :   explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate)
     795        3189 :       : TurboFanCodeStub(isolate) {}
     796             : 
     797         350 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
     798         350 :   ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
     799             : 
     800             :  protected:
     801         700 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
     802        4589 :   DEFINE_TURBOFAN_CODE_STUB(KeyedLoadSloppyArguments, TurboFanCodeStub);
     803             : };
     804             : 
     805             : 
     806             : class CommonStoreModeBits : public BitField<KeyedAccessStoreMode, 0, 3> {};
     807             : 
     808           0 : class KeyedStoreSloppyArgumentsStub : public TurboFanCodeStub {
     809             :  public:
     810             :   explicit KeyedStoreSloppyArgumentsStub(Isolate* isolate,
     811             :                                          KeyedAccessStoreMode mode)
     812           0 :       : TurboFanCodeStub(isolate) {
     813           0 :     minor_key_ = CommonStoreModeBits::encode(mode);
     814             :   }
     815             : 
     816           0 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
     817           0 :   ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
     818             : 
     819             :  protected:
     820           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
     821           0 :   DEFINE_TURBOFAN_CODE_STUB(KeyedStoreSloppyArguments, TurboFanCodeStub);
     822             : };
     823             : 
     824       11206 : class CallApiCallbackStub : public PlatformCodeStub {
     825             :  public:
     826             :   static const int kArgBits = 3;
     827             :   static const int kArgMax = (1 << kArgBits) - 1;
     828             : 
     829             :   // CallApiCallbackStub for regular setters and getters.
     830             :   CallApiCallbackStub(Isolate* isolate, bool is_store, bool is_lazy)
     831         393 :       : CallApiCallbackStub(isolate, is_store ? 1 : 0, is_store, is_lazy) {}
     832             : 
     833             :   // CallApiCallbackStub for callback functions.
     834             :   CallApiCallbackStub(Isolate* isolate, int argc, bool is_lazy)
     835       20157 :       : CallApiCallbackStub(isolate, argc, false, is_lazy) {}
     836             : 
     837             :  private:
     838       20550 :   CallApiCallbackStub(Isolate* isolate, int argc, bool is_store, bool is_lazy)
     839       20550 :       : PlatformCodeStub(isolate) {
     840       20550 :     CHECK(0 <= argc && argc <= kArgMax);
     841       20550 :     minor_key_ = IsStoreBits::encode(is_store) |
     842       20550 :                  ArgumentBits::encode(argc) |
     843       20550 :                  IsLazyAccessorBits::encode(is_lazy);
     844       20550 :   }
     845             : 
     846             :   bool is_store() const { return IsStoreBits::decode(minor_key_); }
     847             :   bool is_lazy() const { return IsLazyAccessorBits::decode(minor_key_); }
     848             :   int argc() const { return ArgumentBits::decode(minor_key_); }
     849             : 
     850             :   class IsStoreBits: public BitField<bool, 0, 1> {};
     851             :   class IsLazyAccessorBits : public BitField<bool, 1, 1> {};
     852             :   class ArgumentBits : public BitField<int, 2, kArgBits> {};
     853             : 
     854       40406 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiCallback);
     855       38943 :   DEFINE_PLATFORM_CODE_STUB(CallApiCallback, PlatformCodeStub);
     856             : };
     857             : 
     858             : 
     859           0 : class CallApiGetterStub : public PlatformCodeStub {
     860             :  public:
     861        1591 :   explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
     862             : 
     863           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
     864        1720 :   DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
     865             : };
     866             : 
     867             : 
     868      387497 : class BinaryOpICStub : public HydrogenCodeStub {
     869             :  public:
     870      834777 :   BinaryOpICStub(Isolate* isolate, Token::Value op)
     871      834777 :       : HydrogenCodeStub(isolate, UNINITIALIZED) {
     872             :     BinaryOpICState state(isolate, op);
     873      834777 :     set_sub_minor_key(state.GetExtraICState());
     874      834777 :   }
     875             : 
     876             :   BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state)
     877      395062 :       : HydrogenCodeStub(isolate) {
     878      395062 :     set_sub_minor_key(state.GetExtraICState());
     879             :   }
     880             : 
     881             :   static void GenerateAheadOfTime(Isolate* isolate);
     882             : 
     883        6372 :   Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
     884             : 
     885       10239 :   ExtraICState GetExtraICState() const final {
     886       40440 :     return static_cast<ExtraICState>(sub_minor_key());
     887             :   }
     888             : 
     889             :   BinaryOpICState state() const {
     890       19962 :     return BinaryOpICState(isolate(), GetExtraICState());
     891             :   }
     892             : 
     893             :   void PrintState(std::ostream& os) const final;  // NOLINT
     894             : 
     895             :  private:
     896             :   static void GenerateAheadOfTime(Isolate* isolate,
     897             :                                   const BinaryOpICState& state);
     898             : 
     899       68896 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
     900     1267293 :   DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub);
     901             : };
     902             : 
     903             : 
     904             : // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail
     905             : // call support for stubs in Hydrogen.
     906       46824 : class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
     907             :  public:
     908             :   BinaryOpICWithAllocationSiteStub(Isolate* isolate,
     909             :                                    const BinaryOpICState& state)
     910       46824 :       : PlatformCodeStub(isolate) {
     911       46824 :     minor_key_ = state.GetExtraICState();
     912             :   }
     913             : 
     914             :   static void GenerateAheadOfTime(Isolate* isolate);
     915             : 
     916       46824 :   Handle<Code> GetCodeCopyFromTemplate(Handle<AllocationSite> allocation_site) {
     917             :     FindAndReplacePattern pattern;
     918       46824 :     pattern.Add(isolate()->factory()->undefined_map(), allocation_site);
     919       46824 :     return CodeStub::GetCodeCopy(pattern);
     920             :   }
     921             : 
     922        3867 :   Code::Kind GetCodeKind() const override { return Code::BINARY_OP_IC; }
     923             : 
     924        3867 :   ExtraICState GetExtraICState() const override {
     925       58425 :     return static_cast<ExtraICState>(minor_key_);
     926             :   }
     927             : 
     928             :   void PrintState(std::ostream& os) const override;  // NOLINT
     929             : 
     930             :  private:
     931             :   BinaryOpICState state() const {
     932       54558 :     return BinaryOpICState(isolate(), GetExtraICState());
     933             :   }
     934             : 
     935             :   static void GenerateAheadOfTime(Isolate* isolate,
     936             :                                   const BinaryOpICState& state);
     937             : 
     938           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
     939      105249 :   DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
     940             : };
     941             : 
     942             : 
     943           0 : class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
     944             :  public:
     945             :   BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
     946             :       : BinaryOpICStub(isolate, op) {}
     947             : 
     948             :   BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
     949        3867 :       : BinaryOpICStub(isolate, state) {}
     950             : 
     951        3867 :   Code::Kind GetCodeKind() const final { return Code::STUB; }
     952             : 
     953       24124 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
     954       15929 :   DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub);
     955             : };
     956             : 
     957           0 : class StringAddStub final : public TurboFanCodeStub {
     958             :  public:
     959             :   StringAddStub(Isolate* isolate, StringAddFlags flags,
     960             :                 PretenureFlag pretenure_flag)
     961       92531 :       : TurboFanCodeStub(isolate) {
     962       92531 :     minor_key_ = (StringAddFlagsBits::encode(flags) |
     963       92531 :                   PretenureFlagBits::encode(pretenure_flag));
     964             :   }
     965             : 
     966             :   StringAddFlags flags() const {
     967             :     return StringAddFlagsBits::decode(minor_key_);
     968             :   }
     969             : 
     970             :   PretenureFlag pretenure_flag() const {
     971             :     return PretenureFlagBits::decode(minor_key_);
     972             :   }
     973             : 
     974             :  private:
     975             :   class StringAddFlagsBits : public BitField<StringAddFlags, 0, 3> {};
     976             :   class PretenureFlagBits : public BitField<PretenureFlag, 3, 1> {};
     977             : 
     978             :   void PrintBaseName(std::ostream& os) const override;  // NOLINT
     979             : 
     980         258 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
     981       92918 :   DEFINE_TURBOFAN_CODE_STUB(StringAdd, TurboFanCodeStub);
     982             : };
     983             : 
     984             : 
     985      272912 : class CompareICStub : public PlatformCodeStub {
     986             :  public:
     987             :   CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left,
     988             :                 CompareICState::State right, CompareICState::State state)
     989      988817 :       : PlatformCodeStub(isolate) {
     990             :     DCHECK(Token::IsCompareOp(op));
     991             :     DCHECK(OpBits::is_valid(op - Token::EQ));
     992     1258305 :     minor_key_ = OpBits::encode(op - Token::EQ) |
     993      549248 :                  LeftStateBits::encode(left) | RightStateBits::encode(right) |
     994      988817 :                  StateBits::encode(state);
     995             :   }
     996             :   // Creates uninitialized compare stub.
     997             :   CompareICStub(Isolate* isolate, Token::Value op)
     998             :       : CompareICStub(isolate, op, CompareICState::UNINITIALIZED,
     999             :                       CompareICState::UNINITIALIZED,
    1000             :                       CompareICState::UNINITIALIZED) {}
    1001             : 
    1002             :   CompareICStub(Isolate* isolate, ExtraICState extra_ic_state)
    1003      818740 :       : PlatformCodeStub(isolate) {
    1004      818740 :     minor_key_ = extra_ic_state;
    1005             :   }
    1006             : 
    1007       66854 :   ExtraICState GetExtraICState() const final {
    1008       66854 :     return static_cast<ExtraICState>(minor_key_);
    1009             :   }
    1010             : 
    1011        2159 :   void set_known_map(Handle<Map> map) { known_map_ = map; }
    1012             : 
    1013             :   InlineCacheState GetICState() const;
    1014             : 
    1015             :   Token::Value op() const {
    1016      146357 :     return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
    1017             :   }
    1018             : 
    1019             :   CompareICState::State left() const {
    1020             :     return LeftStateBits::decode(minor_key_);
    1021             :   }
    1022             :   CompareICState::State right() const {
    1023             :     return RightStateBits::decode(minor_key_);
    1024             :   }
    1025             :   CompareICState::State state() const { return StateBits::decode(minor_key_); }
    1026             : 
    1027             :  private:
    1028       66854 :   Code::Kind GetCodeKind() const override { return Code::COMPARE_IC; }
    1029             : 
    1030             :   void GenerateBooleans(MacroAssembler* masm);
    1031             :   void GenerateSmis(MacroAssembler* masm);
    1032             :   void GenerateNumbers(MacroAssembler* masm);
    1033             :   void GenerateInternalizedStrings(MacroAssembler* masm);
    1034             :   void GenerateStrings(MacroAssembler* masm);
    1035             :   void GenerateUniqueNames(MacroAssembler* masm);
    1036             :   void GenerateReceivers(MacroAssembler* masm);
    1037             :   void GenerateMiss(MacroAssembler* masm);
    1038             :   void GenerateKnownReceivers(MacroAssembler* masm);
    1039             :   void GenerateGeneric(MacroAssembler* masm);
    1040             : 
    1041       36258 :   bool strict() const { return op() == Token::EQ_STRICT; }
    1042             :   Condition GetCondition() const;
    1043             : 
    1044             :   // Although we don't cache anything in the special cache we have to define
    1045             :   // this predicate to avoid appearance of code stubs with embedded maps in
    1046             :   // the global stub cache.
    1047     1055692 :   bool UseSpecialCache() override {
    1048     1055692 :     return state() == CompareICState::KNOWN_RECEIVER;
    1049             :   }
    1050             : 
    1051             :   class OpBits : public BitField<int, 0, 3> {};
    1052             :   class LeftStateBits : public BitField<CompareICState::State, 3, 4> {};
    1053             :   class RightStateBits : public BitField<CompareICState::State, 7, 4> {};
    1054             :   class StateBits : public BitField<CompareICState::State, 11, 4> {};
    1055             : 
    1056             :   Handle<Map> known_map_;
    1057             : 
    1058           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
    1059     1185084 :   DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub);
    1060             : };
    1061             : 
    1062             : 
    1063           0 : class CEntryStub : public PlatformCodeStub {
    1064             :  public:
    1065             :   CEntryStub(Isolate* isolate, int result_size,
    1066             :              SaveFPRegsMode save_doubles = kDontSaveFPRegs,
    1067             :              ArgvMode argv_mode = kArgvOnStack, bool builtin_exit_frame = false)
    1068     3459629 :       : PlatformCodeStub(isolate) {
    1069     4505422 :     minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs) |
    1070     1247487 :                  FrameTypeBits::encode(builtin_exit_frame) |
    1071     4545164 :                  ArgvMode::encode(argv_mode == kArgvInRegister);
    1072             :     DCHECK(result_size == 1 || result_size == 2 || result_size == 3);
    1073     3459629 :     minor_key_ = ResultSizeBits::update(minor_key_, result_size);
    1074             :   }
    1075             : 
    1076             :   // The version of this stub that doesn't save doubles is generated ahead of
    1077             :   // time, so it's OK to call it from other stubs that can't cope with GC during
    1078             :   // their code generation.  On machines that always have gp registers (x64) we
    1079             :   // can generate both variants ahead of time.
    1080             :   static void GenerateAheadOfTime(Isolate* isolate);
    1081             : 
    1082             :  private:
    1083             :   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
    1084             :   bool argv_in_register() const { return ArgvMode::decode(minor_key_); }
    1085             :   bool is_builtin_exit() const { return FrameTypeBits::decode(minor_key_); }
    1086             :   int result_size() const { return ResultSizeBits::decode(minor_key_); }
    1087             : 
    1088             :   bool NeedsImmovableCode() override;
    1089             : 
    1090             :   class SaveDoublesBits : public BitField<bool, 0, 1> {};
    1091             :   class ArgvMode : public BitField<bool, 1, 1> {};
    1092             :   class FrameTypeBits : public BitField<bool, 2, 1> {};
    1093             :   class ResultSizeBits : public BitField<int, 3, 3> {};
    1094             : 
    1095           0 :   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
    1096     3114404 :   DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub);
    1097             : };
    1098             : 
    1099             : 
    1100           0 : class JSEntryStub : public PlatformCodeStub {
    1101             :  public:
    1102             :   JSEntryStub(Isolate* isolate, StackFrame::Type type)
    1103          86 :       : PlatformCodeStub(isolate) {
    1104             :     DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT);
    1105          86 :     minor_key_ = StackFrameTypeBits::encode(type);
    1106             :   }
    1107             : 
    1108             :  private:
    1109             :   void FinishCode(Handle<Code> code) override;
    1110             : 
    1111          86 :   void PrintName(std::ostream& os) const override {  // NOLINT
    1112             :     os << (type() == StackFrame::ENTRY ? "JSEntryStub"
    1113          86 :                                        : "JSConstructEntryStub");
    1114          86 :   }
    1115             : 
    1116             :   StackFrame::Type type() const {
    1117             :     return StackFrameTypeBits::decode(minor_key_);
    1118             :   }
    1119             : 
    1120             :   class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {};
    1121             : 
    1122             :   int handler_offset_;
    1123             : 
    1124           0 :   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
    1125         258 :   DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
    1126             : };
    1127             : 
    1128             : // TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
    1129           0 : class CallConstructStub final : public PlatformCodeStub {
    1130             :  public:
    1131      123776 :   explicit CallConstructStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
    1132             : 
    1133           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct);
    1134      137610 :   DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub);
    1135             : };
    1136             : 
    1137             : 
    1138             : enum ReceiverCheckMode {
    1139             :   // We don't know anything about the receiver.
    1140             :   RECEIVER_IS_UNKNOWN,
    1141             : 
    1142             :   // We know the receiver is a string.
    1143             :   RECEIVER_IS_STRING
    1144             : };
    1145             : 
    1146             : 
    1147             : enum EmbedMode {
    1148             :   // The code being generated is part of an IC handler, which may MISS
    1149             :   // to an IC in failure cases.
    1150             :   PART_OF_IC_HANDLER,
    1151             : 
    1152             :   NOT_PART_OF_IC_HANDLER
    1153             : };
    1154             : 
    1155             : 
    1156             : // Generates code implementing String.prototype.charCodeAt.
    1157             : //
    1158             : // Only supports the case when the receiver is a string and the index
    1159             : // is a number (smi or heap number) that is a valid index into the
    1160             : // string. Additional index constraints are specified by the
    1161             : // flags. Otherwise, bails out to the provided labels.
    1162             : //
    1163             : // Register usage: |object| may be changed to another string in a way
    1164             : // that doesn't affect charCodeAt/charAt semantics, |index| is
    1165             : // preserved, |scratch| and |result| are clobbered.
    1166             : class StringCharCodeAtGenerator {
    1167             :  public:
    1168             :   StringCharCodeAtGenerator(Register object, Register index, Register result,
    1169             :                             Label* receiver_not_string, Label* index_not_number,
    1170             :                             Label* index_out_of_range,
    1171             :                             ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
    1172             :       : object_(object),
    1173             :         index_(index),
    1174             :         result_(result),
    1175             :         receiver_not_string_(receiver_not_string),
    1176             :         index_not_number_(index_not_number),
    1177             :         index_out_of_range_(index_out_of_range),
    1178          64 :         check_mode_(check_mode) {
    1179             :     DCHECK(!result_.is(object_));
    1180             :     DCHECK(!result_.is(index_));
    1181             :   }
    1182             : 
    1183             :   // Generates the fast case code. On the fallthrough path |result|
    1184             :   // register contains the result.
    1185             :   void GenerateFast(MacroAssembler* masm);
    1186             : 
    1187             :   // Generates the slow case code. Must not be naturally
    1188             :   // reachable. Expected to be put after a ret instruction (e.g., in
    1189             :   // deferred code). Always jumps back to the fast case.
    1190             :   void GenerateSlow(MacroAssembler* masm, EmbedMode embed_mode,
    1191             :                     const RuntimeCallHelper& call_helper);
    1192             : 
    1193             :  private:
    1194             :   Register object_;
    1195             :   Register index_;
    1196             :   Register result_;
    1197             : 
    1198             :   Label* receiver_not_string_;
    1199             :   Label* index_not_number_;
    1200             :   Label* index_out_of_range_;
    1201             : 
    1202             :   ReceiverCheckMode check_mode_;
    1203             : 
    1204             :   Label call_runtime_;
    1205             :   Label index_not_smi_;
    1206             :   Label got_smi_index_;
    1207             :   Label exit_;
    1208             : 
    1209             :   DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
    1210             : };
    1211             : 
    1212           0 : class CallICTrampolineStub : public CallICStub {
    1213             :  public:
    1214             :   CallICTrampolineStub(Isolate* isolate, ConvertReceiverMode convert_mode,
    1215             :                        TailCallMode tail_call_mode)
    1216     1105373 :       : CallICStub(isolate, convert_mode, tail_call_mode) {}
    1217             : 
    1218       52320 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallICTrampoline);
    1219     1210172 :   DEFINE_TURBOFAN_CODE_STUB(CallICTrampoline, CallICStub);
    1220             : };
    1221             : 
    1222           0 : class DoubleToIStub : public PlatformCodeStub {
    1223             :  public:
    1224             :   DoubleToIStub(Isolate* isolate, Register source, Register destination,
    1225             :                 int offset, bool is_truncating, bool skip_fastpath = false)
    1226       93526 :       : PlatformCodeStub(isolate) {
    1227       93526 :     minor_key_ = SourceRegisterBits::encode(source.code()) |
    1228       93526 :                  DestinationRegisterBits::encode(destination.code()) |
    1229       93526 :                  OffsetBits::encode(offset) |
    1230             :                  IsTruncatingBits::encode(is_truncating) |
    1231       93526 :                  SkipFastPathBits::encode(skip_fastpath) |
    1232      187052 :                  SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
    1233             :   }
    1234             : 
    1235           0 :   bool SometimesSetsUpAFrame() override { return false; }
    1236             : 
    1237             :  private:
    1238             :   Register source() const {
    1239             :     return Register::from_code(SourceRegisterBits::decode(minor_key_));
    1240             :   }
    1241             :   Register destination() const {
    1242             :     return Register::from_code(DestinationRegisterBits::decode(minor_key_));
    1243             :   }
    1244             :   bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); }
    1245             :   bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); }
    1246             :   int offset() const { return OffsetBits::decode(minor_key_); }
    1247             : 
    1248             :   static const int kBitsPerRegisterNumber = 6;
    1249             :   STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters);
    1250             :   class SourceRegisterBits:
    1251             :       public BitField<int, 0, kBitsPerRegisterNumber> {};  // NOLINT
    1252             :   class DestinationRegisterBits:
    1253             :       public BitField<int, kBitsPerRegisterNumber,
    1254             :         kBitsPerRegisterNumber> {};  // NOLINT
    1255             :   class IsTruncatingBits:
    1256             :       public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {};  // NOLINT
    1257             :   class OffsetBits:
    1258             :       public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {};  // NOLINT
    1259             :   class SkipFastPathBits:
    1260             :       public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {};  // NOLINT
    1261             :   class SSE3Bits:
    1262             :       public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {};  // NOLINT
    1263             : 
    1264           0 :   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
    1265      121356 :   DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
    1266             : };
    1267             : 
    1268          40 : class ScriptContextFieldStub : public TurboFanCodeStub {
    1269             :  public:
    1270             :   ScriptContextFieldStub(Isolate* isolate,
    1271             :                          const ScriptContextTable::LookupResult* lookup_result)
    1272       55496 :       : TurboFanCodeStub(isolate) {
    1273             :     DCHECK(Accepted(lookup_result));
    1274      110992 :     minor_key_ = ContextIndexBits::encode(lookup_result->context_index) |
    1275      110992 :                  SlotIndexBits::encode(lookup_result->slot_index);
    1276             :   }
    1277             : 
    1278       13544 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
    1279             : 
    1280             :   int context_index() const { return ContextIndexBits::decode(minor_key_); }
    1281             : 
    1282             :   int slot_index() const { return SlotIndexBits::decode(minor_key_); }
    1283             : 
    1284             :   static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
    1285      166488 :     return ContextIndexBits::is_valid(lookup_result->context_index) &&
    1286       55496 :            SlotIndexBits::is_valid(lookup_result->slot_index);
    1287             :   }
    1288             : 
    1289             :  private:
    1290             :   static const int kContextIndexBits = 9;
    1291             :   static const int kSlotIndexBits = 12;
    1292             :   class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
    1293             :   class SlotIndexBits
    1294             :       : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
    1295             : 
    1296           0 :   DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, TurboFanCodeStub);
    1297             : };
    1298             : 
    1299             : 
    1300           0 : class LoadScriptContextFieldStub : public ScriptContextFieldStub {
    1301             :  public:
    1302             :   LoadScriptContextFieldStub(
    1303             :       Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
    1304       55456 :       : ScriptContextFieldStub(isolate, lookup_result) {}
    1305             : 
    1306       14961 :   ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
    1307             : 
    1308             :  private:
    1309       29922 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(LoadWithVector);
    1310      115300 :   DEFINE_TURBOFAN_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
    1311             : };
    1312             : 
    1313             : 
    1314          40 : class StoreScriptContextFieldStub : public ScriptContextFieldStub {
    1315             :  public:
    1316             :   StoreScriptContextFieldStub(
    1317             :       Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
    1318          40 :       : ScriptContextFieldStub(isolate, lookup_result) {}
    1319             : 
    1320          31 :   ExtraICState GetExtraICState() const override { return Code::STORE_IC; }
    1321             : 
    1322             :  private:
    1323          62 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
    1324         164 :   DEFINE_TURBOFAN_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
    1325             : };
    1326             : 
    1327      254068 : class StoreFastElementStub : public TurboFanCodeStub {
    1328             :  public:
    1329             :   StoreFastElementStub(Isolate* isolate, bool is_js_array,
    1330             :                        ElementsKind elements_kind, KeyedAccessStoreMode mode)
    1331      254068 :       : TurboFanCodeStub(isolate) {
    1332      253466 :     minor_key_ = CommonStoreModeBits::encode(mode) |
    1333      253982 :                  ElementsKindBits::encode(elements_kind) |
    1334      254068 :                  IsJSArrayBits::encode(is_js_array);
    1335             :   }
    1336             : 
    1337             :   static void GenerateAheadOfTime(Isolate* isolate);
    1338             : 
    1339             :   bool is_js_array() const { return IsJSArrayBits::decode(minor_key_); }
    1340             : 
    1341             :   ElementsKind elements_kind() const {
    1342             :     return ElementsKindBits::decode(minor_key_);
    1343             :   }
    1344             : 
    1345             :   KeyedAccessStoreMode store_mode() const {
    1346             :     return CommonStoreModeBits::decode(minor_key_);
    1347             :   }
    1348             : 
    1349        3844 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
    1350        3844 :   ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
    1351             : 
    1352             :  private:
    1353             :   class ElementsKindBits
    1354             :       : public BitField<ElementsKind, CommonStoreModeBits::kNext, 8> {};
    1355             :   class IsJSArrayBits : public BitField<bool, ElementsKindBits::kNext, 1> {};
    1356             : 
    1357        7688 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
    1358      269444 :   DEFINE_TURBOFAN_CODE_STUB(StoreFastElement, TurboFanCodeStub);
    1359             : };
    1360             : 
    1361             : 
    1362         402 : class TransitionElementsKindStub : public HydrogenCodeStub {
    1363             :  public:
    1364             :   TransitionElementsKindStub(Isolate* isolate, ElementsKind from_kind,
    1365             :                              ElementsKind to_kind)
    1366         402 :       : HydrogenCodeStub(isolate) {
    1367             :     set_sub_minor_key(FromKindBits::encode(from_kind) |
    1368         402 :                       ToKindBits::encode(to_kind));
    1369             :   }
    1370             : 
    1371             :   ElementsKind from_kind() const {
    1372          54 :     return FromKindBits::decode(sub_minor_key());
    1373             :   }
    1374             : 
    1375             :   ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); }
    1376             : 
    1377             :  private:
    1378             :   class FromKindBits: public BitField<ElementsKind, 8, 8> {};
    1379             :   class ToKindBits: public BitField<ElementsKind, 0, 8> {};
    1380             : 
    1381         548 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind);
    1382         730 :   DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub);
    1383             : };
    1384             : 
    1385           0 : class AllocateHeapNumberStub : public TurboFanCodeStub {
    1386             :  public:
    1387             :   explicit AllocateHeapNumberStub(Isolate* isolate)
    1388       12944 :       : TurboFanCodeStub(isolate) {}
    1389             : 
    1390             :   void InitializeDescriptor(CodeStubDescriptor* descriptor) override;
    1391             : 
    1392        1196 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
    1393       15336 :   DEFINE_TURBOFAN_CODE_STUB(AllocateHeapNumber, TurboFanCodeStub);
    1394             : };
    1395             : 
    1396        1460 : class CommonArrayConstructorStub : public TurboFanCodeStub {
    1397             :  protected:
    1398             :   CommonArrayConstructorStub(Isolate* isolate, ElementsKind kind,
    1399             :                              AllocationSiteOverrideMode override_mode)
    1400        2388 :       : TurboFanCodeStub(isolate) {
    1401             :     // It only makes sense to override local allocation site behavior
    1402             :     // if there is a difference between the global allocation site policy
    1403             :     // for an ElementsKind and the desired usage of the stub.
    1404             :     DCHECK(override_mode != DISABLE_ALLOCATION_SITES ||
    1405             :            AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
    1406             :     set_sub_minor_key(ElementsKindBits::encode(kind) |
    1407         840 :                       AllocationSiteOverrideModeBits::encode(override_mode));
    1408             :   }
    1409             : 
    1410        2388 :   void set_sub_minor_key(uint32_t key) { minor_key_ = key; }
    1411             : 
    1412             :   uint32_t sub_minor_key() const { return minor_key_; }
    1413             : 
    1414             :   CommonArrayConstructorStub(uint32_t key, Isolate* isolate)
    1415           0 :       : TurboFanCodeStub(key, isolate) {}
    1416             : 
    1417             :  public:
    1418         860 :   ElementsKind elements_kind() const {
    1419             :     return ElementsKindBits::decode(sub_minor_key());
    1420             :   }
    1421             : 
    1422         516 :   AllocationSiteOverrideMode override_mode() const {
    1423             :     return AllocationSiteOverrideModeBits::decode(sub_minor_key());
    1424             :   }
    1425             : 
    1426             :   static void GenerateStubsAheadOfTime(Isolate* isolate);
    1427             : 
    1428             :  private:
    1429             :   // Ensure data fits within available bits.
    1430             :   STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
    1431             : 
    1432             :   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
    1433             :   class AllocationSiteOverrideModeBits
    1434             :       : public BitField<AllocationSiteOverrideMode, 8, 1> {};  // NOLINT
    1435             : };
    1436             : 
    1437         602 : class ArrayNoArgumentConstructorStub : public CommonArrayConstructorStub {
    1438             :  public:
    1439             :   ArrayNoArgumentConstructorStub(
    1440             :       Isolate* isolate, ElementsKind kind,
    1441             :       AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
    1442         645 :       : CommonArrayConstructorStub(isolate, kind, override_mode) {}
    1443             : 
    1444             :  private:
    1445         344 :   void PrintName(std::ostream& os) const override {  // NOLINT
    1446         344 :     os << "ArrayNoArgumentConstructorStub";
    1447         344 :   }
    1448             : 
    1449         688 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
    1450        1677 :   DEFINE_TURBOFAN_CODE_STUB(ArrayNoArgumentConstructor,
    1451             :                             CommonArrayConstructorStub);
    1452             : };
    1453             : 
    1454          86 : class InternalArrayNoArgumentConstructorStub
    1455             :     : public CommonArrayConstructorStub {
    1456             :  public:
    1457             :   InternalArrayNoArgumentConstructorStub(Isolate* isolate, ElementsKind kind)
    1458         172 :       : CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
    1459             : 
    1460             :  private:
    1461          86 :   void PrintName(std::ostream& os) const override {  // NOLINT
    1462          86 :     os << "InternalArrayNoArgumentConstructorStub";
    1463          86 :   }
    1464             : 
    1465         172 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayNoArgumentConstructor);
    1466         430 :   DEFINE_TURBOFAN_CODE_STUB(InternalArrayNoArgumentConstructor,
    1467             :                             CommonArrayConstructorStub);
    1468             : };
    1469             : 
    1470         643 : class ArraySingleArgumentConstructorStub : public CommonArrayConstructorStub {
    1471             :  public:
    1472             :   ArraySingleArgumentConstructorStub(
    1473             :       Isolate* isolate, ElementsKind kind,
    1474             :       AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
    1475        1356 :       : CommonArrayConstructorStub(isolate, kind, override_mode) {}
    1476             : 
    1477             :  private:
    1478         344 :   void PrintName(std::ostream& os) const override {  // NOLINT
    1479         344 :     os << "ArraySingleArgumentConstructorStub";
    1480         344 :   }
    1481             : 
    1482        1330 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
    1483        2388 :   DEFINE_TURBOFAN_CODE_STUB(ArraySingleArgumentConstructor,
    1484             :                             CommonArrayConstructorStub);
    1485             : };
    1486             : 
    1487         129 : class InternalArraySingleArgumentConstructorStub
    1488             :     : public CommonArrayConstructorStub {
    1489             :  public:
    1490             :   InternalArraySingleArgumentConstructorStub(Isolate* isolate,
    1491             :                                              ElementsKind kind)
    1492         215 :       : CommonArrayConstructorStub(isolate, kind, DONT_OVERRIDE) {}
    1493             : 
    1494             :  private:
    1495          86 :   void PrintName(std::ostream& os) const override {  // NOLINT
    1496          86 :     os << "InternalArraySingleArgumentConstructorStub";
    1497          86 :   }
    1498             : 
    1499         172 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(ArraySingleArgumentConstructor);
    1500         473 :   DEFINE_TURBOFAN_CODE_STUB(InternalArraySingleArgumentConstructor,
    1501             :                             CommonArrayConstructorStub);
    1502             : };
    1503             : 
    1504           0 : class ArrayNArgumentsConstructorStub : public PlatformCodeStub {
    1505             :  public:
    1506             :   explicit ArrayNArgumentsConstructorStub(Isolate* isolate)
    1507         302 :       : PlatformCodeStub(isolate) {}
    1508             : 
    1509           0 :   CallInterfaceDescriptor GetCallInterfaceDescriptor() const override {
    1510          42 :     return ArrayNArgumentsConstructorDescriptor(isolate());
    1511             :   }
    1512             : 
    1513             :  private:
    1514         431 :   DEFINE_PLATFORM_CODE_STUB(ArrayNArgumentsConstructor, PlatformCodeStub);
    1515             : };
    1516             : 
    1517        2707 : class StoreSlowElementStub : public TurboFanCodeStub {
    1518             :  public:
    1519             :   StoreSlowElementStub(Isolate* isolate, KeyedAccessStoreMode mode)
    1520        2707 :       : TurboFanCodeStub(isolate) {
    1521        2707 :     minor_key_ = CommonStoreModeBits::encode(mode);
    1522             :   }
    1523             : 
    1524         643 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
    1525         643 :   ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
    1526             : 
    1527             :  private:
    1528        1286 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
    1529        5279 :   DEFINE_TURBOFAN_CODE_STUB(StoreSlowElement, TurboFanCodeStub);
    1530             : };
    1531             : 
    1532           0 : class ToBooleanICStub : public HydrogenCodeStub {
    1533             :  public:
    1534             :   ToBooleanICStub(Isolate* isolate, ExtraICState state)
    1535      130693 :       : HydrogenCodeStub(isolate) {
    1536      522772 :     set_sub_minor_key(HintsBits::encode(static_cast<uint16_t>(state)));
    1537             :   }
    1538             : 
    1539             :   bool UpdateStatus(Handle<Object> object);
    1540             :   ToBooleanHints hints() const {
    1541      317826 :     return ToBooleanHints(HintsBits::decode(sub_minor_key()));
    1542             :   }
    1543             : 
    1544       21342 :   Code::Kind GetCodeKind() const override { return Code::TO_BOOLEAN_IC; }
    1545             :   void PrintState(std::ostream& os) const override;  // NOLINT
    1546             : 
    1547           0 :   bool SometimesSetsUpAFrame() override { return false; }
    1548             : 
    1549      231709 :   static Handle<Code> GetUninitialized(Isolate* isolate) {
    1550      231709 :     return ToBooleanICStub(isolate, UNINITIALIZED).GetCode();
    1551             :   }
    1552             : 
    1553       42684 :   ExtraICState GetExtraICState() const override { return hints(); }
    1554             : 
    1555             :   InlineCacheState GetICState() const {
    1556      392079 :     if (hints() == ToBooleanHint::kNone) {
    1557             :       return ::v8::internal::UNINITIALIZED;
    1558             :     } else {
    1559             :       return MONOMORPHIC;
    1560             :     }
    1561             :   }
    1562             : 
    1563             :  private:
    1564             :   ToBooleanICStub(Isolate* isolate, InitializationState init_state)
    1565      231709 :       : HydrogenCodeStub(isolate, init_state) {}
    1566             : 
    1567             :   static const int kNumHints = 8;
    1568             :   STATIC_ASSERT(static_cast<int>(ToBooleanHint::kAny) ==
    1569             :                 ((1 << kNumHints) - 1));
    1570             :   class HintsBits : public BitField<uint16_t, 0, kNumHints> {};
    1571             : 
    1572      133332 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(TypeConversion);
    1573      450418 :   DEFINE_HYDROGEN_CODE_STUB(ToBooleanIC, HydrogenCodeStub);
    1574             : };
    1575             : 
    1576        8238 : class ElementsTransitionAndStoreStub : public TurboFanCodeStub {
    1577             :  public:
    1578             :   ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind,
    1579             :                                  ElementsKind to_kind, bool is_jsarray,
    1580             :                                  KeyedAccessStoreMode store_mode)
    1581        8238 :       : TurboFanCodeStub(isolate) {
    1582        8238 :     minor_key_ = CommonStoreModeBits::encode(store_mode) |
    1583       16476 :                  FromBits::encode(from_kind) | ToBits::encode(to_kind) |
    1584        8238 :                  IsJSArrayBits::encode(is_jsarray);
    1585             :   }
    1586             : 
    1587             :   ElementsKind from_kind() const { return FromBits::decode(minor_key_); }
    1588             :   ElementsKind to_kind() const { return ToBits::decode(minor_key_); }
    1589             :   bool is_jsarray() const { return IsJSArrayBits::decode(minor_key_); }
    1590             :   KeyedAccessStoreMode store_mode() const {
    1591             :     return CommonStoreModeBits::decode(minor_key_);
    1592             :   }
    1593             : 
    1594        2138 :   Code::Kind GetCodeKind() const override { return Code::HANDLER; }
    1595        2138 :   ExtraICState GetExtraICState() const override { return Code::KEYED_STORE_IC; }
    1596             : 
    1597             :  private:
    1598             :   class FromBits
    1599             :       : public BitField<ElementsKind, CommonStoreModeBits::kNext, 8> {};
    1600             :   class ToBits : public BitField<ElementsKind, 11, 8> {};
    1601             :   class IsJSArrayBits : public BitField<bool, 19, 1> {};
    1602             : 
    1603        4276 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreTransition);
    1604       16790 :   DEFINE_TURBOFAN_CODE_STUB(ElementsTransitionAndStore, TurboFanCodeStub);
    1605             : };
    1606             : 
    1607             : 
    1608       26647 : class StubFailureTrampolineStub : public PlatformCodeStub {
    1609             :  public:
    1610             :   StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode)
    1611      148019 :       : PlatformCodeStub(isolate) {
    1612       87333 :     minor_key_ = FunctionModeField::encode(function_mode);
    1613             :   }
    1614             : 
    1615             :   static void GenerateAheadOfTime(Isolate* isolate);
    1616             : 
    1617             :  private:
    1618             :   StubFunctionMode function_mode() const {
    1619             :     return FunctionModeField::decode(minor_key_);
    1620             :   }
    1621             : 
    1622             :   class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
    1623             : 
    1624           0 :   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
    1625      148105 :   DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub);
    1626             : };
    1627             : 
    1628             : 
    1629           0 : class ProfileEntryHookStub : public PlatformCodeStub {
    1630             :  public:
    1631           0 :   explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
    1632             : 
    1633             :   // The profile entry hook function is not allowed to cause a GC.
    1634           0 :   bool SometimesSetsUpAFrame() override { return false; }
    1635             : 
    1636             :   // Generates a call to the entry hook if it's enabled.
    1637             :   static void MaybeCallEntryHook(MacroAssembler* masm);
    1638             : 
    1639             :  private:
    1640             :   static void EntryHookTrampoline(intptr_t function,
    1641             :                                   intptr_t stack_pointer,
    1642             :                                   Isolate* isolate);
    1643             : 
    1644             :   // ProfileEntryHookStub is called at the start of a function, so it has the
    1645             :   // same register set.
    1646           0 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction)
    1647           0 :   DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub);
    1648             : };
    1649             : 
    1650             : 
    1651           0 : class StoreBufferOverflowStub : public PlatformCodeStub {
    1652             :  public:
    1653             :   StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp)
    1654      254421 :       : PlatformCodeStub(isolate) {
    1655      326784 :     minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs);
    1656             :   }
    1657             : 
    1658             :   static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
    1659           0 :   bool SometimesSetsUpAFrame() override { return false; }
    1660             : 
    1661             :  private:
    1662             :   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
    1663             : 
    1664             :   class SaveDoublesBits : public BitField<bool, 0, 1> {};
    1665             : 
    1666           0 :   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
    1667      254679 :   DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
    1668             : };
    1669             : 
    1670           0 : class SubStringStub : public TurboFanCodeStub {
    1671             :  public:
    1672         890 :   explicit SubStringStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
    1673             : 
    1674        1070 :   DEFINE_CALL_INTERFACE_DESCRIPTOR(SubString);
    1675        1062 :   DEFINE_TURBOFAN_CODE_STUB(SubString, TurboFanCodeStub);
    1676             : };
    1677             : 
    1678             : 
    1679             : #undef DEFINE_CALL_INTERFACE_DESCRIPTOR
    1680             : #undef DEFINE_PLATFORM_CODE_STUB
    1681             : #undef DEFINE_HANDLER_CODE_STUB
    1682             : #undef DEFINE_HYDROGEN_CODE_STUB
    1683             : #undef DEFINE_CODE_STUB
    1684             : #undef DEFINE_CODE_STUB_BASE
    1685             : 
    1686             : }  // namespace internal
    1687             : }  // namespace v8
    1688             : 
    1689             : #endif  // V8_CODE_STUBS_H_

Generated by: LCOV version 1.10