• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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