LCOV - code coverage report
Current view: top level - src/compiler - raw-machine-assembler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 148 178 83.1 %
Date: 2017-04-26 Functions: 28 36 77.8 %

          Line data    Source code
       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/compiler/node-properties.h"
       8             : #include "src/compiler/pipeline.h"
       9             : #include "src/compiler/scheduler.h"
      10             : #include "src/objects-inl.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace compiler {
      15             : 
      16      351926 : RawMachineAssembler::RawMachineAssembler(
      17      841367 :     Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
      18             :     MachineRepresentation word, MachineOperatorBuilder::Flags flags,
      19     1897139 :     MachineOperatorBuilder::AlignmentRequirements alignment_requirements)
      20             :     : isolate_(isolate),
      21             :       graph_(graph),
      22      351926 :       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     1759626 :       current_block_(schedule()->start()) {
      28      351923 :   int param_count = static_cast<int>(parameter_count());
      29             :   // Add an extra input for the JSFunction parameter to the start node.
      30      351923 :   graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
      31     2386586 :   for (size_t i = 0; i < parameter_count(); ++i) {
      32      841367 :     parameters_[i] =
      33     1682734 :         AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
      34             :   }
      35      351926 :   graph->SetEnd(graph->NewNode(common_.End(0)));
      36      351926 : }
      37             : 
      38         378 : Node* RawMachineAssembler::RelocatableIntPtrConstant(intptr_t value,
      39             :                                                      RelocInfo::Mode rmode) {
      40             :   return kPointerSize == 8
      41             :              ? RelocatableInt64Constant(value, rmode)
      42         378 :              : RelocatableInt32Constant(static_cast<int>(value), rmode);
      43             : }
      44             : 
      45      347840 : Schedule* RawMachineAssembler::Export() {
      46             :   // Compute the correct codegen order.
      47             :   DCHECK(schedule_->rpo_order()->empty());
      48      347840 :   OFStream os(stdout);
      49      347839 :   if (FLAG_trace_turbo_scheduler) {
      50           0 :     PrintF("--- RAW SCHEDULE -------------------------------------------\n");
      51           0 :     os << *schedule_;
      52             :   }
      53      347839 :   schedule_->EnsureCFGWellFormedness();
      54      695680 :   Scheduler::ComputeSpecialRPO(zone(), schedule_);
      55      347840 :   schedule_->PropagateDeferredMark();
      56      347840 :   if (FLAG_trace_turbo_scheduler) {
      57           0 :     PrintF("--- EDGE SPLIT AND PROPAGATED DEFERRED SCHEDULE ------------\n");
      58           0 :     os << *schedule_;
      59             :   }
      60             :   // Invalidate RawMachineAssembler.
      61      347840 :   Schedule* schedule = schedule_;
      62      347840 :   schedule_ = nullptr;
      63      347840 :   return schedule;
      64             : }
      65             : 
      66             : 
      67      609303 : Node* RawMachineAssembler::Parameter(size_t index) {
      68             :   DCHECK(index < parameter_count());
      69     1218606 :   return parameters_[index];
      70             : }
      71             : 
      72             : 
      73     1335002 : void RawMachineAssembler::Goto(RawMachineLabel* label) {
      74             :   DCHECK(current_block_ != schedule()->end());
      75      667501 :   schedule()->AddGoto(CurrentBlock(), Use(label));
      76      667501 :   current_block_ = nullptr;
      77      667501 : }
      78             : 
      79             : 
      80      951274 : void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
      81      951275 :                                  RawMachineLabel* false_val) {
      82             :   DCHECK(current_block_ != schedule()->end());
      83      951274 :   Node* branch = MakeNode(common()->Branch(), 1, &condition);
      84      951275 :   schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val));
      85      951274 :   current_block_ = nullptr;
      86      951274 : }
      87             : 
      88         845 : void RawMachineAssembler::Continuations(Node* call, RawMachineLabel* if_success,
      89         845 :                                         RawMachineLabel* if_exception) {
      90             :   DCHECK_NOT_NULL(schedule_);
      91             :   DCHECK_NOT_NULL(current_block_);
      92         845 :   schedule()->AddCall(CurrentBlock(), call, Use(if_success), Use(if_exception));
      93         845 :   current_block_ = nullptr;
      94         845 : }
      95             : 
      96        4904 : void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
      97             :                                  const int32_t* case_values,
      98             :                                  RawMachineLabel** case_labels,
      99      275128 :                                  size_t case_count) {
     100             :   DCHECK_NE(schedule()->end(), current_block_);
     101        4904 :   size_t succ_count = case_count + 1;
     102        4904 :   Node* switch_node = AddNode(common()->Switch(succ_count), index);
     103             :   BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
     104       67556 :   for (size_t index = 0; index < case_count; ++index) {
     105       62652 :     int32_t case_value = case_values[index];
     106       62652 :     BasicBlock* case_block = schedule()->NewBasicBlock();
     107             :     Node* case_node =
     108       62652 :         graph()->NewNode(common()->IfValue(case_value), switch_node);
     109       62652 :     schedule()->AddNode(case_block, case_node);
     110      125304 :     schedule()->AddGoto(case_block, Use(case_labels[index]));
     111       62652 :     succ_blocks[index] = case_block;
     112             :   }
     113        4904 :   BasicBlock* default_block = schedule()->NewBasicBlock();
     114        4904 :   Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
     115        4904 :   schedule()->AddNode(default_block, default_node);
     116        4904 :   schedule()->AddGoto(default_block, Use(default_label));
     117        4904 :   succ_blocks[case_count] = default_block;
     118        4904 :   schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
     119        4904 :   current_block_ = nullptr;
     120        4904 : }
     121             : 
     122      622874 : void RawMachineAssembler::Return(Node* value) {
     123      311437 :   Node* values[] = {Int32Constant(0), value};
     124      311437 :   Node* ret = MakeNode(common()->Return(1), 2, values);
     125      311437 :   schedule()->AddReturn(CurrentBlock(), ret);
     126      311437 :   current_block_ = nullptr;
     127      311437 : }
     128             : 
     129             : 
     130           0 : void RawMachineAssembler::Return(Node* v1, Node* v2) {
     131           0 :   Node* values[] = {Int32Constant(0), v1, v2};
     132           0 :   Node* ret = MakeNode(common()->Return(2), 3, values);
     133           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     134           0 :   current_block_ = nullptr;
     135           0 : }
     136             : 
     137             : 
     138         186 : void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
     139          93 :   Node* values[] = {Int32Constant(0), v1, v2, v3};
     140          93 :   Node* ret = MakeNode(common()->Return(3), 4, values);
     141          93 :   schedule()->AddReturn(CurrentBlock(), ret);
     142          93 :   current_block_ = nullptr;
     143          93 : }
     144             : 
     145        1834 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* value) {
     146         917 :   Node* values[] = {pop, value};
     147         917 :   Node* ret = MakeNode(common()->Return(1), 2, values);
     148         917 :   schedule()->AddReturn(CurrentBlock(), ret);
     149         917 :   current_block_ = nullptr;
     150         917 : }
     151             : 
     152           0 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2) {
     153           0 :   Node* values[] = {pop, v1, v2};
     154           0 :   Node* ret = MakeNode(common()->Return(2), 3, values);
     155           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     156           0 :   current_block_ = nullptr;
     157           0 : }
     158             : 
     159           0 : void RawMachineAssembler::PopAndReturn(Node* pop, Node* v1, Node* v2,
     160           0 :                                        Node* v3) {
     161           0 :   Node* values[] = {pop, v1, v2, v3};
     162           0 :   Node* ret = MakeNode(common()->Return(3), 4, values);
     163           0 :   schedule()->AddReturn(CurrentBlock(), ret);
     164           0 :   current_block_ = nullptr;
     165           0 : }
     166             : 
     167       18174 : void RawMachineAssembler::DebugBreak() { AddNode(machine()->DebugBreak()); }
     168             : 
     169       18088 : void RawMachineAssembler::Unreachable() {
     170        9044 :   Node* ret = MakeNode(common()->Throw(), 0, nullptr);
     171        9044 :   schedule()->AddThrow(CurrentBlock(), ret);
     172        9044 :   current_block_ = nullptr;
     173        9044 : }
     174             : 
     175           0 : void RawMachineAssembler::Comment(const char* msg) {
     176           0 :   AddNode(machine()->Comment(msg));
     177           0 : }
     178             : 
     179      210438 : Node* RawMachineAssembler::CallN(CallDescriptor* desc, int input_count,
     180             :                                  Node* const* inputs) {
     181             :   DCHECK(!desc->NeedsFrameState());
     182             :   // +1 is for target.
     183             :   DCHECK_EQ(input_count, desc->ParameterCount() + 1);
     184      210438 :   return AddNode(common()->Call(desc), input_count, inputs);
     185             : }
     186             : 
     187           3 : Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* desc,
     188             :                                                int input_count,
     189             :                                                Node* const* inputs) {
     190             :   DCHECK(desc->NeedsFrameState());
     191             :   // +2 is for target and frame state.
     192             :   DCHECK_EQ(input_count, desc->ParameterCount() + 2);
     193           3 :   return AddNode(common()->Call(desc), input_count, inputs);
     194             : }
     195             : 
     196      148873 : Node* RawMachineAssembler::TailCallN(CallDescriptor* desc, int input_count,
     197      148873 :                                      Node* const* inputs) {
     198             :   // +1 is for target.
     199             :   DCHECK_EQ(input_count, desc->ParameterCount() + 1);
     200      148873 :   Node* tail_call = MakeNode(common()->TailCall(desc), input_count, inputs);
     201      148873 :   schedule()->AddTailCall(CurrentBlock(), tail_call);
     202      148873 :   current_block_ = nullptr;
     203      148873 :   return tail_call;
     204             : }
     205             : 
     206           6 : Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
     207             :                                           Node* function) {
     208             :   MachineSignature::Builder builder(zone(), 1, 0);
     209             :   builder.AddReturn(return_type);
     210             :   const CallDescriptor* descriptor =
     211          12 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     212             : 
     213          12 :   return AddNode(common()->Call(descriptor), function);
     214             : }
     215             : 
     216             : 
     217         176 : Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
     218             :                                           MachineType arg0_type, Node* function,
     219             :                                           Node* arg0) {
     220             :   MachineSignature::Builder builder(zone(), 1, 1);
     221             :   builder.AddReturn(return_type);
     222             :   builder.AddParam(arg0_type);
     223             :   const CallDescriptor* descriptor =
     224         352 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     225             : 
     226         352 :   return AddNode(common()->Call(descriptor), function, arg0);
     227             : }
     228             : 
     229             : 
     230         828 : Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
     231             :                                           MachineType arg0_type,
     232             :                                           MachineType arg1_type, Node* function,
     233             :                                           Node* arg0, Node* arg1) {
     234             :   MachineSignature::Builder builder(zone(), 1, 2);
     235             :   builder.AddReturn(return_type);
     236             :   builder.AddParam(arg0_type);
     237             :   builder.AddParam(arg1_type);
     238             :   const CallDescriptor* descriptor =
     239        1656 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     240             : 
     241        1656 :   return AddNode(common()->Call(descriptor), function, arg0, arg1);
     242             : }
     243             : 
     244         172 : Node* RawMachineAssembler::CallCFunction3(MachineType return_type,
     245             :                                           MachineType arg0_type,
     246             :                                           MachineType arg1_type,
     247             :                                           MachineType arg2_type, Node* function,
     248             :                                           Node* arg0, Node* arg1, Node* arg2) {
     249             :   MachineSignature::Builder builder(zone(), 1, 3);
     250             :   builder.AddReturn(return_type);
     251             :   builder.AddParam(arg0_type);
     252             :   builder.AddParam(arg1_type);
     253             :   builder.AddParam(arg2_type);
     254             :   const CallDescriptor* descriptor =
     255         344 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     256             : 
     257         344 :   return AddNode(common()->Call(descriptor), function, arg0, arg1, arg2);
     258             : }
     259             : 
     260         344 : Node* RawMachineAssembler::CallCFunction6(
     261             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     262             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     263             :     MachineType arg5_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
     264             :     Node* arg3, Node* arg4, Node* arg5) {
     265             :   MachineSignature::Builder builder(zone(), 1, 6);
     266             :   builder.AddReturn(return_type);
     267             :   builder.AddParam(arg0_type);
     268             :   builder.AddParam(arg1_type);
     269             :   builder.AddParam(arg2_type);
     270             :   builder.AddParam(arg3_type);
     271             :   builder.AddParam(arg4_type);
     272             :   builder.AddParam(arg5_type);
     273             :   const CallDescriptor* descriptor =
     274         688 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     275             : 
     276             :   return AddNode(common()->Call(descriptor), function, arg0, arg1, arg2, arg3,
     277         688 :                  arg4, arg5);
     278             : }
     279             : 
     280           6 : Node* RawMachineAssembler::CallCFunction8(
     281             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     282             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     283             :     MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
     284             :     Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
     285             :     Node* arg5, Node* arg6, Node* arg7) {
     286             :   MachineSignature::Builder builder(zone(), 1, 8);
     287             :   builder.AddReturn(return_type);
     288             :   builder.AddParam(arg0_type);
     289             :   builder.AddParam(arg1_type);
     290             :   builder.AddParam(arg2_type);
     291             :   builder.AddParam(arg3_type);
     292             :   builder.AddParam(arg4_type);
     293             :   builder.AddParam(arg5_type);
     294             :   builder.AddParam(arg6_type);
     295             :   builder.AddParam(arg7_type);
     296           6 :   Node* args[] = {function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
     297             :   const CallDescriptor* descriptor =
     298          12 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     299           6 :   return AddNode(common()->Call(descriptor), arraysize(args), args);
     300             : }
     301             : 
     302         443 : Node* RawMachineAssembler::CallCFunction9(
     303             :     MachineType return_type, MachineType arg0_type, MachineType arg1_type,
     304             :     MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
     305             :     MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
     306             :     MachineType arg8_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
     307             :     Node* arg3, Node* arg4, Node* arg5, Node* arg6, Node* arg7, Node* arg8) {
     308             :   MachineSignature::Builder builder(zone(), 1, 9);
     309             :   builder.AddReturn(return_type);
     310             :   builder.AddParam(arg0_type);
     311             :   builder.AddParam(arg1_type);
     312             :   builder.AddParam(arg2_type);
     313             :   builder.AddParam(arg3_type);
     314             :   builder.AddParam(arg4_type);
     315             :   builder.AddParam(arg5_type);
     316             :   builder.AddParam(arg6_type);
     317             :   builder.AddParam(arg7_type);
     318             :   builder.AddParam(arg8_type);
     319             :   Node* args[] = {function, arg0, arg1, arg2, arg3,
     320         443 :                   arg4,     arg5, arg6, arg7, arg8};
     321             :   const CallDescriptor* descriptor =
     322         886 :       Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
     323         443 :   return AddNode(common()->Call(descriptor), arraysize(args), args);
     324             : }
     325             : 
     326           0 : BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
     327     2639297 :   label->used_ = true;
     328           0 :   return EnsureBlock(label);
     329             : }
     330             : 
     331     1747192 : BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
     332     4386488 :   if (label->block_ == nullptr) {
     333     1747192 :     label->block_ = schedule()->NewBasicBlock();
     334             :   }
     335     4386488 :   return label->block_;
     336             : }
     337             : 
     338     1747191 : void RawMachineAssembler::Bind(RawMachineLabel* label) {
     339             :   DCHECK(current_block_ == nullptr);
     340             :   DCHECK(!label->bound_);
     341     1747191 :   label->bound_ = true;
     342     1747191 :   current_block_ = EnsureBlock(label);
     343     1747191 :   current_block_->set_deferred(label->deferred_);
     344     1747191 : }
     345             : 
     346             : #if DEBUG
     347             : void RawMachineAssembler::Bind(RawMachineLabel* label,
     348             :                                AssemblerDebugInfo info) {
     349             :   if (current_block_ != nullptr) {
     350             :     std::stringstream str;
     351             :     str << "Binding label without closing previous block:"
     352             :         << "\n#    label:          " << info
     353             :         << "\n#    previous block: " << *current_block_;
     354             :     FATAL(str.str().c_str());
     355             :   }
     356             :   Bind(label);
     357             :   current_block_->set_debug_info(info);
     358             : }
     359             : 
     360             : void RawMachineAssembler::PrintCurrentBlock(std::ostream& os) {
     361             :   os << CurrentBlock();
     362             : }
     363             : 
     364             : void RawMachineAssembler::SetInitialDebugInformation(
     365             :     AssemblerDebugInfo debug_info) {
     366             :   CurrentBlock()->set_debug_info(debug_info);
     367             : }
     368             : #endif  // DEBUG
     369             : 
     370           0 : BasicBlock* RawMachineAssembler::CurrentBlock() {
     371             :   DCHECK(current_block_);
     372    17549728 :   return current_block_;
     373             : }
     374             : 
     375      402067 : Node* RawMachineAssembler::Phi(MachineRepresentation rep, int input_count,
     376      402067 :                                Node* const* inputs) {
     377      402067 :   Node** buffer = new (zone()->New(sizeof(Node*) * (input_count + 1)))
     378      402067 :       Node*[input_count + 1];
     379      402067 :   std::copy(inputs, inputs + input_count, buffer);
     380      804134 :   buffer[input_count] = graph()->start();
     381      402067 :   return AddNode(common()->Phi(rep, input_count), input_count + 1, buffer);
     382             : }
     383             : 
     384      142555 : void RawMachineAssembler::AppendPhiInput(Node* phi, Node* new_input) {
     385             :   const Operator* op = phi->op();
     386      142555 :   const Operator* new_op = common()->ResizeMergeOrPhi(op, phi->InputCount());
     387      285110 :   phi->InsertInput(zone(), phi->InputCount() - 1, new_input);
     388      142555 :   NodeProperties::ChangeOp(phi, new_op);
     389      142555 : }
     390             : 
     391    15454825 : Node* RawMachineAssembler::AddNode(const Operator* op, int input_count,
     392    15454839 :                                    Node* const* inputs) {
     393             :   DCHECK_NOT_NULL(schedule_);
     394             :   DCHECK_NOT_NULL(current_block_);
     395             :   Node* node = MakeNode(op, input_count, inputs);
     396    15454839 :   schedule()->AddNode(CurrentBlock(), node);
     397    15454824 :   return node;
     398             : }
     399             : 
     400           0 : Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
     401    16876462 :                                     Node* const* inputs) {
     402             :   // The raw machine assembler nodes do not have effect and control inputs,
     403             :   // so we disable checking input counts here.
     404    16876462 :   return graph()->NewNodeUnchecked(op, input_count, inputs);
     405             : }
     406             : 
     407     1760126 : RawMachineLabel::~RawMachineLabel() {
     408             :   // If this DCHECK fails, it means that the label has been bound but it's not
     409             :   // used, or the opposite. This would cause the register allocator to crash.
     410             :   DCHECK_EQ(bound_, used_);
     411     1760126 : }
     412             : 
     413             : }  // namespace compiler
     414             : }  // namespace internal
     415             : }  // namespace v8

Generated by: LCOV version 1.10