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