Line data Source code
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/compiler/js-graph.h"
6 :
7 : #include "src/code-stubs.h"
8 : #include "src/compiler/node-properties.h"
9 : #include "src/compiler/typer.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace compiler {
15 :
16 : #define CACHED(name, expr) \
17 : cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr))
18 :
19 191139 : Node* JSGraph::AllocateInNewSpaceStubConstant() {
20 264244 : return CACHED(kAllocateInNewSpaceStubConstant,
21 : HeapConstant(BUILTIN_CODE(isolate(), AllocateInNewSpace)));
22 : }
23 :
24 54 : Node* JSGraph::AllocateInOldSpaceStubConstant() {
25 72 : return CACHED(kAllocateInOldSpaceStubConstant,
26 : HeapConstant(BUILTIN_CODE(isolate(), AllocateInOldSpace)));
27 : }
28 :
29 886786 : Node* JSGraph::ArrayConstructorStubConstant() {
30 1330168 : return CACHED(kArrayConstructorStubConstant,
31 : HeapConstant(ArrayConstructorStub(isolate()).GetCode()));
32 : }
33 :
34 10335 : Node* JSGraph::ToNumberBuiltinConstant() {
35 11352 : return CACHED(kToNumberBuiltinConstant,
36 : HeapConstant(BUILTIN_CODE(isolate(), ToNumber)));
37 : }
38 :
39 1889584 : Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
40 891789 : ArgvMode argv_mode, bool builtin_exit_frame) {
41 1889584 : if (save_doubles == kDontSaveFPRegs && argv_mode == kArgvOnStack) {
42 : DCHECK(result_size >= 1 && result_size <= 3);
43 1889584 : if (!builtin_exit_frame) {
44 : CachedNode key;
45 1881797 : if (result_size == 1) {
46 : key = kCEntryStub1Constant;
47 443774 : } else if (result_size == 2) {
48 : key = kCEntryStub2Constant;
49 : } else {
50 : DCHECK_EQ(3, result_size);
51 : key = kCEntryStub3Constant;
52 : }
53 3655325 : return CACHED(
54 : key, HeapConstant(CEntryStub(isolate(), result_size, save_doubles,
55 : argv_mode, builtin_exit_frame)
56 : .GetCode()));
57 : }
58 : CachedNode key = builtin_exit_frame
59 : ? kCEntryStub1WithBuiltinExitFrameConstant
60 7787 : : kCEntryStub1Constant;
61 17837 : return CACHED(key,
62 : HeapConstant(CEntryStub(isolate(), result_size, save_doubles,
63 : argv_mode, builtin_exit_frame)
64 : .GetCode()));
65 : }
66 : CEntryStub stub(isolate(), result_size, save_doubles, argv_mode,
67 : builtin_exit_frame);
68 0 : return HeapConstant(stub.GetCode());
69 : }
70 :
71 63392 : Node* JSGraph::EmptyFixedArrayConstant() {
72 93612 : return CACHED(kEmptyFixedArrayConstant,
73 : HeapConstant(factory()->empty_fixed_array()));
74 : }
75 :
76 55352 : Node* JSGraph::EmptyStringConstant() {
77 80208 : return CACHED(kEmptyStringConstant, HeapConstant(factory()->empty_string()));
78 : }
79 :
80 673 : Node* JSGraph::FixedArrayMapConstant() {
81 1249 : return CACHED(kFixedArrayMapConstant,
82 : HeapConstant(factory()->fixed_array_map()));
83 : }
84 :
85 236 : Node* JSGraph::PropertyArrayMapConstant() {
86 453 : return CACHED(kPropertyArrayMapConstant,
87 : HeapConstant(factory()->property_array_map()));
88 : }
89 :
90 32 : Node* JSGraph::FixedDoubleArrayMapConstant() {
91 63 : return CACHED(kFixedDoubleArrayMapConstant,
92 : HeapConstant(factory()->fixed_double_array_map()));
93 : }
94 :
95 132782 : Node* JSGraph::HeapNumberMapConstant() {
96 193940 : return CACHED(kHeapNumberMapConstant,
97 : HeapConstant(factory()->heap_number_map()));
98 : }
99 :
100 16686423 : Node* JSGraph::OptimizedOutConstant() {
101 17129803 : return CACHED(kOptimizedOutConstant,
102 : HeapConstant(factory()->optimized_out()));
103 : }
104 :
105 35765 : Node* JSGraph::StaleRegisterConstant() {
106 37297 : return CACHED(kStaleRegisterConstant,
107 : HeapConstant(factory()->stale_register()));
108 : }
109 :
110 1855131 : Node* JSGraph::UndefinedConstant() {
111 2468688 : return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
112 : }
113 :
114 :
115 275006 : Node* JSGraph::TheHoleConstant() {
116 372990 : return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
117 : }
118 :
119 :
120 982061 : Node* JSGraph::TrueConstant() {
121 1425525 : return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
122 : }
123 :
124 :
125 961670 : Node* JSGraph::FalseConstant() {
126 1405182 : return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
127 : }
128 :
129 :
130 21753 : Node* JSGraph::NullConstant() {
131 35530 : return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
132 : }
133 :
134 :
135 1100671 : Node* JSGraph::ZeroConstant() {
136 1387617 : return CACHED(kZeroConstant, NumberConstant(0.0));
137 : }
138 :
139 214655 : Node* JSGraph::OneConstant() {
140 507896 : return CACHED(kOneConstant, NumberConstant(1.0));
141 : }
142 :
143 8 : Node* JSGraph::MinusOneConstant() {
144 8 : return CACHED(kMinusOneConstant, NumberConstant(-1.0));
145 : }
146 :
147 2023 : Node* JSGraph::NaNConstant() {
148 2023 : return CACHED(kNaNConstant,
149 : NumberConstant(std::numeric_limits<double>::quiet_NaN()));
150 : }
151 :
152 :
153 28846663 : Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
154 12169024 : Node** loc = cache_.FindHeapConstant(value);
155 12169062 : if (*loc == nullptr) {
156 16677576 : *loc = graph()->NewNode(common()->HeapConstant(value));
157 : }
158 12169018 : return *loc;
159 : }
160 :
161 :
162 10998991 : Node* JSGraph::Constant(Handle<Object> value) {
163 : // Dereference the handle to determine if a number constant or other
164 : // canonicalized node can be used.
165 1971758 : if (value->IsNumber()) {
166 119416 : return Constant(value->Number());
167 1852342 : } else if (value->IsUndefined(isolate())) {
168 18982 : return UndefinedConstant();
169 1833360 : } else if (value->IsTrue(isolate())) {
170 32593 : return TrueConstant();
171 1800767 : } else if (value->IsFalse(isolate())) {
172 30258 : return FalseConstant();
173 1770509 : } else if (value->IsNull(isolate())) {
174 254 : return NullConstant();
175 1770255 : } else if (value->IsTheHole(isolate())) {
176 6 : return TheHoleConstant();
177 : } else {
178 1770249 : return HeapConstant(Handle<HeapObject>::cast(value));
179 : }
180 : }
181 :
182 :
183 388160 : Node* JSGraph::Constant(double value) {
184 411207 : if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
185 370934 : if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
186 359292 : return NumberConstant(value);
187 : }
188 :
189 :
190 3615224 : Node* JSGraph::Constant(int32_t value) {
191 3879083 : if (value == 0) return ZeroConstant();
192 3638655 : if (value == 1) return OneConstant();
193 3064077 : return NumberConstant(value);
194 : }
195 :
196 6258 : Node* JSGraph::Constant(uint32_t value) {
197 6299 : if (value == 0) return ZeroConstant();
198 6348 : if (value == 1) return OneConstant();
199 6086 : return NumberConstant(value);
200 : }
201 :
202 17106383 : Node* JSGraph::Int32Constant(int32_t value) {
203 : Node** loc = cache_.FindInt32Constant(value);
204 8680314 : if (*loc == nullptr) {
205 8426209 : *loc = graph()->NewNode(common()->Int32Constant(value));
206 : }
207 8680339 : return *loc;
208 : }
209 :
210 :
211 10729219 : Node* JSGraph::Int64Constant(int64_t value) {
212 : Node** loc = cache_.FindInt64Constant(value);
213 6161108 : if (*loc == nullptr) {
214 4568128 : *loc = graph()->NewNode(common()->Int64Constant(value));
215 : }
216 6161122 : return *loc;
217 : }
218 :
219 6968 : Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
220 : Node** loc = cache_.FindRelocatableInt32Constant(
221 2322 : value, static_cast<RelocInfoMode>(rmode));
222 2323 : if (*loc == nullptr) {
223 4646 : *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
224 : }
225 2323 : return *loc;
226 : }
227 :
228 494465 : Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
229 : Node** loc = cache_.FindRelocatableInt64Constant(
230 164821 : value, static_cast<RelocInfoMode>(rmode));
231 164822 : if (*loc == nullptr) {
232 329644 : *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
233 : }
234 164822 : return *loc;
235 : }
236 :
237 164821 : Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
238 : RelocInfo::Mode rmode) {
239 : return kPointerSize == 8
240 : ? RelocatableInt64Constant(value, rmode)
241 164821 : : RelocatableInt32Constant(static_cast<int>(value), rmode);
242 : }
243 :
244 11261013 : Node* JSGraph::NumberConstant(double value) {
245 : Node** loc = cache_.FindNumberConstant(value);
246 4208227 : if (*loc == nullptr) {
247 7052789 : *loc = graph()->NewNode(common()->NumberConstant(value));
248 : }
249 4208230 : return *loc;
250 : }
251 :
252 :
253 413040 : Node* JSGraph::Float32Constant(float value) {
254 : Node** loc = cache_.FindFloat32Constant(value);
255 148667 : if (*loc == nullptr) {
256 264373 : *loc = graph()->NewNode(common()->Float32Constant(value));
257 : }
258 148670 : return *loc;
259 : }
260 :
261 :
262 1227272 : Node* JSGraph::Float64Constant(double value) {
263 : Node** loc = cache_.FindFloat64Constant(value);
264 585402 : if (*loc == nullptr) {
265 641874 : *loc = graph()->NewNode(common()->Float64Constant(value));
266 : }
267 585400 : return *loc;
268 : }
269 :
270 5132 : Node* JSGraph::PointerConstant(intptr_t value) {
271 : Node** loc = cache_.FindPointerConstant(value);
272 3344 : if (*loc == nullptr) {
273 1788 : *loc = graph()->NewNode(common()->PointerConstant(value));
274 : }
275 3344 : return *loc;
276 : }
277 :
278 4807184 : Node* JSGraph::ExternalConstant(ExternalReference reference) {
279 2014535 : Node** loc = cache_.FindExternalConstant(reference);
280 2014586 : if (*loc == nullptr) {
281 2792643 : *loc = graph()->NewNode(common()->ExternalConstant(reference));
282 : }
283 2014593 : return *loc;
284 : }
285 :
286 :
287 0 : Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
288 0 : return ExternalConstant(ExternalReference(function_id, isolate()));
289 : }
290 :
291 20090 : Node* JSGraph::EmptyStateValues() {
292 20090 : return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(
293 : 0, SparseInputMask::Dense())));
294 : }
295 :
296 5151860 : Node* JSGraph::SingleDeadTypedStateValues() {
297 5151860 : return CACHED(kSingleDeadTypedStateValues,
298 : graph()->NewNode(common()->TypedStateValues(
299 : new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
300 : ZoneVector<MachineType>(0, graph()->zone()),
301 : SparseInputMask(SparseInputMask::kEndMarker << 1))));
302 : }
303 :
304 15195150 : Node* JSGraph::Dead() {
305 15195151 : return CACHED(kDead, graph()->NewNode(common()->Dead()));
306 : }
307 :
308 :
309 3328665 : void JSGraph::GetCachedNodes(NodeVector* nodes) {
310 3328665 : cache_.GetCachedNodes(nodes);
311 96530982 : for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
312 93202271 : if (Node* node = cached_nodes_[i]) {
313 27515981 : if (!node->IsDead()) nodes->push_back(node);
314 : }
315 : }
316 3328711 : }
317 :
318 : } // namespace compiler
319 : } // namespace internal
320 : } // namespace v8
|