Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / raw-machine-assembler.cc
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/code-factory.h"
6 #include "src/compiler/pipeline.h"
7 #include "src/compiler/raw-machine-assembler.h"
8 #include "src/compiler/scheduler.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 RawMachineAssembler::RawMachineAssembler(Graph* graph,
15                                          MachineSignature* machine_sig,
16                                          MachineType word,
17                                          MachineOperatorBuilder::Flags flags)
18     : GraphBuilder(graph),
19       schedule_(new (zone()) Schedule(zone())),
20       machine_(word, flags),
21       common_(zone()),
22       machine_sig_(machine_sig),
23       call_descriptor_(
24           Linkage::GetSimplifiedCDescriptor(graph->zone(), machine_sig)),
25       parameters_(NULL),
26       exit_label_(schedule()->end()),
27       current_block_(schedule()->start()) {
28   int param_count = static_cast<int>(parameter_count());
29   Node* s = graph->NewNode(common_.Start(param_count));
30   graph->SetStart(s);
31   if (parameter_count() == 0) return;
32   parameters_ = zone()->NewArray<Node*>(param_count);
33   for (size_t i = 0; i < parameter_count(); ++i) {
34     parameters_[i] =
35         NewNode(common()->Parameter(static_cast<int>(i)), graph->start());
36   }
37 }
38
39
40 Schedule* RawMachineAssembler::Export() {
41   // Compute the correct codegen order.
42   DCHECK(schedule_->rpo_order()->empty());
43   ZonePool zone_pool(isolate());
44   Scheduler::ComputeSpecialRPO(&zone_pool, schedule_);
45   // Invalidate MachineAssembler.
46   Schedule* schedule = schedule_;
47   schedule_ = NULL;
48   return schedule;
49 }
50
51
52 Node* RawMachineAssembler::Parameter(size_t index) {
53   DCHECK(index < parameter_count());
54   return parameters_[index];
55 }
56
57
58 RawMachineAssembler::Label* RawMachineAssembler::Exit() {
59   exit_label_.used_ = true;
60   return &exit_label_;
61 }
62
63
64 void RawMachineAssembler::Goto(Label* label) {
65   DCHECK(current_block_ != schedule()->end());
66   schedule()->AddGoto(CurrentBlock(), Use(label));
67   current_block_ = NULL;
68 }
69
70
71 void RawMachineAssembler::Branch(Node* condition, Label* true_val,
72                                  Label* false_val) {
73   DCHECK(current_block_ != schedule()->end());
74   Node* branch = NewNode(common()->Branch(), condition);
75   schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val));
76   current_block_ = NULL;
77 }
78
79
80 void RawMachineAssembler::Return(Node* value) {
81   schedule()->AddReturn(CurrentBlock(), value);
82   current_block_ = NULL;
83 }
84
85
86 Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver,
87                                              Node* context, Node* frame_state,
88                                              CallFunctionFlags flags) {
89   Callable callable = CodeFactory::CallFunction(isolate(), 0, flags);
90   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
91       callable.descriptor(), 1, CallDescriptor::kNeedsFrameState, zone());
92   Node* stub_code = HeapConstant(callable.code());
93   Node* call = graph()->NewNode(common()->Call(desc), stub_code, function,
94                                 receiver, context, frame_state);
95   schedule()->AddNode(CurrentBlock(), call);
96   return call;
97 }
98
99
100 Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver,
101                                    Node* context, Node* frame_state) {
102   CallDescriptor* descriptor =
103       Linkage::GetJSCallDescriptor(1, zone(), CallDescriptor::kNeedsFrameState);
104   Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver,
105                                 context, frame_state);
106   schedule()->AddNode(CurrentBlock(), call);
107   return call;
108 }
109
110
111 Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function,
112                                         Node* arg0, Node* context,
113                                         Node* frame_state) {
114   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
115       function, 1, Operator::kNoProperties, zone());
116
117   Node* centry = HeapConstant(CEntryStub(isolate(), 1).GetCode());
118   Node* ref = NewNode(
119       common()->ExternalConstant(ExternalReference(function, isolate())));
120   Node* arity = Int32Constant(1);
121
122   Node* call = graph()->NewNode(common()->Call(descriptor), centry, arg0, ref,
123                                 arity, context, frame_state);
124   schedule()->AddNode(CurrentBlock(), call);
125   return call;
126 }
127
128
129 void RawMachineAssembler::Bind(Label* label) {
130   DCHECK(current_block_ == NULL);
131   DCHECK(!label->bound_);
132   label->bound_ = true;
133   current_block_ = EnsureBlock(label);
134 }
135
136
137 BasicBlock* RawMachineAssembler::Use(Label* label) {
138   label->used_ = true;
139   return EnsureBlock(label);
140 }
141
142
143 BasicBlock* RawMachineAssembler::EnsureBlock(Label* label) {
144   if (label->block_ == NULL) label->block_ = schedule()->NewBasicBlock();
145   return label->block_;
146 }
147
148
149 BasicBlock* RawMachineAssembler::CurrentBlock() {
150   DCHECK(current_block_);
151   return current_block_;
152 }
153
154
155 Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
156                                     Node** inputs, bool incomplete) {
157   DCHECK(ScheduleValid());
158   DCHECK(current_block_ != NULL);
159   Node* node = graph()->NewNode(op, input_count, inputs, incomplete);
160   BasicBlock* block = op->opcode() == IrOpcode::kParameter ? schedule()->start()
161                                                            : CurrentBlock();
162   schedule()->AddNode(block, node);
163   return node;
164 }
165
166 }  // namespace compiler
167 }  // namespace internal
168 }  // namespace v8