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/code-stubs.h"
6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/node-properties.h"
8 #include "src/compiler/typer.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 #define CACHED(name, expr) \
15 cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr))
16
AllocateInNewSpaceStubConstant()17 Node* JSGraph::AllocateInNewSpaceStubConstant() {
18 return CACHED(kAllocateInNewSpaceStubConstant,
19 HeapConstant(isolate()->builtins()->AllocateInNewSpace()));
20 }
21
AllocateInOldSpaceStubConstant()22 Node* JSGraph::AllocateInOldSpaceStubConstant() {
23 return CACHED(kAllocateInOldSpaceStubConstant,
24 HeapConstant(isolate()->builtins()->AllocateInOldSpace()));
25 }
26
ToNumberBuiltinConstant()27 Node* JSGraph::ToNumberBuiltinConstant() {
28 return CACHED(kToNumberBuiltinConstant,
29 HeapConstant(isolate()->builtins()->ToNumber()));
30 }
31
CEntryStubConstant(int result_size)32 Node* JSGraph::CEntryStubConstant(int result_size) {
33 if (result_size == 1) {
34 return CACHED(kCEntryStubConstant,
35 HeapConstant(CEntryStub(isolate(), 1).GetCode()));
36 }
37 return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
38 }
39
40
EmptyFixedArrayConstant()41 Node* JSGraph::EmptyFixedArrayConstant() {
42 return CACHED(kEmptyFixedArrayConstant,
43 HeapConstant(factory()->empty_fixed_array()));
44 }
45
EmptyLiteralsArrayConstant()46 Node* JSGraph::EmptyLiteralsArrayConstant() {
47 return CACHED(kEmptyLiteralsArrayConstant,
48 HeapConstant(factory()->empty_literals_array()));
49 }
50
HeapNumberMapConstant()51 Node* JSGraph::HeapNumberMapConstant() {
52 return CACHED(kHeapNumberMapConstant,
53 HeapConstant(factory()->heap_number_map()));
54 }
55
OptimizedOutConstant()56 Node* JSGraph::OptimizedOutConstant() {
57 return CACHED(kOptimizedOutConstant,
58 HeapConstant(factory()->optimized_out()));
59 }
60
StaleRegisterConstant()61 Node* JSGraph::StaleRegisterConstant() {
62 return CACHED(kStaleRegisterConstant,
63 HeapConstant(factory()->stale_register()));
64 }
65
UndefinedConstant()66 Node* JSGraph::UndefinedConstant() {
67 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
68 }
69
70
TheHoleConstant()71 Node* JSGraph::TheHoleConstant() {
72 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
73 }
74
75
TrueConstant()76 Node* JSGraph::TrueConstant() {
77 return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
78 }
79
80
FalseConstant()81 Node* JSGraph::FalseConstant() {
82 return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
83 }
84
85
NullConstant()86 Node* JSGraph::NullConstant() {
87 return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
88 }
89
90
ZeroConstant()91 Node* JSGraph::ZeroConstant() {
92 return CACHED(kZeroConstant, NumberConstant(0.0));
93 }
94
95
OneConstant()96 Node* JSGraph::OneConstant() {
97 return CACHED(kOneConstant, NumberConstant(1.0));
98 }
99
100
NaNConstant()101 Node* JSGraph::NaNConstant() {
102 return CACHED(kNaNConstant,
103 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
104 }
105
106
HeapConstant(Handle<HeapObject> value)107 Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
108 Node** loc = cache_.FindHeapConstant(value);
109 if (*loc == nullptr) {
110 *loc = graph()->NewNode(common()->HeapConstant(value));
111 }
112 return *loc;
113 }
114
115
Constant(Handle<Object> value)116 Node* JSGraph::Constant(Handle<Object> value) {
117 // Dereference the handle to determine if a number constant or other
118 // canonicalized node can be used.
119 if (value->IsNumber()) {
120 return Constant(value->Number());
121 } else if (value->IsUndefined(isolate())) {
122 return UndefinedConstant();
123 } else if (value->IsTrue(isolate())) {
124 return TrueConstant();
125 } else if (value->IsFalse(isolate())) {
126 return FalseConstant();
127 } else if (value->IsNull(isolate())) {
128 return NullConstant();
129 } else if (value->IsTheHole(isolate())) {
130 return TheHoleConstant();
131 } else {
132 return HeapConstant(Handle<HeapObject>::cast(value));
133 }
134 }
135
136
Constant(double value)137 Node* JSGraph::Constant(double value) {
138 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
139 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
140 return NumberConstant(value);
141 }
142
143
Constant(int32_t value)144 Node* JSGraph::Constant(int32_t value) {
145 if (value == 0) return ZeroConstant();
146 if (value == 1) return OneConstant();
147 return NumberConstant(value);
148 }
149
150
Int32Constant(int32_t value)151 Node* JSGraph::Int32Constant(int32_t value) {
152 Node** loc = cache_.FindInt32Constant(value);
153 if (*loc == nullptr) {
154 *loc = graph()->NewNode(common()->Int32Constant(value));
155 }
156 return *loc;
157 }
158
159
Int64Constant(int64_t value)160 Node* JSGraph::Int64Constant(int64_t value) {
161 Node** loc = cache_.FindInt64Constant(value);
162 if (*loc == nullptr) {
163 *loc = graph()->NewNode(common()->Int64Constant(value));
164 }
165 return *loc;
166 }
167
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)168 Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
169 Node** loc = cache_.FindRelocatableInt32Constant(
170 value, static_cast<RelocInfoMode>(rmode));
171 if (*loc == nullptr) {
172 *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
173 }
174 return *loc;
175 }
176
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)177 Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
178 Node** loc = cache_.FindRelocatableInt64Constant(
179 value, static_cast<RelocInfoMode>(rmode));
180 if (*loc == nullptr) {
181 *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
182 }
183 return *loc;
184 }
185
RelocatableIntPtrConstant(intptr_t value,RelocInfo::Mode rmode)186 Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
187 RelocInfo::Mode rmode) {
188 return kPointerSize == 8
189 ? RelocatableInt64Constant(value, rmode)
190 : RelocatableInt32Constant(static_cast<int>(value), rmode);
191 }
192
NumberConstant(double value)193 Node* JSGraph::NumberConstant(double value) {
194 Node** loc = cache_.FindNumberConstant(value);
195 if (*loc == nullptr) {
196 *loc = graph()->NewNode(common()->NumberConstant(value));
197 }
198 return *loc;
199 }
200
201
Float32Constant(float value)202 Node* JSGraph::Float32Constant(float value) {
203 Node** loc = cache_.FindFloat32Constant(value);
204 if (*loc == nullptr) {
205 *loc = graph()->NewNode(common()->Float32Constant(value));
206 }
207 return *loc;
208 }
209
210
Float64Constant(double value)211 Node* JSGraph::Float64Constant(double value) {
212 Node** loc = cache_.FindFloat64Constant(value);
213 if (*loc == nullptr) {
214 *loc = graph()->NewNode(common()->Float64Constant(value));
215 }
216 return *loc;
217 }
218
219
ExternalConstant(ExternalReference reference)220 Node* JSGraph::ExternalConstant(ExternalReference reference) {
221 Node** loc = cache_.FindExternalConstant(reference);
222 if (*loc == nullptr) {
223 *loc = graph()->NewNode(common()->ExternalConstant(reference));
224 }
225 return *loc;
226 }
227
228
ExternalConstant(Runtime::FunctionId function_id)229 Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
230 return ExternalConstant(ExternalReference(function_id, isolate()));
231 }
232
EmptyStateValues()233 Node* JSGraph::EmptyStateValues() {
234 return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(0)));
235 }
236
Dead()237 Node* JSGraph::Dead() {
238 return CACHED(kDead, graph()->NewNode(common()->Dead()));
239 }
240
241
GetCachedNodes(NodeVector * nodes)242 void JSGraph::GetCachedNodes(NodeVector* nodes) {
243 cache_.GetCachedNodes(nodes);
244 for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
245 if (Node* node = cached_nodes_[i]) {
246 if (!node->IsDead()) nodes->push_back(node);
247 }
248 }
249 }
250
251 } // namespace compiler
252 } // namespace internal
253 } // namespace v8
254