blob: cafd047e74781f9a2b5e72c4c7f4e1aed65ea5bb [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernier958fae72015-03-24 16:35:39 -04005#include "src/code-stubs.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006#include "src/compiler/js-graph.h"
Ben Murdoch014dc512016-03-22 12:00:34 +00007#include "src/compiler/node-properties.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/typer.h"
9
10namespace v8 {
11namespace internal {
12namespace compiler {
13
Ben Murdoch014dc512016-03-22 12:00:34 +000014#define CACHED(name, expr) \
15 cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr))
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016
Ben Murdochbcf72ee2016-08-08 18:44:38 +010017Node* JSGraph::AllocateInNewSpaceStubConstant() {
18 return CACHED(kAllocateInNewSpaceStubConstant,
19 HeapConstant(isolate()->builtins()->AllocateInNewSpace()));
20}
21
22Node* JSGraph::AllocateInOldSpaceStubConstant() {
23 return CACHED(kAllocateInOldSpaceStubConstant,
24 HeapConstant(isolate()->builtins()->AllocateInOldSpace()));
25}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026
Ben Murdoch13e2dad2016-09-16 13:49:30 +010027Node* JSGraph::ToNumberBuiltinConstant() {
28 return CACHED(kToNumberBuiltinConstant,
29 HeapConstant(isolate()->builtins()->ToNumber()));
30}
31
Ben Murdochf91f0612016-11-29 16:50:11 +000032Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
33 ArgvMode argv_mode, bool builtin_exit_frame) {
34 if (save_doubles == kDontSaveFPRegs && argv_mode == kArgvOnStack &&
35 result_size == 1) {
36 CachedNode key = builtin_exit_frame
37 ? kCEntryStubWithBuiltinExitFrameConstant
38 : kCEntryStubConstant;
39 return CACHED(key,
40 HeapConstant(CEntryStub(isolate(), result_size, save_doubles,
41 argv_mode, builtin_exit_frame)
42 .GetCode()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 }
Ben Murdochf91f0612016-11-29 16:50:11 +000044 CEntryStub stub(isolate(), result_size, save_doubles, argv_mode,
45 builtin_exit_frame);
46 return HeapConstant(stub.GetCode());
Ben Murdoch014dc512016-03-22 12:00:34 +000047}
Emily Bernier958fae72015-03-24 16:35:39 -040048
Ben Murdoch014dc512016-03-22 12:00:34 +000049Node* JSGraph::EmptyFixedArrayConstant() {
50 return CACHED(kEmptyFixedArrayConstant,
51 HeapConstant(factory()->empty_fixed_array()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052}
53
Ben Murdoch13e2dad2016-09-16 13:49:30 +010054Node* JSGraph::EmptyLiteralsArrayConstant() {
55 return CACHED(kEmptyLiteralsArrayConstant,
56 HeapConstant(factory()->empty_literals_array()));
57}
58
Ben Murdochf91f0612016-11-29 16:50:11 +000059Node* JSGraph::EmptyStringConstant() {
60 return CACHED(kEmptyStringConstant, HeapConstant(factory()->empty_string()));
61}
62
63Node* JSGraph::FixedArrayMapConstant() {
64 return CACHED(kFixedArrayMapConstant,
65 HeapConstant(factory()->fixed_array_map()));
66}
67
68Node* JSGraph::FixedDoubleArrayMapConstant() {
69 return CACHED(kFixedDoubleArrayMapConstant,
70 HeapConstant(factory()->fixed_double_array_map()));
71}
72
Ben Murdochbcf72ee2016-08-08 18:44:38 +010073Node* JSGraph::HeapNumberMapConstant() {
74 return CACHED(kHeapNumberMapConstant,
75 HeapConstant(factory()->heap_number_map()));
76}
77
Ben Murdoch3b9bc312016-06-02 14:46:10 +010078Node* JSGraph::OptimizedOutConstant() {
79 return CACHED(kOptimizedOutConstant,
80 HeapConstant(factory()->optimized_out()));
81}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082
Ben Murdochbcf72ee2016-08-08 18:44:38 +010083Node* JSGraph::StaleRegisterConstant() {
84 return CACHED(kStaleRegisterConstant,
85 HeapConstant(factory()->stale_register()));
86}
87
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088Node* JSGraph::UndefinedConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +000089 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090}
91
92
93Node* JSGraph::TheHoleConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +000094 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000095}
96
97
98Node* JSGraph::TrueConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +000099 return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100}
101
102
103Node* JSGraph::FalseConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +0000104 return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105}
106
107
108Node* JSGraph::NullConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +0000109 return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110}
111
112
113Node* JSGraph::ZeroConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +0000114 return CACHED(kZeroConstant, NumberConstant(0.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115}
116
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117Node* JSGraph::OneConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +0000118 return CACHED(kOneConstant, NumberConstant(1.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119}
120
121
122Node* JSGraph::NaNConstant() {
Ben Murdoch014dc512016-03-22 12:00:34 +0000123 return CACHED(kNaNConstant,
124 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125}
126
127
Emily Bernier958fae72015-03-24 16:35:39 -0400128Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000129 Node** loc = cache_.FindHeapConstant(value);
130 if (*loc == nullptr) {
131 *loc = graph()->NewNode(common()->HeapConstant(value));
132 }
133 return *loc;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134}
135
136
137Node* JSGraph::Constant(Handle<Object> value) {
138 // Dereference the handle to determine if a number constant or other
139 // canonicalized node can be used.
140 if (value->IsNumber()) {
141 return Constant(value->Number());
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100142 } else if (value->IsUndefined(isolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 return UndefinedConstant();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100144 } else if (value->IsTrue(isolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 return TrueConstant();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100146 } else if (value->IsFalse(isolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 return FalseConstant();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100148 } else if (value->IsNull(isolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 return NullConstant();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100150 } else if (value->IsTheHole(isolate())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151 return TheHoleConstant();
152 } else {
Emily Bernier958fae72015-03-24 16:35:39 -0400153 return HeapConstant(Handle<HeapObject>::cast(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154 }
155}
156
157
158Node* JSGraph::Constant(double value) {
159 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
160 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
161 return NumberConstant(value);
162}
163
164
165Node* JSGraph::Constant(int32_t value) {
166 if (value == 0) return ZeroConstant();
167 if (value == 1) return OneConstant();
168 return NumberConstant(value);
169}
170
Ben Murdochf91f0612016-11-29 16:50:11 +0000171Node* JSGraph::Constant(uint32_t value) {
172 if (value == 0) return ZeroConstant();
173 if (value == 1) return OneConstant();
174 return NumberConstant(value);
175}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176
177Node* JSGraph::Int32Constant(int32_t value) {
178 Node** loc = cache_.FindInt32Constant(value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000179 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400180 *loc = graph()->NewNode(common()->Int32Constant(value));
181 }
182 return *loc;
183}
184
185
186Node* JSGraph::Int64Constant(int64_t value) {
187 Node** loc = cache_.FindInt64Constant(value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000188 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400189 *loc = graph()->NewNode(common()->Int64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 }
191 return *loc;
192}
193
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100194Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100195 Node** loc = cache_.FindRelocatableInt32Constant(
196 value, static_cast<RelocInfoMode>(rmode));
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100197 if (*loc == nullptr) {
198 *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
199 }
200 return *loc;
201}
202
203Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100204 Node** loc = cache_.FindRelocatableInt64Constant(
205 value, static_cast<RelocInfoMode>(rmode));
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100206 if (*loc == nullptr) {
207 *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
208 }
209 return *loc;
210}
211
212Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
213 RelocInfo::Mode rmode) {
214 return kPointerSize == 8
215 ? RelocatableInt64Constant(value, rmode)
216 : RelocatableInt32Constant(static_cast<int>(value), rmode);
217}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218
219Node* JSGraph::NumberConstant(double value) {
220 Node** loc = cache_.FindNumberConstant(value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000221 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400222 *loc = graph()->NewNode(common()->NumberConstant(value));
223 }
224 return *loc;
225}
226
227
228Node* JSGraph::Float32Constant(float value) {
229 Node** loc = cache_.FindFloat32Constant(value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000230 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400231 *loc = graph()->NewNode(common()->Float32Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000232 }
233 return *loc;
234}
235
236
237Node* JSGraph::Float64Constant(double value) {
238 Node** loc = cache_.FindFloat64Constant(value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000239 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400240 *loc = graph()->NewNode(common()->Float64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 }
242 return *loc;
243}
244
245
246Node* JSGraph::ExternalConstant(ExternalReference reference) {
247 Node** loc = cache_.FindExternalConstant(reference);
Ben Murdoch014dc512016-03-22 12:00:34 +0000248 if (*loc == nullptr) {
Emily Bernier958fae72015-03-24 16:35:39 -0400249 *loc = graph()->NewNode(common()->ExternalConstant(reference));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 }
251 return *loc;
252}
Emily Bernier958fae72015-03-24 16:35:39 -0400253
254
Ben Murdoch014dc512016-03-22 12:00:34 +0000255Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
256 return ExternalConstant(ExternalReference(function_id, isolate()));
257}
258
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100259Node* JSGraph::EmptyStateValues() {
260 return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(0)));
Ben Murdoch014dc512016-03-22 12:00:34 +0000261}
262
Ben Murdoch014dc512016-03-22 12:00:34 +0000263Node* JSGraph::Dead() {
264 return CACHED(kDead, graph()->NewNode(common()->Dead()));
265}
266
267
Emily Bernier958fae72015-03-24 16:35:39 -0400268void JSGraph::GetCachedNodes(NodeVector* nodes) {
269 cache_.GetCachedNodes(nodes);
Ben Murdoch014dc512016-03-22 12:00:34 +0000270 for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
271 if (Node* node = cached_nodes_[i]) {
272 if (!node->IsDead()) nodes->push_back(node);
273 }
Emily Bernier958fae72015-03-24 16:35:39 -0400274 }
275}
276
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277} // namespace compiler
278} // namespace internal
279} // namespace v8