LCOV - code coverage report
Current view: top level - src/compiler - code-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 21 21 100.0 %
Date: 2017-04-26 Functions: 21 21 100.0 %

          Line data    Source code
       1             : // Copyright 2015 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_COMPILER_CODE_ASSEMBLER_H_
       6             : #define V8_COMPILER_CODE_ASSEMBLER_H_
       7             : 
       8             : #include <map>
       9             : #include <memory>
      10             : 
      11             : // Clients of this interface shouldn't depend on lots of compiler internals.
      12             : // Do not include anything from src/compiler here!
      13             : #include "src/allocation.h"
      14             : #include "src/builtins/builtins.h"
      15             : #include "src/code-factory.h"
      16             : #include "src/globals.h"
      17             : #include "src/heap/heap.h"
      18             : #include "src/machine-type.h"
      19             : #include "src/runtime/runtime.h"
      20             : #include "src/zone/zone-containers.h"
      21             : 
      22             : namespace v8 {
      23             : namespace internal {
      24             : 
      25             : class Callable;
      26             : class CallInterfaceDescriptor;
      27             : class Isolate;
      28             : class Factory;
      29             : class Zone;
      30             : 
      31             : namespace compiler {
      32             : 
      33             : class CallDescriptor;
      34             : class CodeAssemblerLabel;
      35             : class CodeAssemblerVariable;
      36             : class CodeAssemblerState;
      37             : class Node;
      38             : class RawMachineAssembler;
      39             : class RawMachineLabel;
      40             : 
      41             : typedef ZoneList<CodeAssemblerVariable*> CodeAssemblerVariableList;
      42             : 
      43             : typedef std::function<void()> CodeAssemblerCallback;
      44             : 
      45             : #define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
      46             :   V(Float32Equal)                                \
      47             :   V(Float32LessThan)                             \
      48             :   V(Float32LessThanOrEqual)                      \
      49             :   V(Float32GreaterThan)                          \
      50             :   V(Float32GreaterThanOrEqual)                   \
      51             :   V(Float64Equal)                                \
      52             :   V(Float64LessThan)                             \
      53             :   V(Float64LessThanOrEqual)                      \
      54             :   V(Float64GreaterThan)                          \
      55             :   V(Float64GreaterThanOrEqual)                   \
      56             :   V(Int32GreaterThan)                            \
      57             :   V(Int32GreaterThanOrEqual)                     \
      58             :   V(Int32LessThan)                               \
      59             :   V(Int32LessThanOrEqual)                        \
      60             :   V(IntPtrLessThan)                              \
      61             :   V(IntPtrLessThanOrEqual)                       \
      62             :   V(IntPtrGreaterThan)                           \
      63             :   V(IntPtrGreaterThanOrEqual)                    \
      64             :   V(IntPtrEqual)                                 \
      65             :   V(Uint32LessThan)                              \
      66             :   V(Uint32LessThanOrEqual)                       \
      67             :   V(Uint32GreaterThanOrEqual)                    \
      68             :   V(UintPtrLessThan)                             \
      69             :   V(UintPtrLessThanOrEqual)                      \
      70             :   V(UintPtrGreaterThan)                          \
      71             :   V(UintPtrGreaterThanOrEqual)                   \
      72             :   V(WordEqual)                                   \
      73             :   V(WordNotEqual)                                \
      74             :   V(Word32Equal)                                 \
      75             :   V(Word32NotEqual)                              \
      76             :   V(Word64Equal)                                 \
      77             :   V(Word64NotEqual)
      78             : 
      79             : #define CODE_ASSEMBLER_BINARY_OP_LIST(V)   \
      80             :   CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
      81             :   V(Float64Add)                            \
      82             :   V(Float64Sub)                            \
      83             :   V(Float64Mul)                            \
      84             :   V(Float64Div)                            \
      85             :   V(Float64Mod)                            \
      86             :   V(Float64Atan2)                          \
      87             :   V(Float64Pow)                            \
      88             :   V(Float64Max)                            \
      89             :   V(Float64Min)                            \
      90             :   V(Float64InsertLowWord32)                \
      91             :   V(Float64InsertHighWord32)               \
      92             :   V(IntPtrAddWithOverflow)                 \
      93             :   V(IntPtrSubWithOverflow)                 \
      94             :   V(IntPtrMul)                             \
      95             :   V(Int32Add)                              \
      96             :   V(Int32AddWithOverflow)                  \
      97             :   V(Int32Sub)                              \
      98             :   V(Int32Mul)                              \
      99             :   V(Int32MulWithOverflow)                  \
     100             :   V(Int32Div)                              \
     101             :   V(Int32Mod)                              \
     102             :   V(WordOr)                                \
     103             :   V(WordAnd)                               \
     104             :   V(WordXor)                               \
     105             :   V(WordShl)                               \
     106             :   V(WordShr)                               \
     107             :   V(WordSar)                               \
     108             :   V(WordRor)                               \
     109             :   V(Word32Or)                              \
     110             :   V(Word32And)                             \
     111             :   V(Word32Xor)                             \
     112             :   V(Word32Shl)                             \
     113             :   V(Word32Shr)                             \
     114             :   V(Word32Sar)                             \
     115             :   V(Word32Ror)                             \
     116             :   V(Word64Or)                              \
     117             :   V(Word64And)                             \
     118             :   V(Word64Xor)                             \
     119             :   V(Word64Shr)                             \
     120             :   V(Word64Sar)                             \
     121             :   V(Word64Ror)
     122             : 
     123             : #define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
     124             :   V(Float64Abs)                         \
     125             :   V(Float64Acos)                        \
     126             :   V(Float64Acosh)                       \
     127             :   V(Float64Asin)                        \
     128             :   V(Float64Asinh)                       \
     129             :   V(Float64Atan)                        \
     130             :   V(Float64Atanh)                       \
     131             :   V(Float64Cos)                         \
     132             :   V(Float64Cosh)                        \
     133             :   V(Float64Exp)                         \
     134             :   V(Float64Expm1)                       \
     135             :   V(Float64Log)                         \
     136             :   V(Float64Log1p)                       \
     137             :   V(Float64Log2)                        \
     138             :   V(Float64Log10)                       \
     139             :   V(Float64Cbrt)                        \
     140             :   V(Float64Neg)                         \
     141             :   V(Float64Sin)                         \
     142             :   V(Float64Sinh)                        \
     143             :   V(Float64Sqrt)                        \
     144             :   V(Float64Tan)                         \
     145             :   V(Float64Tanh)                        \
     146             :   V(Float64ExtractLowWord32)            \
     147             :   V(Float64ExtractHighWord32)           \
     148             :   V(BitcastTaggedToWord)                \
     149             :   V(BitcastWordToTagged)                \
     150             :   V(BitcastWordToTaggedSigned)          \
     151             :   V(TruncateFloat64ToFloat32)           \
     152             :   V(TruncateFloat64ToWord32)            \
     153             :   V(TruncateInt64ToInt32)               \
     154             :   V(ChangeFloat32ToFloat64)             \
     155             :   V(ChangeFloat64ToUint32)              \
     156             :   V(ChangeFloat64ToUint64)              \
     157             :   V(ChangeInt32ToFloat64)               \
     158             :   V(ChangeInt32ToInt64)                 \
     159             :   V(ChangeUint32ToFloat64)              \
     160             :   V(ChangeUint32ToUint64)               \
     161             :   V(RoundFloat64ToInt32)                \
     162             :   V(RoundInt32ToFloat32)                \
     163             :   V(Float64SilenceNaN)                  \
     164             :   V(Float64RoundDown)                   \
     165             :   V(Float64RoundUp)                     \
     166             :   V(Float64RoundTiesEven)               \
     167             :   V(Float64RoundTruncate)               \
     168             :   V(Word32Clz)                          \
     169             :   V(Word32Not)                          \
     170             :   V(Int32AbsWithOverflow)               \
     171             :   V(Int64AbsWithOverflow)               \
     172             :   V(IntPtrAbsWithOverflow)              \
     173             :   V(Word32BinaryNot)
     174             : 
     175             : // A "public" interface used by components outside of compiler directory to
     176             : // create code objects with TurboFan's backend. This class is mostly a thin shim
     177             : // around the RawMachineAssembler, and its primary job is to ensure that the
     178             : // innards of the RawMachineAssembler and other compiler implementation details
     179             : // don't leak outside of the the compiler directory..
     180             : //
     181             : // V8 components that need to generate low-level code using this interface
     182             : // should include this header--and this header only--from the compiler directory
     183             : // (this is actually enforced). Since all interesting data structures are
     184             : // forward declared, it's not possible for clients to peek inside the compiler
     185             : // internals.
     186             : //
     187             : // In addition to providing isolation between TurboFan and code generation
     188             : // clients, CodeAssembler also provides an abstraction for creating variables
     189             : // and enhanced Label functionality to merge variable values along paths where
     190             : // they have differing values, including loops.
     191             : //
     192             : // The CodeAssembler itself is stateless (and instances are expected to be
     193             : // temporary-scoped and short-lived); all its state is encapsulated into
     194             : // a CodeAssemblerState instance.
     195             : class V8_EXPORT_PRIVATE CodeAssembler {
     196             :  public:
     197      119506 :   explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {}
     198             :   ~CodeAssembler();
     199             : 
     200             :   static Handle<Code> GenerateCode(CodeAssemblerState* state);
     201             : 
     202             :   bool Is64() const;
     203             :   bool IsFloat64RoundUpSupported() const;
     204             :   bool IsFloat64RoundDownSupported() const;
     205             :   bool IsFloat64RoundTiesEvenSupported() const;
     206             :   bool IsFloat64RoundTruncateSupported() const;
     207             :   bool IsInt32AbsWithOverflowSupported() const;
     208             :   bool IsInt64AbsWithOverflowSupported() const;
     209             :   bool IsIntPtrAbsWithOverflowSupported() const;
     210             : 
     211             :   // Shortened aliases for use in CodeAssembler subclasses.
     212             :   typedef CodeAssemblerLabel Label;
     213             :   typedef CodeAssemblerVariable Variable;
     214             :   typedef CodeAssemblerVariableList VariableList;
     215             : 
     216             :   // ===========================================================================
     217             :   // Base Assembler
     218             :   // ===========================================================================
     219             : 
     220             :   // Constants.
     221             :   Node* Int32Constant(int32_t value);
     222             :   Node* Int64Constant(int64_t value);
     223             :   Node* IntPtrConstant(intptr_t value);
     224             :   Node* NumberConstant(double value);
     225             :   Node* SmiConstant(Smi* value);
     226             :   Node* SmiConstant(int value);
     227             :   Node* HeapConstant(Handle<HeapObject> object);
     228             :   Node* CStringConstant(const char* str);
     229             :   Node* BooleanConstant(bool value);
     230             :   Node* ExternalConstant(ExternalReference address);
     231             :   Node* Float64Constant(double value);
     232             :   Node* NaNConstant();
     233             : 
     234             :   bool ToInt32Constant(Node* node, int32_t& out_value);
     235             :   bool ToInt64Constant(Node* node, int64_t& out_value);
     236             :   bool ToSmiConstant(Node* node, Smi*& out_value);
     237             :   bool ToIntPtrConstant(Node* node, intptr_t& out_value);
     238             : 
     239             :   Node* Parameter(int value);
     240             :   Node* GetJSContextParameter();
     241             :   void Return(Node* value);
     242             :   void Return(Node* value1, Node* value2);
     243             :   void Return(Node* value1, Node* value2, Node* value3);
     244             :   void PopAndReturn(Node* pop, Node* value);
     245             : 
     246             :   void ReturnIf(Node* condition, Node* value);
     247             : 
     248             :   void DebugBreak();
     249             :   void Unreachable();
     250             :   void Comment(const char* format, ...);
     251             : 
     252             :   void Bind(Label* label);
     253             : #if DEBUG
     254             :   void Bind(Label* label, AssemblerDebugInfo debug_info);
     255             : #endif  // DEBUG
     256             :   void Goto(Label* label);
     257             :   void GotoIf(Node* condition, Label* true_label);
     258             :   void GotoIfNot(Node* condition, Label* false_label);
     259             :   void Branch(Node* condition, Label* true_label, Label* false_label);
     260             : 
     261             :   void Switch(Node* index, Label* default_label, const int32_t* case_values,
     262             :               Label** case_labels, size_t case_count);
     263             : 
     264             :   // Access to the frame pointer
     265             :   Node* LoadFramePointer();
     266             :   Node* LoadParentFramePointer();
     267             : 
     268             :   // Access to the stack pointer
     269             :   Node* LoadStackPointer();
     270             : 
     271             :   // Load raw memory location.
     272             :   Node* Load(MachineType rep, Node* base);
     273             :   Node* Load(MachineType rep, Node* base, Node* offset);
     274             :   Node* AtomicLoad(MachineType rep, Node* base, Node* offset);
     275             : 
     276             :   // Load a value from the root array.
     277             :   Node* LoadRoot(Heap::RootListIndex root_index);
     278             : 
     279             :   // Store value to raw memory location.
     280             :   Node* Store(Node* base, Node* value);
     281             :   Node* Store(Node* base, Node* offset, Node* value);
     282             :   Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
     283             :   Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
     284             :   Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
     285             :                             Node* value);
     286             :   Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
     287             :                     Node* value);
     288             : 
     289             :   // Exchange value at raw memory location
     290             :   Node* AtomicExchange(MachineType type, Node* base, Node* offset, Node* value);
     291             : 
     292             :   // Compare and Exchange value at raw memory location
     293             :   Node* AtomicCompareExchange(MachineType type, Node* base, Node* offset,
     294             :                               Node* old_value, Node* new_value);
     295             : 
     296             :   Node* AtomicAdd(MachineType type, Node* base, Node* offset, Node* value);
     297             : 
     298             :   Node* AtomicSub(MachineType type, Node* base, Node* offset, Node* value);
     299             : 
     300             :   Node* AtomicAnd(MachineType type, Node* base, Node* offset, Node* value);
     301             : 
     302             :   Node* AtomicOr(MachineType type, Node* base, Node* offset, Node* value);
     303             : 
     304             :   Node* AtomicXor(MachineType type, Node* base, Node* offset, Node* value);
     305             : 
     306             :   // Store a value to the root array.
     307             :   Node* StoreRoot(Heap::RootListIndex root_index, Node* value);
     308             : 
     309             : // Basic arithmetic operations.
     310             : #define DECLARE_CODE_ASSEMBLER_BINARY_OP(name) Node* name(Node* a, Node* b);
     311             :   CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
     312             : #undef DECLARE_CODE_ASSEMBLER_BINARY_OP
     313             : 
     314             :   Node* IntPtrAdd(Node* left, Node* right);
     315             :   Node* IntPtrSub(Node* left, Node* right);
     316             : 
     317             :   Node* WordShl(Node* value, int shift);
     318             :   Node* WordShr(Node* value, int shift);
     319             :   Node* Word32Shr(Node* value, int shift);
     320             : 
     321             : // Unary
     322             : #define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
     323             :   CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
     324             : #undef DECLARE_CODE_ASSEMBLER_UNARY_OP
     325             : 
     326             :   // Changes a double to an inptr_t for pointer arithmetic outside of Smi range.
     327             :   // Assumes that the double can be exactly represented as an int.
     328             :   Node* ChangeFloat64ToUintPtr(Node* value);
     329             : 
     330             :   // Changes an intptr_t to a double, e.g. for storing an element index
     331             :   // outside Smi range in a HeapNumber. Lossless on 32-bit,
     332             :   // rounds on 64-bit (which doesn't affect valid element indices).
     333             :   Node* RoundIntPtrToFloat64(Node* value);
     334             :   // No-op on 32-bit, otherwise zero extend.
     335             :   Node* ChangeUint32ToWord(Node* value);
     336             :   // No-op on 32-bit, otherwise sign extend.
     337             :   Node* ChangeInt32ToIntPtr(Node* value);
     338             : 
     339             :   // No-op that guarantees that the value is kept alive till this point even
     340             :   // if GC happens.
     341             :   Node* Retain(Node* value);
     342             : 
     343             :   // Projections
     344             :   Node* Projection(int index, Node* value);
     345             : 
     346             :   // Calls
     347             :   template <class... TArgs>
     348             :   Node* CallRuntime(Runtime::FunctionId function, Node* context, TArgs... args);
     349             : 
     350             :   template <class... TArgs>
     351             :   Node* TailCallRuntime(Runtime::FunctionId function, Node* context,
     352             :                         TArgs... args);
     353             : 
     354             :   template <class... TArgs>
     355       42618 :   Node* CallStub(Callable const& callable, Node* context, TArgs... args) {
     356       42618 :     Node* target = HeapConstant(callable.code());
     357       42618 :     return CallStub(callable.descriptor(), target, context, args...);
     358             :   }
     359             : 
     360             :   template <class... TArgs>
     361             :   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
     362             :                  Node* context, TArgs... args) {
     363       46631 :     return CallStubR(descriptor, 1, target, context, args...);
     364             :   }
     365             : 
     366             :   template <class... TArgs>
     367             :   Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
     368             :                   Node* target, Node* context, TArgs... args);
     369             : 
     370             :   Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
     371             :                   int input_count, Node* const* inputs);
     372             : 
     373             :   template <class... TArgs>
     374      112668 :   Node* TailCallStub(Callable const& callable, Node* context, TArgs... args) {
     375      112668 :     Node* target = HeapConstant(callable.code());
     376      112668 :     return TailCallStub(callable.descriptor(), target, context, args...);
     377             :   }
     378             : 
     379             :   template <class... TArgs>
     380             :   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
     381             :                      Node* context, TArgs... args);
     382             : 
     383             :   template <class... TArgs>
     384             :   Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
     385             :                                  Node* target, TArgs... args);
     386             : 
     387             :   template <class... TArgs>
     388       10585 :   Node* CallJS(Callable const& callable, Node* context, Node* function,
     389             :                Node* receiver, TArgs... args) {
     390             :     int argc = static_cast<int>(sizeof...(args));
     391       10585 :     Node* arity = Int32Constant(argc);
     392       10585 :     return CallStub(callable, context, function, arity, receiver, args...);
     393             :   }
     394             : 
     395             :   template <class... TArgs>
     396         358 :   Node* ConstructJS(Callable const& callable, Node* context, Node* new_target,
     397             :                     TArgs... args) {
     398             :     int argc = static_cast<int>(sizeof...(args));
     399         358 :     Node* arity = Int32Constant(argc);
     400         358 :     Node* receiver = LoadRoot(Heap::kUndefinedValueRootIndex);
     401             : 
     402             :     // Construct(target, new_target, arity, receiver, arguments...)
     403             :     return CallStub(callable, context, new_target, new_target, arity, receiver,
     404         358 :                     args...);
     405             :   }
     406             : 
     407             :   Node* CallCFunctionN(Signature<MachineType>* signature, int input_count,
     408             :                        Node* const* inputs);
     409             : 
     410             :   // Call to a C function with one argument.
     411             :   Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
     412             :                        Node* function, Node* arg0);
     413             : 
     414             :   // Call to a C function with two arguments.
     415             :   Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
     416             :                        MachineType arg1_type, Node* function, Node* arg0,
     417             :                        Node* arg1);
     418             : 
     419             :   // Call to a C function with three arguments.
     420             :   Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
     421             :                        MachineType arg1_type, MachineType arg2_type,
     422             :                        Node* function, Node* arg0, Node* arg1, Node* arg2);
     423             : 
     424             :   // Call to a C function with six arguments.
     425             :   Node* CallCFunction6(MachineType return_type, MachineType arg0_type,
     426             :                        MachineType arg1_type, MachineType arg2_type,
     427             :                        MachineType arg3_type, MachineType arg4_type,
     428             :                        MachineType arg5_type, Node* function, Node* arg0,
     429             :                        Node* arg1, Node* arg2, Node* arg3, Node* arg4,
     430             :                        Node* arg5);
     431             : 
     432             :   // Call to a C function with nine arguments.
     433             :   Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
     434             :                        MachineType arg1_type, MachineType arg2_type,
     435             :                        MachineType arg3_type, MachineType arg4_type,
     436             :                        MachineType arg5_type, MachineType arg6_type,
     437             :                        MachineType arg7_type, MachineType arg8_type,
     438             :                        Node* function, Node* arg0, Node* arg1, Node* arg2,
     439             :                        Node* arg3, Node* arg4, Node* arg5, Node* arg6,
     440             :                        Node* arg7, Node* arg8);
     441             : 
     442             :   // Exception handling support.
     443             :   void GotoIfException(Node* node, Label* if_exception,
     444             :                        Variable* exception_var = nullptr);
     445             : 
     446             :   // Helpers which delegate to RawMachineAssembler.
     447             :   Factory* factory() const;
     448             :   Isolate* isolate() const;
     449             :   Zone* zone() const;
     450             : 
     451     2337654 :   CodeAssemblerState* state() { return state_; }
     452             : 
     453             :   void BreakOnNode(int node_id);
     454             : 
     455             :   bool UnalignedLoadSupported(const MachineType& machineType,
     456             :                               uint8_t alignment) const;
     457             :   bool UnalignedStoreSupported(const MachineType& machineType,
     458             :                                uint8_t alignment) const;
     459             : 
     460             :  protected:
     461             :   void RegisterCallGenerationCallbacks(
     462             :       const CodeAssemblerCallback& call_prologue,
     463             :       const CodeAssemblerCallback& call_epilogue);
     464             :   void UnregisterCallGenerationCallbacks();
     465             : 
     466             :  private:
     467             :   RawMachineAssembler* raw_assembler() const;
     468             : 
     469             :   // Calls respective callback registered in the state.
     470             :   void CallPrologue();
     471             :   void CallEpilogue();
     472             : 
     473             :   CodeAssemblerState* state_;
     474             : 
     475             :   DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
     476             : };
     477             : 
     478             : class CodeAssemblerVariable {
     479             :  public:
     480             :   explicit CodeAssemblerVariable(CodeAssembler* assembler,
     481             :                                  MachineRepresentation rep);
     482             :   CodeAssemblerVariable(CodeAssembler* assembler, MachineRepresentation rep,
     483             :                         Node* initial_value);
     484             : #if DEBUG
     485             :   CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
     486             :                         MachineRepresentation rep);
     487             :   CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info,
     488             :                         MachineRepresentation rep, Node* initial_value);
     489             : #endif  // DEBUG
     490             : 
     491             :   ~CodeAssemblerVariable();
     492             :   void Bind(Node* value);
     493             :   Node* value() const;
     494             :   MachineRepresentation rep() const;
     495             :   bool IsBound() const;
     496             : 
     497             :  private:
     498             :   class Impl;
     499             :   friend class CodeAssemblerLabel;
     500             :   friend class CodeAssemblerState;
     501             :   friend std::ostream& operator<<(std::ostream&, const Impl&);
     502             :   friend std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
     503             :   Impl* impl_;
     504             :   CodeAssemblerState* state_;
     505             : };
     506             : 
     507             : std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
     508             : std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable::Impl&);
     509             : 
     510        8256 : class CodeAssemblerLabel {
     511             :  public:
     512             :   enum Type { kDeferred, kNonDeferred };
     513             : 
     514             :   explicit CodeAssemblerLabel(
     515             :       CodeAssembler* assembler,
     516             :       CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
     517     1038274 :       : CodeAssemblerLabel(assembler, 0, nullptr, type) {}
     518             :   CodeAssemblerLabel(
     519             :       CodeAssembler* assembler,
     520             :       const CodeAssemblerVariableList& merged_variables,
     521             :       CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
     522             :       : CodeAssemblerLabel(assembler, merged_variables.length(),
     523       21403 :                            &(merged_variables[0]), type) {}
     524             :   CodeAssemblerLabel(
     525             :       CodeAssembler* assembler, size_t count,
     526             :       CodeAssemblerVariable* const* vars,
     527             :       CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred);
     528             :   CodeAssemblerLabel(
     529             :       CodeAssembler* assembler,
     530             :       std::initializer_list<CodeAssemblerVariable*> vars,
     531             :       CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
     532        2107 :       : CodeAssemblerLabel(assembler, vars.size(), vars.begin(), type) {}
     533             :   CodeAssemblerLabel(
     534             :       CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
     535             :       CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
     536      135826 :       : CodeAssemblerLabel(assembler, 1, &merged_variable, type) {}
     537             :   ~CodeAssemblerLabel();
     538             : 
     539             :   inline bool is_bound() const { return bound_; }
     540             : 
     541             :  private:
     542             :   friend class CodeAssembler;
     543             : 
     544             :   void Bind();
     545             : #if DEBUG
     546             :   void Bind(AssemblerDebugInfo debug_info);
     547             : #endif  // DEBUG
     548             :   void UpdateVariablesAfterBind();
     549             :   void MergeVariables();
     550             : 
     551             :   bool bound_;
     552             :   size_t merge_count_;
     553             :   CodeAssemblerState* state_;
     554             :   RawMachineLabel* label_;
     555             :   // Map of variables that need to be merged to their phi nodes (or placeholders
     556             :   // for those phis).
     557             :   std::map<CodeAssemblerVariable::Impl*, Node*> variable_phis_;
     558             :   // Map of variables to the list of value nodes that have been added from each
     559             :   // merge path in their order of merging.
     560             :   std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>> variable_merges_;
     561             : };
     562             : 
     563             : class V8_EXPORT_PRIVATE CodeAssemblerState {
     564             :  public:
     565             :   // Create with CallStub linkage.
     566             :   // |result_size| specifies the number of results returned by the stub.
     567             :   // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
     568             :   CodeAssemblerState(Isolate* isolate, Zone* zone,
     569             :                      const CallInterfaceDescriptor& descriptor,
     570             :                      Code::Flags flags, const char* name,
     571             :                      size_t result_size = 1);
     572             : 
     573             :   // Create with JSCall linkage.
     574             :   CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count,
     575             :                      Code::Flags flags, const char* name);
     576             : 
     577             :   ~CodeAssemblerState();
     578             : 
     579             :   const char* name() const { return name_; }
     580             :   int parameter_count() const;
     581             : 
     582             : #if DEBUG
     583             :   void PrintCurrentBlock(std::ostream& os);
     584             : #endif  // DEBUG
     585             :   void SetInitialDebugInformation(const char* msg, const char* file, int line);
     586             : 
     587             :  private:
     588             :   friend class CodeAssembler;
     589             :   friend class CodeAssemblerLabel;
     590             :   friend class CodeAssemblerVariable;
     591             : 
     592             :   CodeAssemblerState(Isolate* isolate, Zone* zone,
     593             :                      CallDescriptor* call_descriptor, Code::Flags flags,
     594             :                      const char* name);
     595             : 
     596             :   std::unique_ptr<RawMachineAssembler> raw_assembler_;
     597             :   Code::Flags flags_;
     598             :   const char* name_;
     599             :   bool code_generated_;
     600             :   ZoneSet<CodeAssemblerVariable::Impl*> variables_;
     601             :   CodeAssemblerCallback call_prologue_;
     602             :   CodeAssemblerCallback call_epilogue_;
     603             : 
     604             :   DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);
     605             : };
     606             : 
     607             : }  // namespace compiler
     608             : }  // namespace internal
     609             : }  // namespace v8
     610             : 
     611             : #endif  // V8_COMPILER_CODE_ASSEMBLER_H_

Generated by: LCOV version 1.10