Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 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 #include "src/compiler/raw-machine-assembler.h"
      6 
      7 #include "src/code-factory.h"
      8 #include "src/compiler/node-properties.h"
      9 #include "src/compiler/pipeline.h"
     10 #include "src/compiler/scheduler.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 namespace compiler {
     15 
     16 RawMachineAssembler::RawMachineAssembler(
     17     Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
     18     MachineRepresentation word, MachineOperatorBuilder::Flags flags,
     19     MachineOperatorBuilder::AlignmentRequirements alignment_requirements)
     20     : isolate_(isolate),
     21       graph_(graph),
     22       schedule_(new (zone()) Schedule(zone())),
     23       machine_(zone(), word, flags, alignment_requirements),
     24       common_(zone()),
     25       call_descriptor_(call_descriptor),
     26       parameters_(parameter_count(), zone()),
     27       current_block_(schedule()->start()) {
     28   int param_count = static_cast<int>(parameter_count());
     29   // Add an extra input for the JSFunction parameter to the start node.
     30   graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
     31   for (size_t i = 0; i < parameter_count(); ++i) {
     32     parameters_[i] =
     33         AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
     34   }
     35   graph->SetEnd(graph->NewNode(common_.End(0)));
     36 }
     37 
     38 Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
     39                                                      RelocInfo::Mode rmode) {
     40   return kPointerSize == 8
     41              ? RelocatableInt64Constant(value, rmode)
     42              : RelocatableInt32Constant(static_cast<int>(value), rmode);
     43 }
     44 
     45 Schedule* RawMachineAssembler::Export() {
     46   // Compute the correct codegen order.
     47   DCHECK(schedule_->rpo_order()->empty());
     48   OFStream os(stdout);
     49   if (FLAG_trace_turbo_scheduler) {
     50     PrintF("--- RAW SCHEDULE -------------------------------------------\n");
     51     os << *schedule_;
     52   }
     53   schedule_->EnsureCFGWellFormedness();
     54   schedule_->PropagateDeferredMark();
     55   if (FLAG_trace_turbo_scheduler) {
     56     PrintF("--- EDGE SPLIT AND PROPAGATED DEFERRED SCHEDULE ------------\n");
     57     os << *schedule_;
     58   }
     59   Scheduler::ComputeSpecialRPO(zone(), schedule_);
     60   // Invalidate RawMachineAssembler.
     61   Schedule* schedule = schedule_;
     62   schedule_ = nullptr;
     63   return schedule;
     64 }
     65 
     66 
     67 Node* RawMachineAssembler::Parameter(size_t index) {
     68   DCHECK(index < parameter_count());
     69   return parameters_[index];
     70 }
     71 
     72 
     73 void RawMachineAssembler::Goto(RawMachineLabel* label) {
     74   DCHECK(current_block_ != schedule()->end());
     75   schedule()->AddGoto(CurrentBlock(), Use(label));
     76   current_block_ = nullptr;
     77 }
     78 
     79 
     80 void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
     81                                  RawMachineLabel* false_val) {
     82   DCHECK(current_block_ != schedule()->end());
     83   Node* branch = MakeNode(common()->Branch(), 1, &condition);
     84   schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val));
     85   current_block_ = nullptr;
     86 }
     87 
     88 void RawMachineAssembler::Continuations(Node* call, RawMachineLabel* if_success,
     89                                         RawMachineLabel* if_exception) {
     90   DCHECK_NOT_NULL(schedule_);
     91   DCHECK_NOT_NULL(current_block_);
     92   schedule()->AddCall(CurrentBlock(), call, Use(if_success), Use(if_exception));
     93   current_block_ = nullptr;
     94 }
     95 
     96 void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
     97                                  const int32_t* case_values,
     98                                  RawMachineLabel** case_labels,
     99                                  size_t case_count) {
    100   DCHECK_NE(schedule()->end(), current_block_);
    101   size_t succ_count = case_count + 1;
    102   Node* switch_node = AddNode(common()->Switch(succ_count), index);
    103   BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
    104   for (size_t index = 0; index < case_count; ++index) {
    105     int32_t case_value = case_values[index];
    106     BasicBlock* case_block = schedule()->NewBasicBlock();
    107     Node* case_node =
    108         graph()->NewNode(common()->IfValue(case_value), switch_node);
    109     schedule()->AddNode(case_block, case_node);
    110     schedule()->AddGoto(case_block, Use(case_labels[index]));
    111     succ_blocks[index] = case_block;
    112   }
    113   BasicBlock* default_block = schedule()->NewBasicBlock();
    114   Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
    115   schedule()->AddNode(default_block, default_node);
    116   schedule()->AddGoto(default_block, Use(default_label));
    117   succ_blocks[case_count] = default_block;
    118   schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
    119   current_block_ = nullptr;
    120 }
    121 
    122 void RawMachineAssembler::Return(Node* value) {
    123   Node* values[] = {Int32Constant(0), value};
    124   Node* ret = MakeNode(common()->Return(1), 2, values);
    125   schedule()->AddReturn(CurrentBlock(), ret);
    126   current_block_ = nullptr;
    127 }
    128 
    129 
    130 void RawMachineAssembler::Return(Node* v1, Node* v2) {
    131   Node* values[] = {Int32Constant(0), v1, v2};
    132   Node* ret = MakeNode(common()->Return(2), 3, values);
    133   schedule()->AddReturn(CurrentBlock(), ret);
    134   current_block_ = nullptr;
    135 }
    136 
    137 
    138 void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
    139   Node* values[] = {Int32Constant(0), v1, v2, v3};
    140   Node* ret = MakeNode(common()->Return(3), 4, values);
    141   schedule()->AddReturn(CurrentBlock(), ret);
    142   current_block_ = nullptr;
    143 }
    144 
    145 void RawMachineAssembler::PopAndReturn(Node* pop, Node* value) {
    146   Node* values[] = {pop, value};
    147   Node* ret = MakeNode(common()->Return(1), 2, values);
    148   schedule()->AddReturn(CurrentBlock(), ret);
    149   current_block_ = nullptr;
    150 }
    151 
    152 void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2) {
    153   Node* values[] = {pop, v1, v2};
    154   Node* ret = MakeNode(common()->Return(2), 3, values);
    155   schedule()->AddReturn(CurrentBlock(), ret);
    156   current_block_ = nullptr;
    157 }
    158 
    159 void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
    160                                        Node* v3) {
    161   Node* values[] = {pop, v1, v2, v3};
    162   Node* ret = MakeNode(common()->Return(3), 4, values);
    163   schedule()->AddReturn(CurrentBlock(), ret);
    164   current_block_ = nullptr;
    165 }
    166 
    167 void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
    168 
    169 void RawMachineAssembler::Comment(const char* msg) {
    170   AddNode(machine()->Comment(msg));
    171 }
    172 
    173 Node* RawMachineAssembler::CallN(CallDescriptor* desc, Node* function,
    174                                  Node** args) {
    175   int param_count = static_cast<int>(desc->ParameterCount());
    176   int input_count = param_count + 1;
    177   Node** buffer = zone()->NewArray<Node*>(input_count);
    178   int index = 0;
    179   buffer[index++] = function;
    180   for (int i = 0; i < param_count; i++) {
    181     buffer[index++] = args[i];
    182   }
    183   return AddNode(common()->Call(desc), input_count, buffer);
    184 }
    185 
    186 
    187 Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* desc,
    188                                                Node* function, Node** args,
    189                                                Node* frame_state) {
    190   DCHECK(desc->NeedsFrameState());
    191   int param_count = static_cast<int>(desc->ParameterCount());
    192   int input_count = param_count + 2;
    193   Node** buffer = zone()->NewArray<Node*>(input_count);
    194   int index = 0;
    195   buffer[index++] = function;
    196   for (int i = 0; i < param_count; i++) {
    197     buffer[index++] = args[i];
    198   }
    199   buffer[index++] = frame_state;
    200   return AddNode(common()->Call(desc), input_count, buffer);
    201 }
    202 
    203 Node* RawMachineAssembler::CallRuntime0(Runtime::FunctionId function,
    204                                         Node* context) {
    205   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    206       zone(), function, 0, Operator::kNoProperties, CallDescriptor::kNoFlags);
    207   int return_count = static_cast<int>(descriptor->ReturnCount());
    208 
    209   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    210   Node* ref = AddNode(
    211       common()->ExternalConstant(ExternalReference(function, isolate())));
    212   Node* arity = Int32Constant(0);
    213 
    214   return AddNode(common()->Call(descriptor), centry, ref, arity, context);
    215 }
    216 
    217 Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function,
    218                                         Node* arg1, Node* context) {
    219   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    220       zone(), function, 1, Operator::kNoProperties, CallDescriptor::kNoFlags);
    221   int return_count = static_cast<int>(descriptor->ReturnCount());
    222 
    223   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    224   Node* ref = AddNode(
    225       common()->ExternalConstant(ExternalReference(function, isolate())));
    226   Node* arity = Int32Constant(1);
    227 
    228   return AddNode(common()->Call(descriptor), centry, arg1, ref, arity, context);
    229 }
    230 
    231 
    232 Node* RawMachineAssembler::CallRuntime2(Runtime::FunctionId function,
    233                                         Node* arg1, Node* arg2, Node* context) {
    234   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    235       zone(), function, 2, Operator::kNoProperties, CallDescriptor::kNoFlags);
    236   int return_count = static_cast<int>(descriptor->ReturnCount());
    237 
    238   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    239   Node* ref = AddNode(
    240       common()->ExternalConstant(ExternalReference(function, isolate())));
    241   Node* arity = Int32Constant(2);
    242 
    243   return AddNode(common()->Call(descriptor), centry, arg1, arg2, ref, arity,
    244                  context);
    245 }
    246 
    247 Node* RawMachineAssembler::CallRuntime3(Runtime::FunctionId function,
    248                                         Node* arg1, Node* arg2, Node* arg3,
    249                                         Node* context) {
    250   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    251       zone(), function, 3, Operator::kNoProperties, CallDescriptor::kNoFlags);
    252   int return_count = static_cast<int>(descriptor->ReturnCount());
    253 
    254   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    255   Node* ref = AddNode(
    256       common()->ExternalConstant(ExternalReference(function, isolate())));
    257   Node* arity = Int32Constant(3);
    258 
    259   return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, ref,
    260                  arity, context);
    261 }
    262 
    263 Node* RawMachineAssembler::CallRuntime4(Runtime::FunctionId function,
    264                                         Node* arg1, Node* arg2, Node* arg3,
    265                                         Node* arg4, Node* context) {
    266   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    267       zone(), function, 4, Operator::kNoProperties, CallDescriptor::kNoFlags);
    268   int return_count = static_cast<int>(descriptor->ReturnCount());
    269 
    270   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    271   Node* ref = AddNode(
    272       common()->ExternalConstant(ExternalReference(function, isolate())));
    273   Node* arity = Int32Constant(4);
    274 
    275   return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, arg4,
    276                  ref, arity, context);
    277 }
    278 
    279 Node* RawMachineAssembler::CallRuntime5(Runtime::FunctionId function,
    280                                         Node* arg1, Node* arg2, Node* arg3,
    281                                         Node* arg4, Node* arg5, Node* context) {
    282   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
    283       zone(), function, 5, Operator::kNoProperties, CallDescriptor::kNoFlags);
    284   int return_count = static_cast<int>(descriptor->ReturnCount());
    285 
    286   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    287   Node* ref = AddNode(
    288       common()->ExternalConstant(ExternalReference(function, isolate())));
    289   Node* arity = Int32Constant(5);
    290 
    291   return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, arg4,
    292                  arg5, ref, arity, context);
    293 }
    294 
    295 Node* RawMachineAssembler::TailCallN(CallDescriptor* desc, Node* function,
    296                                      Node** args) {
    297   int param_count = static_cast<int>(desc->ParameterCount());
    298   int input_count = param_count + 1;
    299   Node** buffer = zone()->NewArray<Node*>(input_count);
    300   int index = 0;
    301   buffer[index++] = function;
    302   for (int i = 0; i < param_count; i++) {
    303     buffer[index++] = args[i];
    304   }
    305   Node* tail_call = MakeNode(common()->TailCall(desc), input_count, buffer);
    306   schedule()->AddTailCall(CurrentBlock(), tail_call);
    307   current_block_ = nullptr;
    308   return tail_call;
    309 }
    310 
    311 Node* RawMachineAssembler::TailCallRuntime0(Runtime::FunctionId function,
    312                                             Node* context) {
    313   const int kArity = 0;
    314   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    315       zone(), function, kArity, Operator::kNoProperties,
    316       CallDescriptor::kSupportsTailCalls);
    317   int return_count = static_cast<int>(desc->ReturnCount());
    318 
    319   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    320   Node* ref = AddNode(
    321       common()->ExternalConstant(ExternalReference(function, isolate())));
    322   Node* arity = Int32Constant(kArity);
    323 
    324   Node* nodes[] = {centry, ref, arity, context};
    325   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    326 
    327   schedule()->AddTailCall(CurrentBlock(), tail_call);
    328   current_block_ = nullptr;
    329   return tail_call;
    330 }
    331 
    332 Node* RawMachineAssembler::TailCallRuntime1(Runtime::FunctionId function,
    333                                             Node* arg1, Node* context) {
    334   const int kArity = 1;
    335   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    336       zone(), function, kArity, Operator::kNoProperties,
    337       CallDescriptor::kSupportsTailCalls);
    338   int return_count = static_cast<int>(desc->ReturnCount());
    339 
    340   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    341   Node* ref = AddNode(
    342       common()->ExternalConstant(ExternalReference(function, isolate())));
    343   Node* arity = Int32Constant(kArity);
    344 
    345   Node* nodes[] = {centry, arg1, ref, arity, context};
    346   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    347 
    348   schedule()->AddTailCall(CurrentBlock(), tail_call);
    349   current_block_ = nullptr;
    350   return tail_call;
    351 }
    352 
    353 
    354 Node* RawMachineAssembler::TailCallRuntime2(Runtime::FunctionId function,
    355                                             Node* arg1, Node* arg2,
    356                                             Node* context) {
    357   const int kArity = 2;
    358   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    359       zone(), function, kArity, Operator::kNoProperties,
    360       CallDescriptor::kSupportsTailCalls);
    361   int return_count = static_cast<int>(desc->ReturnCount());
    362 
    363   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    364   Node* ref = AddNode(
    365       common()->ExternalConstant(ExternalReference(function, isolate())));
    366   Node* arity = Int32Constant(kArity);
    367 
    368   Node* nodes[] = {centry, arg1, arg2, ref, arity, context};
    369   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    370 
    371   schedule()->AddTailCall(CurrentBlock(), tail_call);
    372   current_block_ = nullptr;
    373   return tail_call;
    374 }
    375 
    376 Node* RawMachineAssembler::TailCallRuntime3(Runtime::FunctionId function,
    377                                             Node* arg1, Node* arg2, Node* arg3,
    378                                             Node* context) {
    379   const int kArity = 3;
    380   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    381       zone(), function, kArity, Operator::kNoProperties,
    382       CallDescriptor::kSupportsTailCalls);
    383   int return_count = static_cast<int>(desc->ReturnCount());
    384 
    385   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    386   Node* ref = AddNode(
    387       common()->ExternalConstant(ExternalReference(function, isolate())));
    388   Node* arity = Int32Constant(kArity);
    389 
    390   Node* nodes[] = {centry, arg1, arg2, arg3, ref, arity, context};
    391   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    392 
    393   schedule()->AddTailCall(CurrentBlock(), tail_call);
    394   current_block_ = nullptr;
    395   return tail_call;
    396 }
    397 
    398 Node* RawMachineAssembler::TailCallRuntime4(Runtime::FunctionId function,
    399                                             Node* arg1, Node* arg2, Node* arg3,
    400                                             Node* arg4, Node* context) {
    401   const int kArity = 4;
    402   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    403       zone(), function, kArity, Operator::kNoProperties,
    404       CallDescriptor::kSupportsTailCalls);
    405   int return_count = static_cast<int>(desc->ReturnCount());
    406 
    407   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    408   Node* ref = AddNode(
    409       common()->ExternalConstant(ExternalReference(function, isolate())));
    410   Node* arity = Int32Constant(kArity);
    411 
    412   Node* nodes[] = {centry, arg1, arg2, arg3, arg4, ref, arity, context};
    413   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    414 
    415   schedule()->AddTailCall(CurrentBlock(), tail_call);
    416   current_block_ = nullptr;
    417   return tail_call;
    418 }
    419 
    420 Node* RawMachineAssembler::TailCallRuntime5(Runtime::FunctionId function,
    421                                             Node* arg1, Node* arg2, Node* arg3,
    422                                             Node* arg4, Node* arg5,
    423                                             Node* context) {
    424   const int kArity = 5;
    425   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    426       zone(), function, kArity, Operator::kNoProperties,
    427       CallDescriptor::kSupportsTailCalls);
    428   int return_count = static_cast<int>(desc->ReturnCount());
    429 
    430   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    431   Node* ref = AddNode(
    432       common()->ExternalConstant(ExternalReference(function, isolate())));
    433   Node* arity = Int32Constant(kArity);
    434 
    435   Node* nodes[] = {centry, arg1, arg2, arg3, arg4, arg5, ref, arity, context};
    436   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    437 
    438   schedule()->AddTailCall(CurrentBlock(), tail_call);
    439   current_block_ = nullptr;
    440   return tail_call;
    441 }
    442 
    443 Node* RawMachineAssembler::TailCallRuntime6(Runtime::FunctionId function,
    444                                             Node* arg1, Node* arg2, Node* arg3,
    445                                             Node* arg4, Node* arg5, Node* arg6,
    446                                             Node* context) {
    447   const int kArity = 6;
    448   CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
    449       zone(), function, kArity, Operator::kNoProperties,
    450       CallDescriptor::kSupportsTailCalls);
    451   int return_count = static_cast<int>(desc->ReturnCount());
    452 
    453   Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
    454   Node* ref = AddNode(
    455       common()->ExternalConstant(ExternalReference(function, isolate())));
    456   Node* arity = Int32Constant(kArity);
    457 
    458   Node* nodes[] = {centry, arg1, arg2, arg3,  arg4,
    459                    arg5,   arg6, ref,  arity, context};
    460   Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
    461 
    462   schedule()->AddTailCall(CurrentBlock(), tail_call);
    463   current_block_ = nullptr;
    464   return tail_call;
    465 }
    466 
    467 Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
    468                                           Node* function) {
    469   MachineSignature::Builder builder(zone(), 1, 0);
    470   builder.AddReturn(return_type);
    471   const CallDescriptor* descriptor =
    472       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
    473 
    474   return AddNode(common()->Call(descriptor), function);
    475 }
    476 
    477 
    478 Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
    479                                           MachineType arg0_type, Node* function,
    480                                           Node* arg0) {
    481   MachineSignature::Builder builder(zone(), 1, 1);
    482   builder.AddReturn(return_type);
    483   builder.AddParam(arg0_type);
    484   const CallDescriptor* descriptor =
    485       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
    486 
    487   return AddNode(common()->Call(descriptor), function, arg0);
    488 }
    489 
    490 
    491 Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
    492                                           MachineType arg0_type,
    493                                           MachineType arg1_type, Node* function,
    494                                           Node* arg0, Node* arg1) {
    495   MachineSignature::Builder builder(zone(), 1, 2);
    496   builder.AddReturn(return_type);
    497   builder.AddParam(arg0_type);
    498   builder.AddParam(arg1_type);
    499   const CallDescriptor* descriptor =
    500       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
    501 
    502   return AddNode(common()->Call(descriptor), function, arg0, arg1);
    503 }
    504 
    505 
    506 Node* RawMachineAssembler::CallCFunction8(
    507     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
    508     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
    509     MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
    510     Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
    511     Node* arg5, Node* arg6, Node* arg7) {
    512   MachineSignature::Builder builder(zone(), 1, 8);
    513   builder.AddReturn(return_type);
    514   builder.AddParam(arg0_type);
    515   builder.AddParam(arg1_type);
    516   builder.AddParam(arg2_type);
    517   builder.AddParam(arg3_type);
    518   builder.AddParam(arg4_type);
    519   builder.AddParam(arg5_type);
    520   builder.AddParam(arg6_type);
    521   builder.AddParam(arg7_type);
    522   Node* args[] = {function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
    523   const CallDescriptor* descriptor =
    524       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
    525   return AddNode(common()->Call(descriptor), arraysize(args), args);
    526 }
    527 
    528 
    529 void RawMachineAssembler::Bind(RawMachineLabel* label) {
    530   DCHECK(current_block_ == nullptr);
    531   DCHECK(!label->bound_);
    532   label->bound_ = true;
    533   current_block_ = EnsureBlock(label);
    534   current_block_->set_deferred(label->deferred_);
    535 }
    536 
    537 
    538 BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
    539   label->used_ = true;
    540   return EnsureBlock(label);
    541 }
    542 
    543 
    544 BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
    545   if (label->block_ == nullptr) label->block_ = schedule()->NewBasicBlock();
    546   return label->block_;
    547 }
    548 
    549 
    550 BasicBlock* RawMachineAssembler::CurrentBlock() {
    551   DCHECK(current_block_);
    552   return current_block_;
    553 }
    554 
    555 Node* RawMachineAssembler::Phi(MachineRepresentation rep, int input_count,
    556                                Node* const* inputs) {
    557   Node** buffer = new (zone()->New(sizeof(Node*) * (input_count + 1)))
    558       Node*[input_count + 1];
    559   std::copy(inputs, inputs + input_count, buffer);
    560   buffer[input_count] = graph()->start();
    561   return AddNode(common()->Phi(rep, input_count), input_count + 1, buffer);
    562 }
    563 
    564 void RawMachineAssembler::AppendPhiInput(Node* phi, Node* new_input) {
    565   const Operator* op = phi->op();
    566   const Operator* new_op = common()->ResizeMergeOrPhi(op, phi->InputCount());
    567   phi->InsertInput(zone(), phi->InputCount() - 1, new_input);
    568   NodeProperties::ChangeOp(phi, new_op);
    569 }
    570 
    571 Node* RawMachineAssembler::AddNode(const Operator* op, int input_count,
    572                                    Node* const* inputs) {
    573   DCHECK_NOT_NULL(schedule_);
    574   DCHECK_NOT_NULL(current_block_);
    575   Node* node = MakeNode(op, input_count, inputs);
    576   schedule()->AddNode(CurrentBlock(), node);
    577   return node;
    578 }
    579 
    580 Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
    581                                     Node* const* inputs) {
    582   // The raw machine assembler nodes do not have effect and control inputs,
    583   // so we disable checking input counts here.
    584   return graph()->NewNodeUnchecked(op, input_count, inputs);
    585 }
    586 
    587 RawMachineLabel::~RawMachineLabel() { DCHECK(bound_ || !used_); }
    588 
    589 }  // namespace compiler
    590 }  // namespace internal
    591 }  // namespace v8
    592