Line data Source code
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 979862 : GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
15 : Zone* zone)
16 : : temp_zone_(zone),
17 : jsgraph_(jsgraph),
18 : current_effect_(effect),
19 979862 : current_control_(control) {}
20 :
21 2147554 : Node* GraphAssembler::IntPtrConstant(intptr_t value) {
22 2147554 : return jsgraph()->IntPtrConstant(value);
23 : }
24 :
25 665607 : Node* GraphAssembler::Int32Constant(int32_t value) {
26 665607 : return jsgraph()->Int32Constant(value);
27 : }
28 :
29 193 : Node* GraphAssembler::Int64Constant(int64_t value) {
30 193 : return jsgraph()->Int64Constant(value);
31 : }
32 :
33 359052 : Node* GraphAssembler::UniqueIntPtrConstant(intptr_t value) {
34 : return graph()->NewNode(
35 : machine()->Is64() ? common()->Int64Constant(value)
36 538579 : : common()->Int32Constant(static_cast<int32_t>(value)));
37 : }
38 :
39 33420 : Node* GraphAssembler::SmiConstant(int32_t value) {
40 33420 : return jsgraph()->SmiConstant(value);
41 : }
42 :
43 38112 : Node* GraphAssembler::Uint32Constant(int32_t value) {
44 76224 : return jsgraph()->Uint32Constant(value);
45 : }
46 :
47 47538 : Node* GraphAssembler::Float64Constant(double value) {
48 47538 : return jsgraph()->Float64Constant(value);
49 : }
50 :
51 134464 : Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
52 134464 : return jsgraph()->HeapConstant(object);
53 : }
54 :
55 :
56 479139 : Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
57 479139 : return jsgraph()->ExternalConstant(ref);
58 : }
59 :
60 6169 : Node* GraphAssembler::CEntryStubConstant(int result_size) {
61 6169 : return jsgraph()->CEntryStubConstant(result_size);
62 : }
63 :
64 66398 : Node* GraphAssembler::LoadFramePointer() {
65 66398 : return graph()->NewNode(machine()->LoadFramePointer());
66 : }
67 :
68 : #define SINGLETON_CONST_DEF(Name) \
69 : Node* GraphAssembler::Name() { return jsgraph()->Name(); }
70 785737 : 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 1674168 : 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 9380581 : 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 213439 : CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
92 : #undef CHECKED_BINOP_DEF
93 :
94 0 : Node* GraphAssembler::Float64RoundDown(Node* value) {
95 0 : CHECK(machine()->Float64RoundDown().IsSupported());
96 0 : return graph()->NewNode(machine()->Float64RoundDown().op(), value);
97 : }
98 :
99 280 : Node* GraphAssembler::Float64RoundTruncate(Node* value) {
100 140 : CHECK(machine()->Float64RoundTruncate().IsSupported());
101 280 : return graph()->NewNode(machine()->Float64RoundTruncate().op(), value);
102 : }
103 :
104 276396 : Node* GraphAssembler::Projection(int index, Node* value) {
105 414593 : return graph()->NewNode(common()->Projection(index), value, current_control_);
106 : }
107 :
108 348573 : Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
109 : return current_control_ = current_effect_ =
110 : graph()->NewNode(simplified()->AllocateRaw(Type::Any(), pretenure),
111 522859 : size, current_effect_, current_control_);
112 : }
113 :
114 1328288 : Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
115 : return current_effect_ =
116 : graph()->NewNode(simplified()->LoadField(access), object,
117 1992432 : current_effect_, current_control_);
118 : }
119 :
120 10503 : Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
121 10503 : Node* index) {
122 : return current_effect_ =
123 : graph()->NewNode(simplified()->LoadElement(access), object, index,
124 31509 : current_effect_, current_control_);
125 : }
126 :
127 170813 : Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
128 170814 : Node* value) {
129 : return current_effect_ =
130 : graph()->NewNode(simplified()->StoreField(access), object, value,
131 512444 : current_effect_, current_control_);
132 : }
133 :
134 5714 : Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
135 5714 : Node* index, Node* value) {
136 : return current_effect_ =
137 : graph()->NewNode(simplified()->StoreElement(access), object, index,
138 17142 : value, current_effect_, current_control_);
139 : }
140 :
141 58 : Node* GraphAssembler::DebugBreak() {
142 : return current_effect_ = graph()->NewNode(machine()->DebugBreak(),
143 87 : current_effect_, current_control_);
144 : }
145 :
146 10652 : Node* GraphAssembler::Unreachable() {
147 : return current_effect_ = graph()->NewNode(common()->Unreachable(),
148 15978 : current_effect_, current_control_);
149 : }
150 :
151 239439 : Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
152 239440 : Node* value) {
153 : return current_effect_ =
154 : graph()->NewNode(machine()->Store(rep), object, offset, value,
155 718318 : current_effect_, current_control_);
156 : }
157 :
158 894716 : Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
159 : return current_effect_ =
160 : graph()->NewNode(machine()->Load(rep), object, offset,
161 1342076 : current_effect_, current_control_);
162 : }
163 :
164 180 : Node* GraphAssembler::StoreUnaligned(MachineRepresentation rep, Node* object,
165 180 : Node* offset, Node* value) {
166 : Operator const* const op =
167 132 : (rep == MachineRepresentation::kWord8 ||
168 : machine()->UnalignedStoreSupported(rep))
169 360 : ? machine()->Store(StoreRepresentation(rep, kNoWriteBarrier))
170 360 : : machine()->UnalignedStore(rep);
171 : return current_effect_ = graph()->NewNode(op, object, offset, value,
172 360 : current_effect_, current_control_);
173 : }
174 :
175 248 : Node* GraphAssembler::LoadUnaligned(MachineType rep, Node* object,
176 248 : Node* offset) {
177 : Operator const* const op =
178 160 : (rep.representation() == MachineRepresentation::kWord8 ||
179 : machine()->UnalignedLoadSupported(rep.representation()))
180 : ? machine()->Load(rep)
181 496 : : machine()->UnalignedLoad(rep);
182 : return current_effect_ = graph()->NewNode(op, object, offset, current_effect_,
183 496 : current_control_);
184 : }
185 :
186 18312 : Node* GraphAssembler::Retain(Node* buffer) {
187 : return current_effect_ =
188 27468 : graph()->NewNode(common()->Retain(), buffer, current_effect_);
189 : }
190 :
191 13420 : Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
192 : return current_effect_ =
193 : graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
194 20130 : current_effect_, current_control_);
195 : }
196 :
197 58 : Node* GraphAssembler::ToNumber(Node* value) {
198 : return current_effect_ =
199 : graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
200 87 : value, NoContextConstant(), current_effect_);
201 : }
202 :
203 488030 : Node* GraphAssembler::BitcastWordToTagged(Node* value) {
204 : return current_effect_ =
205 : graph()->NewNode(machine()->BitcastWordToTagged(), value,
206 732045 : current_effect_, current_control_);
207 : }
208 :
209 417872 : Node* GraphAssembler::BitcastTaggedToWord(Node* value) {
210 : return current_effect_ =
211 : graph()->NewNode(machine()->BitcastTaggedToWord(), value,
212 626809 : current_effect_, current_control_);
213 : }
214 :
215 0 : Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) {
216 : return current_effect_ =
217 : graph()->NewNode(machine()->Word32PoisonOnSpeculation(), value,
218 0 : current_effect_, current_control_);
219 : }
220 :
221 118654 : Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason,
222 : VectorSlotPair const& feedback,
223 : Node* condition, Node* frame_state,
224 118654 : IsSafetyCheck is_safety_check) {
225 : return current_control_ = current_effect_ = graph()->NewNode(
226 : common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback,
227 : is_safety_check),
228 355965 : condition, frame_state, current_effect_, current_control_);
229 : }
230 :
231 230972 : Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
232 : VectorSlotPair const& feedback,
233 : Node* condition, Node* frame_state,
234 230972 : IsSafetyCheck is_safety_check) {
235 : return current_control_ = current_effect_ = graph()->NewNode(
236 : common()->DeoptimizeUnless(DeoptimizeKind::kEager, reason,
237 : feedback, is_safety_check),
238 692917 : condition, frame_state, current_effect_, current_control_);
239 : }
240 :
241 29781 : void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true,
242 29781 : GraphAssemblerLabel<0u>* if_false,
243 89343 : IsSafetyCheck is_safety_check) {
244 : DCHECK_NOT_NULL(current_control_);
245 :
246 : BranchHint hint = BranchHint::kNone;
247 29781 : if (if_true->IsDeferred() != if_false->IsDeferred()) {
248 8126 : hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
249 : }
250 :
251 : Node* branch = graph()->NewNode(common()->Branch(hint, is_safety_check),
252 59562 : condition, current_control_);
253 :
254 59562 : current_control_ = graph()->NewNode(common()->IfTrue(), branch);
255 29781 : MergeState(if_true);
256 :
257 59562 : current_control_ = graph()->NewNode(common()->IfFalse(), branch);
258 29781 : MergeState(if_false);
259 :
260 29781 : current_control_ = nullptr;
261 29781 : current_effect_ = nullptr;
262 29781 : }
263 :
264 : // Extractors (should be only used when destructing the assembler.
265 1343544 : Node* GraphAssembler::ExtractCurrentControl() {
266 1343544 : Node* result = current_control_;
267 1343544 : current_control_ = nullptr;
268 1343544 : return result;
269 : }
270 :
271 1343543 : Node* GraphAssembler::ExtractCurrentEffect() {
272 1343543 : Node* result = current_effect_;
273 1343543 : current_effect_ = nullptr;
274 1343543 : return result;
275 : }
276 :
277 36549022 : void GraphAssembler::Reset(Node* effect, Node* control) {
278 36549022 : current_effect_ = effect;
279 36549022 : current_control_ = control;
280 36549022 : }
281 :
282 87 : Operator const* GraphAssembler::ToNumberOperator() {
283 29 : if (!to_number_operator_.is_set()) {
284 : Callable callable =
285 29 : Builtins::CallableFor(jsgraph()->isolate(), Builtins::kToNumber);
286 : CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
287 : auto call_descriptor = Linkage::GetStubCallDescriptor(
288 : graph()->zone(), callable.descriptor(),
289 : callable.descriptor().GetStackParameterCount(), flags,
290 58 : Operator::kEliminatable);
291 29 : to_number_operator_.set(common()->Call(call_descriptor));
292 : }
293 29 : return to_number_operator_.get();
294 : }
295 :
296 : } // namespace compiler
297 : } // namespace internal
298 178779 : } // namespace v8
|