Home | History | Annotate | Download | only in compiler
      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/globals.h"
     16 #include "src/heap/heap.h"
     17 #include "src/machine-type.h"
     18 #include "src/runtime/runtime.h"
     19 #include "src/zone/zone-containers.h"
     20 
     21 namespace v8 {
     22 namespace internal {
     23 
     24 class Callable;
     25 class CallInterfaceDescriptor;
     26 class Isolate;
     27 class Factory;
     28 class Zone;
     29 
     30 namespace compiler {
     31 
     32 class CallDescriptor;
     33 class Node;
     34 class RawMachineAssembler;
     35 class RawMachineLabel;
     36 
     37 #define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
     38   V(Float32Equal)                                \
     39   V(Float32LessThan)                             \
     40   V(Float32LessThanOrEqual)                      \
     41   V(Float32GreaterThan)                          \
     42   V(Float32GreaterThanOrEqual)                   \
     43   V(Float64Equal)                                \
     44   V(Float64LessThan)                             \
     45   V(Float64LessThanOrEqual)                      \
     46   V(Float64GreaterThan)                          \
     47   V(Float64GreaterThanOrEqual)                   \
     48   V(Int32GreaterThan)                            \
     49   V(Int32GreaterThanOrEqual)                     \
     50   V(Int32LessThan)                               \
     51   V(Int32LessThanOrEqual)                        \
     52   V(IntPtrLessThan)                              \
     53   V(IntPtrLessThanOrEqual)                       \
     54   V(IntPtrGreaterThan)                           \
     55   V(IntPtrGreaterThanOrEqual)                    \
     56   V(IntPtrEqual)                                 \
     57   V(Uint32LessThan)                              \
     58   V(Uint32LessThanOrEqual)                       \
     59   V(Uint32GreaterThanOrEqual)                    \
     60   V(UintPtrLessThan)                             \
     61   V(UintPtrLessThanOrEqual)                      \
     62   V(UintPtrGreaterThan)                          \
     63   V(UintPtrGreaterThanOrEqual)                   \
     64   V(WordEqual)                                   \
     65   V(WordNotEqual)                                \
     66   V(Word32Equal)                                 \
     67   V(Word32NotEqual)                              \
     68   V(Word64Equal)                                 \
     69   V(Word64NotEqual)
     70 
     71 #define CODE_ASSEMBLER_BINARY_OP_LIST(V)   \
     72   CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
     73   V(Float64Add)                            \
     74   V(Float64Sub)                            \
     75   V(Float64Mul)                            \
     76   V(Float64Div)                            \
     77   V(Float64Mod)                            \
     78   V(Float64Atan2)                          \
     79   V(Float64Pow)                            \
     80   V(Float64InsertLowWord32)                \
     81   V(Float64InsertHighWord32)               \
     82   V(IntPtrAdd)                             \
     83   V(IntPtrAddWithOverflow)                 \
     84   V(IntPtrSub)                             \
     85   V(IntPtrSubWithOverflow)                 \
     86   V(IntPtrMul)                             \
     87   V(Int32Add)                              \
     88   V(Int32AddWithOverflow)                  \
     89   V(Int32Sub)                              \
     90   V(Int32Mul)                              \
     91   V(Int32MulWithOverflow)                  \
     92   V(Int32Div)                              \
     93   V(Int32Mod)                              \
     94   V(WordOr)                                \
     95   V(WordAnd)                               \
     96   V(WordXor)                               \
     97   V(WordShl)                               \
     98   V(WordShr)                               \
     99   V(WordSar)                               \
    100   V(WordRor)                               \
    101   V(Word32Or)                              \
    102   V(Word32And)                             \
    103   V(Word32Xor)                             \
    104   V(Word32Shl)                             \
    105   V(Word32Shr)                             \
    106   V(Word32Sar)                             \
    107   V(Word32Ror)                             \
    108   V(Word64Or)                              \
    109   V(Word64And)                             \
    110   V(Word64Xor)                             \
    111   V(Word64Shr)                             \
    112   V(Word64Sar)                             \
    113   V(Word64Ror)
    114 
    115 #define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
    116   V(Float64Abs)                         \
    117   V(Float64Acos)                        \
    118   V(Float64Acosh)                       \
    119   V(Float64Asin)                        \
    120   V(Float64Asinh)                       \
    121   V(Float64Atan)                        \
    122   V(Float64Atanh)                       \
    123   V(Float64Cos)                         \
    124   V(Float64Cosh)                        \
    125   V(Float64Exp)                         \
    126   V(Float64Expm1)                       \
    127   V(Float64Log)                         \
    128   V(Float64Log1p)                       \
    129   V(Float64Log2)                        \
    130   V(Float64Log10)                       \
    131   V(Float64Cbrt)                        \
    132   V(Float64Neg)                         \
    133   V(Float64Sin)                         \
    134   V(Float64Sinh)                        \
    135   V(Float64Sqrt)                        \
    136   V(Float64Tan)                         \
    137   V(Float64Tanh)                        \
    138   V(Float64ExtractLowWord32)            \
    139   V(Float64ExtractHighWord32)           \
    140   V(BitcastTaggedToWord)                \
    141   V(BitcastWordToTagged)                \
    142   V(BitcastWordToTaggedSigned)          \
    143   V(TruncateFloat64ToFloat32)           \
    144   V(TruncateFloat64ToWord32)            \
    145   V(TruncateInt64ToInt32)               \
    146   V(ChangeFloat32ToFloat64)             \
    147   V(ChangeFloat64ToUint32)              \
    148   V(ChangeInt32ToFloat64)               \
    149   V(ChangeInt32ToInt64)                 \
    150   V(ChangeUint32ToFloat64)              \
    151   V(ChangeUint32ToUint64)               \
    152   V(RoundFloat64ToInt32)                \
    153   V(RoundInt32ToFloat32)                \
    154   V(Float64SilenceNaN)                  \
    155   V(Float64RoundDown)                   \
    156   V(Float64RoundUp)                     \
    157   V(Float64RoundTiesEven)               \
    158   V(Float64RoundTruncate)               \
    159   V(Word32Clz)                          \
    160   V(Word32BinaryNot)
    161 
    162 // A "public" interface used by components outside of compiler directory to
    163 // create code objects with TurboFan's backend. This class is mostly a thin shim
    164 // around the RawMachineAssembler, and its primary job is to ensure that the
    165 // innards of the RawMachineAssembler and other compiler implementation details
    166 // don't leak outside of the the compiler directory..
    167 //
    168 // V8 components that need to generate low-level code using this interface
    169 // should include this header--and this header only--from the compiler directory
    170 // (this is actually enforced). Since all interesting data structures are
    171 // forward declared, it's not possible for clients to peek inside the compiler
    172 // internals.
    173 //
    174 // In addition to providing isolation between TurboFan and code generation
    175 // clients, CodeAssembler also provides an abstraction for creating variables
    176 // and enhanced Label functionality to merge variable values along paths where
    177 // they have differing values, including loops.
    178 class V8_EXPORT_PRIVATE CodeAssembler {
    179  public:
    180   // Create with CallStub linkage.
    181   // |result_size| specifies the number of results returned by the stub.
    182   // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
    183   CodeAssembler(Isolate* isolate, Zone* zone,
    184                 const CallInterfaceDescriptor& descriptor, Code::Flags flags,
    185                 const char* name, size_t result_size = 1);
    186 
    187   // Create with JSCall linkage.
    188   CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count,
    189                 Code::Flags flags, const char* name);
    190 
    191   virtual ~CodeAssembler();
    192 
    193   Handle<Code> GenerateCode();
    194 
    195   bool Is64() const;
    196   bool IsFloat64RoundUpSupported() const;
    197   bool IsFloat64RoundDownSupported() const;
    198   bool IsFloat64RoundTiesEvenSupported() const;
    199   bool IsFloat64RoundTruncateSupported() const;
    200 
    201   class Label;
    202   class Variable {
    203    public:
    204     explicit Variable(CodeAssembler* assembler, MachineRepresentation rep);
    205     ~Variable();
    206     void Bind(Node* value);
    207     Node* value() const;
    208     MachineRepresentation rep() const;
    209     bool IsBound() const;
    210 
    211    private:
    212     friend class CodeAssembler;
    213     class Impl;
    214     Impl* impl_;
    215     CodeAssembler* assembler_;
    216   };
    217 
    218   typedef ZoneList<Variable*> VariableList;
    219 
    220   // ===========================================================================
    221   // Base Assembler
    222   // ===========================================================================
    223 
    224   // Constants.
    225   Node* Int32Constant(int32_t value);
    226   Node* Int64Constant(int64_t value);
    227   Node* IntPtrConstant(intptr_t value);
    228   Node* NumberConstant(double value);
    229   Node* SmiConstant(Smi* value);
    230   Node* SmiConstant(int value);
    231   Node* HeapConstant(Handle<HeapObject> object);
    232   Node* BooleanConstant(bool value);
    233   Node* ExternalConstant(ExternalReference address);
    234   Node* Float64Constant(double value);
    235   Node* NaNConstant();
    236 
    237   bool ToInt32Constant(Node* node, int32_t& out_value);
    238   bool ToInt64Constant(Node* node, int64_t& out_value);
    239   bool ToSmiConstant(Node* node, Smi*& out_value);
    240   bool ToIntPtrConstant(Node* node, intptr_t& out_value);
    241 
    242   Node* Parameter(int value);
    243   void Return(Node* value);
    244   void PopAndReturn(Node* pop, Node* value);
    245 
    246   void DebugBreak();
    247   void Comment(const char* format, ...);
    248 
    249   void Bind(Label* label);
    250   void Goto(Label* label);
    251   void GotoIf(Node* condition, Label* true_label);
    252   void GotoUnless(Node* condition, Label* false_label);
    253   void Branch(Node* condition, Label* true_label, Label* false_label);
    254 
    255   void Switch(Node* index, Label* default_label, const int32_t* case_values,
    256               Label** case_labels, size_t case_count);
    257 
    258   Node* Select(Node* condition, Node* true_value, Node* false_value,
    259                MachineRepresentation rep = MachineRepresentation::kTagged);
    260 
    261   // Access to the frame pointer
    262   Node* LoadFramePointer();
    263   Node* LoadParentFramePointer();
    264 
    265   // Access to the stack pointer
    266   Node* LoadStackPointer();
    267 
    268   // Load raw memory location.
    269   Node* Load(MachineType rep, Node* base);
    270   Node* Load(MachineType rep, Node* base, Node* index);
    271   Node* AtomicLoad(MachineType rep, Node* base, Node* index);
    272 
    273   // Load a value from the root array.
    274   Node* LoadRoot(Heap::RootListIndex root_index);
    275 
    276   // Store value to raw memory location.
    277   Node* Store(MachineRepresentation rep, Node* base, Node* value);
    278   Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
    279   Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
    280   Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
    281                             Node* value);
    282   Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index,
    283                     Node* value);
    284 
    285   // Store a value to the root array.
    286   Node* StoreRoot(Heap::RootListIndex root_index, Node* value);
    287 
    288 // Basic arithmetic operations.
    289 #define DECLARE_CODE_ASSEMBLER_BINARY_OP(name) Node* name(Node* a, Node* b);
    290   CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
    291 #undef DECLARE_CODE_ASSEMBLER_BINARY_OP
    292 
    293   Node* WordShl(Node* value, int shift);
    294   Node* WordShr(Node* value, int shift);
    295   Node* Word32Shr(Node* value, int shift);
    296 
    297 // Unary
    298 #define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
    299   CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
    300 #undef DECLARE_CODE_ASSEMBLER_UNARY_OP
    301 
    302   // Changes an intptr_t to a double, e.g. for storing an element index
    303   // outside Smi range in a HeapNumber. Lossless on 32-bit,
    304   // rounds on 64-bit (which doesn't affect valid element indices).
    305   Node* RoundIntPtrToFloat64(Node* value);
    306   // No-op on 32-bit, otherwise zero extend.
    307   Node* ChangeUint32ToWord(Node* value);
    308   // No-op on 32-bit, otherwise sign extend.
    309   Node* ChangeInt32ToIntPtr(Node* value);
    310 
    311   // No-op that guarantees that the value is kept alive till this point even
    312   // if GC happens.
    313   Node* Retain(Node* value);
    314 
    315   // Projections
    316   Node* Projection(int index, Node* value);
    317 
    318   // Calls
    319   Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
    320   Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
    321   Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
    322                     Node* arg2);
    323   Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
    324                     Node* arg2, Node* arg3);
    325   Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
    326                     Node* arg2, Node* arg3, Node* arg4);
    327   Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
    328                     Node* arg2, Node* arg3, Node* arg4, Node* arg5);
    329 
    330   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context);
    331   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    332                         Node* arg1);
    333   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    334                         Node* arg1, Node* arg2);
    335   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    336                         Node* arg1, Node* arg2, Node* arg3);
    337   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    338                         Node* arg1, Node* arg2, Node* arg3, Node* arg4);
    339   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    340                         Node* arg1, Node* arg2, Node* arg3, Node* arg4,
    341                         Node* arg5);
    342   Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
    343                         Node* arg1, Node* arg2, Node* arg3, Node* arg4,
    344                         Node* arg5, Node* arg6);
    345 
    346   // A pair of a zero-based argument index and a value.
    347   // It helps writing arguments order independent code.
    348   struct Arg {
    349     Arg(int index, Node* value) : index(index), value(value) {}
    350 
    351     int const index;
    352     Node* const value;
    353   };
    354 
    355   Node* CallStub(Callable const& callable, Node* context, Node* arg1,
    356                  size_t result_size = 1);
    357   Node* CallStub(Callable const& callable, Node* context, Node* arg1,
    358                  Node* arg2, size_t result_size = 1);
    359   Node* CallStub(Callable const& callable, Node* context, Node* arg1,
    360                  Node* arg2, Node* arg3, size_t result_size = 1);
    361   Node* CallStub(Callable const& callable, Node* context, Node* arg1,
    362                  Node* arg2, Node* arg3, Node* arg4, size_t result_size = 1);
    363   Node* CallStubN(Callable const& callable, Node** args,
    364                   size_t result_size = 1);
    365 
    366   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    367                  Node* context, size_t result_size = 1);
    368   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    369                  Node* context, Node* arg1, size_t result_size = 1);
    370   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    371                  Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
    372   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    373                  Node* context, Node* arg1, Node* arg2, Node* arg3,
    374                  size_t result_size = 1);
    375   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    376                  Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
    377                  size_t result_size = 1);
    378   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    379                  Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
    380                  Node* arg5, size_t result_size = 1);
    381 
    382   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    383                  Node* context, const Arg& arg1, const Arg& arg2,
    384                  size_t result_size = 1);
    385   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    386                  Node* context, const Arg& arg1, const Arg& arg2,
    387                  const Arg& arg3, size_t result_size = 1);
    388   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    389                  Node* context, const Arg& arg1, const Arg& arg2,
    390                  const Arg& arg3, const Arg& arg4, size_t result_size = 1);
    391   Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    392                  Node* context, const Arg& arg1, const Arg& arg2,
    393                  const Arg& arg3, const Arg& arg4, const Arg& arg5,
    394                  size_t result_size = 1);
    395 
    396   Node* CallStubN(const CallInterfaceDescriptor& descriptor,
    397                   int js_parameter_count, Node* target, Node** args,
    398                   size_t result_size = 1);
    399   Node* CallStubN(const CallInterfaceDescriptor& descriptor, Node* target,
    400                   Node** args, size_t result_size = 1) {
    401     return CallStubN(descriptor, 0, target, args, result_size);
    402   }
    403 
    404   Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
    405                      size_t result_size = 1);
    406   Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
    407                      Node* arg2, size_t result_size = 1);
    408   Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
    409                      Node* arg2, Node* arg3, size_t result_size = 1);
    410   Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
    411                      Node* arg2, Node* arg3, Node* arg4,
    412                      size_t result_size = 1);
    413   Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
    414                      Node* arg2, Node* arg3, Node* arg4, Node* arg5,
    415                      size_t result_size = 1);
    416 
    417   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    418                      Node* context, Node* arg1, size_t result_size = 1);
    419   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    420                      Node* context, Node* arg1, Node* arg2,
    421                      size_t result_size = 1);
    422   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    423                      Node* context, Node* arg1, Node* arg2, Node* arg3,
    424                      size_t result_size = 1);
    425   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    426                      Node* context, Node* arg1, Node* arg2, Node* arg3,
    427                      Node* arg4, size_t result_size = 1);
    428   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    429                      Node* context, Node* arg1, Node* arg2, Node* arg3,
    430                      Node* arg4, Node* arg5, size_t result_size = 1);
    431   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    432                      Node* context, Node* arg1, Node* arg2, Node* arg3,
    433                      Node* arg4, Node* arg5, Node* arg6,
    434                      size_t result_size = 1);
    435 
    436   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    437                      Node* context, const Arg& arg1, const Arg& arg2,
    438                      const Arg& arg3, const Arg& arg4, size_t result_size = 1);
    439   Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
    440                      Node* context, const Arg& arg1, const Arg& arg2,
    441                      const Arg& arg3, const Arg& arg4, const Arg& arg5,
    442                      size_t result_size = 1);
    443 
    444   Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
    445                                  Node* code_target_address, Node** args);
    446 
    447   Node* CallJS(Callable const& callable, Node* context, Node* function,
    448                Node* receiver, size_t result_size = 1);
    449   Node* CallJS(Callable const& callable, Node* context, Node* function,
    450                Node* receiver, Node* arg1, size_t result_size = 1);
    451   Node* CallJS(Callable const& callable, Node* context, Node* function,
    452                Node* receiver, Node* arg1, Node* arg2, size_t result_size = 1);
    453   Node* CallJS(Callable const& callable, Node* context, Node* function,
    454                Node* receiver, Node* arg1, Node* arg2, Node* arg3,
    455                size_t result_size = 1);
    456 
    457   // Call to a C function with two arguments.
    458   Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
    459                        MachineType arg1_type, Node* function, Node* arg0,
    460                        Node* arg1);
    461 
    462   // Exception handling support.
    463   void GotoIfException(Node* node, Label* if_exception,
    464                        Variable* exception_var = nullptr);
    465 
    466   // Helpers which delegate to RawMachineAssembler.
    467   Factory* factory() const;
    468   Isolate* isolate() const;
    469   Zone* zone() const;
    470 
    471  protected:
    472   // Enables subclasses to perform operations before and after a call.
    473   virtual void CallPrologue();
    474   virtual void CallEpilogue();
    475 
    476  private:
    477   CodeAssembler(Isolate* isolate, Zone* zone, CallDescriptor* call_descriptor,
    478                 Code::Flags flags, const char* name);
    479 
    480   Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
    481   Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
    482 
    483   std::unique_ptr<RawMachineAssembler> raw_assembler_;
    484   Code::Flags flags_;
    485   const char* name_;
    486   bool code_generated_;
    487   ZoneSet<Variable::Impl*> variables_;
    488 
    489   DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
    490 };
    491 
    492 class CodeAssembler::Label {
    493  public:
    494   enum Type { kDeferred, kNonDeferred };
    495 
    496   explicit Label(
    497       CodeAssembler* assembler,
    498       CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
    499       : CodeAssembler::Label(assembler, 0, nullptr, type) {}
    500   Label(CodeAssembler* assembler, const VariableList& merged_variables,
    501         CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
    502       : CodeAssembler::Label(assembler, merged_variables.length(),
    503                              &(merged_variables[0]), type) {}
    504   Label(CodeAssembler* assembler, size_t count, Variable** vars,
    505         CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred);
    506   Label(CodeAssembler* assembler, CodeAssembler::Variable* merged_variable,
    507         CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
    508       : Label(assembler, 1, &merged_variable, type) {}
    509   ~Label() {}
    510 
    511  private:
    512   friend class CodeAssembler;
    513 
    514   void Bind();
    515   void MergeVariables();
    516 
    517   bool bound_;
    518   size_t merge_count_;
    519   CodeAssembler* assembler_;
    520   RawMachineLabel* label_;
    521   // Map of variables that need to be merged to their phi nodes (or placeholders
    522   // for those phis).
    523   std::map<Variable::Impl*, Node*> variable_phis_;
    524   // Map of variables to the list of value nodes that have been added from each
    525   // merge path in their order of merging.
    526   std::map<Variable::Impl*, std::vector<Node*>> variable_merges_;
    527 };
    528 
    529 }  // namespace compiler
    530 }  // namespace internal
    531 }  // namespace v8
    532 
    533 #endif  // V8_COMPILER_CODE_ASSEMBLER_H_
    534