OLD | NEW |
---|---|
(Empty) | |
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::TrueConstant() { return jsgraph()->TrueConstant(); } | |
22 | |
23 Node* GraphAssembler::FalseConstant() { return jsgraph()->FalseConstant(); } | |
24 | |
25 Node* GraphAssembler::HeapNumberMapConstant() { | |
26 return jsgraph()->HeapNumberMapConstant(); | |
27 } | |
28 | |
29 Node* GraphAssembler::IntPtrConstant(intptr_t value) { | |
30 return jsgraph()->IntPtrConstant(value); | |
31 } | |
32 | |
33 Node* GraphAssembler::Int32Constant(int32_t value) { | |
34 return jsgraph()->Int32Constant(value); | |
35 } | |
36 | |
37 Node* GraphAssembler::SmiConstant(int32_t value) { | |
38 return jsgraph()->SmiConstant(value); | |
39 } | |
40 | |
41 Node* GraphAssembler::Uint32Constant(int32_t value) { | |
42 return jsgraph()->Uint32Constant(value); | |
43 } | |
44 | |
45 Node* GraphAssembler::Float64Constant(double value) { | |
46 return jsgraph()->Float64Constant(value); | |
47 } | |
48 | |
49 Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) { | |
50 return jsgraph()->HeapConstant(object); | |
51 } | |
52 | |
53 Node* GraphAssembler::NoContextConstant() { | |
54 return jsgraph()->NoContextConstant(); | |
55 } | |
56 | |
57 Node* GraphAssembler::ExternalConstant(ExternalReference ref) { | |
58 return jsgraph()->ExternalConstant(ref); | |
59 } | |
60 | |
61 Node* GraphAssembler::CEntryStubConstant(int result_size) { | |
62 return jsgraph()->CEntryStubConstant(result_size); | |
63 } | |
64 | |
65 Node* GraphAssembler::EmptyStringConstant() { | |
66 return jsgraph()->EmptyStringConstant(); | |
67 } | |
68 | |
69 Node* GraphAssembler::UndefinedConstant() { | |
70 return jsgraph()->UndefinedConstant(); | |
71 } | |
72 | |
73 Node* GraphAssembler::TheHoleConstant() { return jsgraph()->TheHoleConstant(); } | |
74 | |
75 Node* GraphAssembler::FixedArrayMapConstant() { | |
76 return jsgraph()->FixedArrayMapConstant(); | |
77 } | |
78 | |
79 #define PURE_UNOP_DEF(Name) \ | |
80 Node* GraphAssembler::Name(Node* input) { \ | |
81 return graph()->NewNode(machine()->Name(), input); \ | |
82 } | |
83 PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF) | |
84 #undef PURE_UNOP_DEF | |
85 | |
86 #define PURE_BINOP_DEF(Name) \ | |
87 Node* GraphAssembler::Name(Node* left, Node* right) { \ | |
88 return graph()->NewNode(machine()->Name(), left, right); \ | |
89 } | |
90 PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF) | |
91 #undef PURE_BINOP_DEF | |
92 | |
93 #define CHECKED_BINOP_DEF(Name) \ | |
94 Node* GraphAssembler::Name(Node* left, Node* right) { \ | |
95 return graph()->NewNode(machine()->Name(), left, right, current_control_); \ | |
96 } | |
97 CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF) | |
98 #undef CHECKED_BINOP_DEF | |
99 | |
100 Node* GraphAssembler::Float64RoundDown(Node* value) { | |
101 if (machine()->Float64RoundDown().IsSupported()) { | |
102 return graph()->NewNode(machine()->Float64RoundDown().op(), value); | |
103 } | |
104 return nullptr; | |
105 } | |
106 | |
107 Node* GraphAssembler::Projection(int index, Node* value) { | |
108 return graph()->NewNode(common()->Projection(index), value, current_control_); | |
109 } | |
110 | |
111 Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) { | |
112 return current_effect_ = | |
113 graph()->NewNode(simplified()->Allocate(NOT_TENURED), size, | |
114 current_effect_, current_control_); | |
115 } | |
116 | |
117 Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) { | |
118 return current_effect_ = | |
119 graph()->NewNode(simplified()->LoadField(access), object, | |
120 current_effect_, current_control_); | |
121 } | |
122 | |
123 Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object, | |
124 Node* index) { | |
125 return current_effect_ = | |
126 graph()->NewNode(simplified()->LoadElement(access), object, index, | |
127 current_effect_, current_control_); | |
128 } | |
129 | |
130 Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object, | |
131 Node* value) { | |
132 return current_effect_ = | |
133 graph()->NewNode(simplified()->StoreField(access), object, value, | |
134 current_effect_, current_control_); | |
135 } | |
136 | |
137 Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object, | |
138 Node* index, Node* value) { | |
139 return current_effect_ = | |
140 graph()->NewNode(simplified()->StoreElement(access), object, index, | |
141 value, current_effect_, current_control_); | |
142 } | |
143 | |
144 Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset, | |
145 Node* value) { | |
146 return current_effect_ = | |
147 graph()->NewNode(machine()->Store(rep), object, offset, value, | |
148 current_effect_, current_control_); | |
149 } | |
150 | |
151 Node* GraphAssembler::Retain(Node* buffer) { | |
152 return current_effect_ = | |
153 graph()->NewNode(common()->Retain(), buffer, current_effect_); | |
154 } | |
155 | |
156 Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) { | |
157 return current_effect_ = | |
158 graph()->NewNode(machine()->UnsafePointerAdd(), base, external, | |
159 current_effect_, current_control_); | |
160 } | |
161 | |
162 Node* GraphAssembler::ToNumber(Node* value) { | |
163 return current_effect_ = graph()->NewNode( | |
164 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, | |
165 jsgraph()->NoContextConstant(), current_effect_); | |
166 } | |
167 | |
168 Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition, | |
169 Node* frame_state) { | |
170 return current_control_ = current_effect_ = | |
171 graph()->NewNode(common()->DeoptimizeIf(reason), condition, | |
172 frame_state, current_effect_, current_control_); | |
173 } | |
174 | |
175 Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition, | |
176 Node* frame_state) { | |
177 return current_control_ = current_effect_ = | |
178 graph()->NewNode(common()->DeoptimizeUnless(reason), condition, | |
179 frame_state, current_effect_, current_control_); | |
180 } | |
181 | |
182 void GraphAssembler::Branch(Node* condition, | |
183 GraphAssemblerStaticLabel<1>* if_true, | |
184 GraphAssemblerStaticLabel<1>* if_false) { | |
185 DCHECK_NOT_NULL(current_control_); | |
186 | |
187 BranchHint hint = BranchHint::kNone; | |
188 if (if_true->IsDeferred() != if_false->IsDeferred()) { | |
189 hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse; | |
190 } | |
191 | |
192 Node* branch = | |
193 graph()->NewNode(common()->Branch(hint), condition, current_control_); | |
194 | |
195 current_control_ = graph()->NewNode(common()->IfTrue(), branch); | |
196 MergeState(if_true); | |
197 | |
198 current_control_ = graph()->NewNode(common()->IfFalse(), branch); | |
199 MergeState(if_false); | |
200 | |
201 current_control_ = nullptr; | |
202 current_effect_ = nullptr; | |
203 } | |
204 | |
205 // Extractors (should be only used when destructing the assembler. | |
206 Node* GraphAssembler::ExtractCurrentControl() { | |
207 Node* result = current_control_; | |
208 current_control_ = nullptr; | |
209 return result; | |
210 } | |
211 | |
212 Node* GraphAssembler::ExtractCurrentEffect() { | |
213 Node* result = current_effect_; | |
214 current_effect_ = nullptr; | |
215 return result; | |
216 } | |
217 | |
218 void GraphAssembler::Reset(Node* effect, Node* control) { | |
219 current_effect_ = effect; | |
220 current_control_ = control; | |
221 } | |
222 | |
223 Operator const* GraphAssembler::ToNumberOperator() { | |
224 if (!to_number_operator_.is_set()) { | |
225 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate()); | |
226 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | |
227 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
228 jsgraph()->isolate(), graph()->zone(), callable.descriptor(), 0, flags, | |
229 Operator::kEliminatable); | |
230 to_number_operator_.set(common()->Call(desc)); | |
231 } | |
232 return to_number_operator_.get(); | |
233 } | |
234 | |
235 Node* GraphAssemblerLabel::PhiAt(size_t index) { | |
236 DCHECK(IsBound()); | |
237 return GetBindingsPtrFor(index)[0]; | |
238 } | |
239 | |
240 GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred, | |
241 size_t merge_count, size_t var_count, | |
242 MachineRepresentation* representations, | |
243 Zone* zone) | |
244 : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred), | |
245 max_merge_count_(merge_count), | |
246 var_count_(var_count) { | |
247 effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1); | |
248 for (size_t i = 0; i < MaxMergeCount() + 1; i++) { | |
249 effects_[i] = nullptr; | |
250 } | |
251 | |
252 controls_ = zone->NewArray<Node*>(MaxMergeCount()); | |
253 for (size_t i = 0; i < MaxMergeCount(); i++) { | |
254 controls_[i] = nullptr; | |
255 } | |
256 | |
257 size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1; | |
258 bindings_ = zone->NewArray<Node*>(num_bindings); | |
259 for (size_t i = 0; i < num_bindings; i++) { | |
260 bindings_[i] = nullptr; | |
261 } | |
262 | |
263 representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1); | |
264 for (size_t i = 0; i < PhiCount(); i++) { | |
265 representations_[i] = representations[i]; | |
266 } | |
267 } | |
268 | |
269 GraphAssemblerLabel::~GraphAssemblerLabel() { | |
270 DCHECK(IsBound() || MergedCount() == 0); | |
271 } | |
272 | |
273 Node** GraphAssemblerLabel::GetBindingsPtrFor(size_t phi_index) { | |
Igor Sheludko
2017/01/02 13:23:27
Please add bounds checks here and in other getters
Jarin
2017/01/03 09:27:55
Done.
| |
274 return &bindings_[phi_index * (MaxMergeCount() + 1)]; | |
275 } | |
276 | |
277 MachineRepresentation GraphAssemblerLabel::GetRepresentationFor( | |
278 size_t phi_index) { | |
279 return representations_[phi_index]; | |
280 } | |
281 | |
282 Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; } | |
283 | |
284 Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; } | |
285 | |
286 } // namespace compiler | |
287 } // namespace internal | |
288 } // namespace v8 | |
OLD | NEW |