blob: 229169f792432fbc52a388ca3e48aed7bc18153e [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 Bernierd0a1eb72015-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 Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Murdochc5610432016-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
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027Node* JSGraph::CEntryStubConstant(int result_size) {
28 if (result_size == 1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 return CACHED(kCEntryStubConstant,
30 HeapConstant(CEntryStub(isolate(), 1).GetCode()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
33}
Emily Bernierd0a1eb72015-03-24 16:35:39 -040034
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035
36Node* JSGraph::EmptyFixedArrayConstant() {
37 return CACHED(kEmptyFixedArrayConstant,
38 HeapConstant(factory()->empty_fixed_array()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039}
40
Ben Murdochc5610432016-08-08 18:44:38 +010041Node* JSGraph::HeapNumberMapConstant() {
42 return CACHED(kHeapNumberMapConstant,
43 HeapConstant(factory()->heap_number_map()));
44}
45
Ben Murdochda12d292016-06-02 14:46:10 +010046Node* JSGraph::OptimizedOutConstant() {
47 return CACHED(kOptimizedOutConstant,
48 HeapConstant(factory()->optimized_out()));
49}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050
Ben Murdochc5610432016-08-08 18:44:38 +010051Node* JSGraph::StaleRegisterConstant() {
52 return CACHED(kStaleRegisterConstant,
53 HeapConstant(factory()->stale_register()));
54}
55
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056Node* JSGraph::UndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058}
59
60
61Node* JSGraph::TheHoleConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063}
64
65
66Node* JSGraph::TrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068}
69
70
71Node* JSGraph::FalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072 return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073}
74
75
76Node* JSGraph::NullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000077 return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078}
79
80
81Node* JSGraph::ZeroConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 return CACHED(kZeroConstant, NumberConstant(0.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083}
84
85
86Node* JSGraph::OneConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 return CACHED(kOneConstant, NumberConstant(1.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088}
89
90
91Node* JSGraph::NaNConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 return CACHED(kNaNConstant,
93 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094}
95
96
Emily Bernierd0a1eb72015-03-24 16:35:39 -040097Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098 Node** loc = cache_.FindHeapConstant(value);
99 if (*loc == nullptr) {
100 *loc = graph()->NewNode(common()->HeapConstant(value));
101 }
102 return *loc;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103}
104
105
106Node* JSGraph::Constant(Handle<Object> value) {
107 // Dereference the handle to determine if a number constant or other
108 // canonicalized node can be used.
109 if (value->IsNumber()) {
110 return Constant(value->Number());
111 } else if (value->IsUndefined()) {
112 return UndefinedConstant();
113 } else if (value->IsTrue()) {
114 return TrueConstant();
115 } else if (value->IsFalse()) {
116 return FalseConstant();
117 } else if (value->IsNull()) {
118 return NullConstant();
119 } else if (value->IsTheHole()) {
120 return TheHoleConstant();
121 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400122 return HeapConstant(Handle<HeapObject>::cast(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 }
124}
125
126
127Node* JSGraph::Constant(double value) {
128 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
129 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
130 return NumberConstant(value);
131}
132
133
134Node* JSGraph::Constant(int32_t value) {
135 if (value == 0) return ZeroConstant();
136 if (value == 1) return OneConstant();
137 return NumberConstant(value);
138}
139
140
141Node* JSGraph::Int32Constant(int32_t value) {
142 Node** loc = cache_.FindInt32Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000143 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400144 *loc = graph()->NewNode(common()->Int32Constant(value));
145 }
146 return *loc;
147}
148
149
150Node* JSGraph::Int64Constant(int64_t value) {
151 Node** loc = cache_.FindInt64Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400153 *loc = graph()->NewNode(common()->Int64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154 }
155 return *loc;
156}
157
Ben Murdochc5610432016-08-08 18:44:38 +0100158Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
159 Node** loc = cache_.FindRelocatableInt32Constant(value);
160 if (*loc == nullptr) {
161 *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode));
162 }
163 return *loc;
164}
165
166Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
167 Node** loc = cache_.FindRelocatableInt64Constant(value);
168 if (*loc == nullptr) {
169 *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode));
170 }
171 return *loc;
172}
173
174Node* JSGraph::RelocatableIntPtrConstant(intptr_t value,
175 RelocInfo::Mode rmode) {
176 return kPointerSize == 8
177 ? RelocatableInt64Constant(value, rmode)
178 : RelocatableInt32Constant(static_cast<int>(value), rmode);
179}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180
181Node* JSGraph::NumberConstant(double value) {
182 Node** loc = cache_.FindNumberConstant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400184 *loc = graph()->NewNode(common()->NumberConstant(value));
185 }
186 return *loc;
187}
188
189
190Node* JSGraph::Float32Constant(float value) {
191 Node** loc = cache_.FindFloat32Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193 *loc = graph()->NewNode(common()->Float32Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000194 }
195 return *loc;
196}
197
198
199Node* JSGraph::Float64Constant(double value) {
200 Node** loc = cache_.FindFloat64Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400202 *loc = graph()->NewNode(common()->Float64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 }
204 return *loc;
205}
206
207
208Node* JSGraph::ExternalConstant(ExternalReference reference) {
209 Node** loc = cache_.FindExternalConstant(reference);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400211 *loc = graph()->NewNode(common()->ExternalConstant(reference));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 }
213 return *loc;
214}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215
216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
218 return ExternalConstant(ExternalReference(function_id, isolate()));
219}
220
221
222Node* JSGraph::EmptyFrameState() {
223 Node* empty_frame_state = cached_nodes_[kEmptyFrameState];
224 if (!empty_frame_state || empty_frame_state->IsDead()) {
225 Node* state_values = graph()->NewNode(common()->StateValues(0));
226 empty_frame_state = graph()->NewNode(
227 common()->FrameState(BailoutId::None(),
228 OutputFrameStateCombine::Ignore(), nullptr),
229 state_values, state_values, state_values, NoContextConstant(),
230 UndefinedConstant(), graph()->start());
231 cached_nodes_[kEmptyFrameState] = empty_frame_state;
232 }
233 return empty_frame_state;
234}
235
236
237Node* JSGraph::Dead() {
238 return CACHED(kDead, graph()->NewNode(common()->Dead()));
239}
240
241
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400242void JSGraph::GetCachedNodes(NodeVector* nodes) {
243 cache_.GetCachedNodes(nodes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244 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 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400248 }
249}
250
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000251} // namespace compiler
252} // namespace internal
253} // namespace v8