• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/compiler/graph-assembler.h"
6 
7 #include "src/code-factory.h"
8 #include "src/compiler/linkage.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13 
GraphAssembler(JSGraph * jsgraph,Node * effect,Node * control,Zone * zone)14 GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
15                                Zone* zone)
16     : temp_zone_(zone),
17       jsgraph_(jsgraph),
18       current_effect_(effect),
19       current_control_(control) {}
20 
IntPtrConstant(intptr_t value)21 Node* GraphAssembler::IntPtrConstant(intptr_t value) {
22   return jsgraph()->IntPtrConstant(value);
23 }
24 
Int32Constant(int32_t value)25 Node* GraphAssembler::Int32Constant(int32_t value) {
26   return jsgraph()->Int32Constant(value);
27 }
28 
UniqueInt32Constant(int32_t value)29 Node* GraphAssembler::UniqueInt32Constant(int32_t value) {
30   return graph()->NewNode(common()->Int32Constant(value));
31 }
32 
SmiConstant(int32_t value)33 Node* GraphAssembler::SmiConstant(int32_t value) {
34   return jsgraph()->SmiConstant(value);
35 }
36 
Uint32Constant(int32_t value)37 Node* GraphAssembler::Uint32Constant(int32_t value) {
38   return jsgraph()->Uint32Constant(value);
39 }
40 
Float64Constant(double value)41 Node* GraphAssembler::Float64Constant(double value) {
42   return jsgraph()->Float64Constant(value);
43 }
44 
HeapConstant(Handle<HeapObject> object)45 Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
46   return jsgraph()->HeapConstant(object);
47 }
48 
49 
ExternalConstant(ExternalReference ref)50 Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
51   return jsgraph()->ExternalConstant(ref);
52 }
53 
CEntryStubConstant(int result_size)54 Node* GraphAssembler::CEntryStubConstant(int result_size) {
55   return jsgraph()->CEntryStubConstant(result_size);
56 }
57 
LoadFramePointer()58 Node* GraphAssembler::LoadFramePointer() {
59   return graph()->NewNode(machine()->LoadFramePointer());
60 }
61 
62 #define SINGLETON_CONST_DEF(Name) \
63   Node* GraphAssembler::Name() { return jsgraph()->Name(); }
64 JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
65 #undef SINGLETON_CONST_DEF
66 
67 #define PURE_UNOP_DEF(Name)                            \
68   Node* GraphAssembler::Name(Node* input) {            \
69     return graph()->NewNode(machine()->Name(), input); \
70   }
PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)71 PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
72 #undef PURE_UNOP_DEF
73 
74 #define PURE_BINOP_DEF(Name)                                 \
75   Node* GraphAssembler::Name(Node* left, Node* right) {      \
76     return graph()->NewNode(machine()->Name(), left, right); \
77   }
78 PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
79 #undef PURE_BINOP_DEF
80 
81 #define CHECKED_BINOP_DEF(Name)                                                \
82   Node* GraphAssembler::Name(Node* left, Node* right) {                        \
83     return graph()->NewNode(machine()->Name(), left, right, current_control_); \
84   }
85 CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
86 #undef CHECKED_BINOP_DEF
87 
88 Node* GraphAssembler::Float64RoundDown(Node* value) {
89   CHECK(machine()->Float64RoundDown().IsSupported());
90   return graph()->NewNode(machine()->Float64RoundDown().op(), value);
91 }
92 
Float64RoundTruncate(Node * value)93 Node* GraphAssembler::Float64RoundTruncate(Node* value) {
94   CHECK(machine()->Float64RoundTruncate().IsSupported());
95   return graph()->NewNode(machine()->Float64RoundTruncate().op(), value);
96 }
97 
Projection(int index,Node * value)98 Node* GraphAssembler::Projection(int index, Node* value) {
99   return graph()->NewNode(common()->Projection(index), value, current_control_);
100 }
101 
Allocate(PretenureFlag pretenure,Node * size)102 Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
103   return current_control_ = current_effect_ =
104              graph()->NewNode(simplified()->AllocateRaw(Type::Any(), pretenure),
105                               size, current_effect_, current_control_);
106 }
107 
LoadField(FieldAccess const & access,Node * object)108 Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
109   return current_effect_ =
110              graph()->NewNode(simplified()->LoadField(access), object,
111                               current_effect_, current_control_);
112 }
113 
LoadElement(ElementAccess const & access,Node * object,Node * index)114 Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
115                                   Node* index) {
116   return current_effect_ =
117              graph()->NewNode(simplified()->LoadElement(access), object, index,
118                               current_effect_, current_control_);
119 }
120 
StoreField(FieldAccess const & access,Node * object,Node * value)121 Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
122                                  Node* value) {
123   return current_effect_ =
124              graph()->NewNode(simplified()->StoreField(access), object, value,
125                               current_effect_, current_control_);
126 }
127 
StoreElement(ElementAccess const & access,Node * object,Node * index,Node * value)128 Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
129                                    Node* index, Node* value) {
130   return current_effect_ =
131              graph()->NewNode(simplified()->StoreElement(access), object, index,
132                               value, current_effect_, current_control_);
133 }
134 
DebugBreak()135 Node* GraphAssembler::DebugBreak() {
136   return current_effect_ = graph()->NewNode(machine()->DebugBreak(),
137                                             current_effect_, current_control_);
138 }
139 
Unreachable()140 Node* GraphAssembler::Unreachable() {
141   return current_effect_ = graph()->NewNode(common()->Unreachable(),
142                                             current_effect_, current_control_);
143 }
144 
Store(StoreRepresentation rep,Node * object,Node * offset,Node * value)145 Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
146                             Node* value) {
147   return current_effect_ =
148              graph()->NewNode(machine()->Store(rep), object, offset, value,
149                               current_effect_, current_control_);
150 }
151 
Load(MachineType rep,Node * object,Node * offset)152 Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
153   return current_effect_ =
154              graph()->NewNode(machine()->Load(rep), object, offset,
155                               current_effect_, current_control_);
156 }
157 
StoreUnaligned(MachineRepresentation rep,Node * object,Node * offset,Node * value)158 Node* GraphAssembler::StoreUnaligned(MachineRepresentation rep, Node* object,
159                                      Node* offset, Node* value) {
160   Operator const* const op =
161       (rep == MachineRepresentation::kWord8 ||
162        machine()->UnalignedStoreSupported(rep))
163           ? machine()->Store(StoreRepresentation(rep, kNoWriteBarrier))
164           : machine()->UnalignedStore(rep);
165   return current_effect_ = graph()->NewNode(op, object, offset, value,
166                                             current_effect_, current_control_);
167 }
168 
LoadUnaligned(MachineType rep,Node * object,Node * offset)169 Node* GraphAssembler::LoadUnaligned(MachineType rep, Node* object,
170                                     Node* offset) {
171   Operator const* const op =
172       (rep.representation() == MachineRepresentation::kWord8 ||
173        machine()->UnalignedLoadSupported(rep.representation()))
174           ? machine()->Load(rep)
175           : machine()->UnalignedLoad(rep);
176   return current_effect_ = graph()->NewNode(op, object, offset, current_effect_,
177                                             current_control_);
178 }
179 
Retain(Node * buffer)180 Node* GraphAssembler::Retain(Node* buffer) {
181   return current_effect_ =
182              graph()->NewNode(common()->Retain(), buffer, current_effect_);
183 }
184 
UnsafePointerAdd(Node * base,Node * external)185 Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
186   return current_effect_ =
187              graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
188                               current_effect_, current_control_);
189 }
190 
ToNumber(Node * value)191 Node* GraphAssembler::ToNumber(Node* value) {
192   return current_effect_ =
193              graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
194                               value, NoContextConstant(), current_effect_);
195 }
196 
BitcastWordToTagged(Node * value)197 Node* GraphAssembler::BitcastWordToTagged(Node* value) {
198   return current_effect_ =
199              graph()->NewNode(machine()->BitcastWordToTagged(), value,
200                               current_effect_, current_control_);
201 }
202 
Word32PoisonOnSpeculation(Node * value)203 Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) {
204   return current_effect_ =
205              graph()->NewNode(machine()->Word32PoisonOnSpeculation(), value,
206                               current_effect_, current_control_);
207 }
208 
DeoptimizeIf(DeoptimizeReason reason,VectorSlotPair const & feedback,Node * condition,Node * frame_state)209 Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason,
210                                    VectorSlotPair const& feedback,
211                                    Node* condition, Node* frame_state) {
212   return current_control_ = current_effect_ = graph()->NewNode(
213              common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback),
214              condition, frame_state, current_effect_, current_control_);
215 }
216 
DeoptimizeIfNot(DeoptimizeReason reason,VectorSlotPair const & feedback,Node * condition,Node * frame_state,IsSafetyCheck is_safety_check)217 Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
218                                       VectorSlotPair const& feedback,
219                                       Node* condition, Node* frame_state,
220                                       IsSafetyCheck is_safety_check) {
221   return current_control_ = current_effect_ = graph()->NewNode(
222              common()->DeoptimizeUnless(DeoptimizeKind::kEager, reason,
223                                         feedback, is_safety_check),
224              condition, frame_state, current_effect_, current_control_);
225 }
226 
Branch(Node * condition,GraphAssemblerLabel<0u> * if_true,GraphAssemblerLabel<0u> * if_false)227 void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true,
228                             GraphAssemblerLabel<0u>* if_false) {
229   DCHECK_NOT_NULL(current_control_);
230 
231   BranchHint hint = BranchHint::kNone;
232   if (if_true->IsDeferred() != if_false->IsDeferred()) {
233     hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
234   }
235 
236   Node* branch =
237       graph()->NewNode(common()->Branch(hint), condition, current_control_);
238 
239   current_control_ = graph()->NewNode(common()->IfTrue(), branch);
240   MergeState(if_true);
241 
242   current_control_ = graph()->NewNode(common()->IfFalse(), branch);
243   MergeState(if_false);
244 
245   current_control_ = nullptr;
246   current_effect_ = nullptr;
247 }
248 
249 // Extractors (should be only used when destructing the assembler.
ExtractCurrentControl()250 Node* GraphAssembler::ExtractCurrentControl() {
251   Node* result = current_control_;
252   current_control_ = nullptr;
253   return result;
254 }
255 
ExtractCurrentEffect()256 Node* GraphAssembler::ExtractCurrentEffect() {
257   Node* result = current_effect_;
258   current_effect_ = nullptr;
259   return result;
260 }
261 
Reset(Node * effect,Node * control)262 void GraphAssembler::Reset(Node* effect, Node* control) {
263   current_effect_ = effect;
264   current_control_ = control;
265 }
266 
ToNumberOperator()267 Operator const* GraphAssembler::ToNumberOperator() {
268   if (!to_number_operator_.is_set()) {
269     Callable callable =
270         Builtins::CallableFor(jsgraph()->isolate(), Builtins::kToNumber);
271     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
272     auto call_descriptor =
273         Linkage::GetStubCallDescriptor(graph()->zone(), callable.descriptor(),
274                                        0, flags, Operator::kEliminatable);
275     to_number_operator_.set(common()->Call(call_descriptor));
276   }
277   return to_number_operator_.get();
278 }
279 
280 }  // namespace compiler
281 }  // namespace internal
282 }  // namespace v8
283