blob: 98ca7aa3c3f831dc36bb59e569ebc772447dedfc [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
17
Emily Bernierd0a1eb72015-03-24 16:35:39 -040018Node* JSGraph::CEntryStubConstant(int result_size) {
19 if (result_size == 1) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 return CACHED(kCEntryStubConstant,
21 HeapConstant(CEntryStub(isolate(), 1).GetCode()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023 return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
24}
Emily Bernierd0a1eb72015-03-24 16:35:39 -040025
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026
27Node* JSGraph::EmptyFixedArrayConstant() {
28 return CACHED(kEmptyFixedArrayConstant,
29 HeapConstant(factory()->empty_fixed_array()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030}
31
Ben Murdochda12d292016-06-02 14:46:10 +010032Node* JSGraph::OptimizedOutConstant() {
33 return CACHED(kOptimizedOutConstant,
34 HeapConstant(factory()->optimized_out()));
35}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036
37Node* JSGraph::UndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039}
40
41
42Node* JSGraph::TheHoleConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044}
45
46
47Node* JSGraph::TrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049}
50
51
52Node* JSGraph::FalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054}
55
56
57Node* JSGraph::NullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058 return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059}
60
61
62Node* JSGraph::ZeroConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063 return CACHED(kZeroConstant, NumberConstant(0.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064}
65
66
67Node* JSGraph::OneConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 return CACHED(kOneConstant, NumberConstant(1.0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069}
70
71
72Node* JSGraph::NaNConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 return CACHED(kNaNConstant,
74 NumberConstant(std::numeric_limits<double>::quiet_NaN()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075}
76
77
Emily Bernierd0a1eb72015-03-24 16:35:39 -040078Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 if (value->IsConsString()) {
80 value = String::Flatten(Handle<String>::cast(value), TENURED);
81 }
82 Node** loc = cache_.FindHeapConstant(value);
83 if (*loc == nullptr) {
84 *loc = graph()->NewNode(common()->HeapConstant(value));
85 }
86 return *loc;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087}
88
89
90Node* JSGraph::Constant(Handle<Object> value) {
91 // Dereference the handle to determine if a number constant or other
92 // canonicalized node can be used.
93 if (value->IsNumber()) {
94 return Constant(value->Number());
95 } else if (value->IsUndefined()) {
96 return UndefinedConstant();
97 } else if (value->IsTrue()) {
98 return TrueConstant();
99 } else if (value->IsFalse()) {
100 return FalseConstant();
101 } else if (value->IsNull()) {
102 return NullConstant();
103 } else if (value->IsTheHole()) {
104 return TheHoleConstant();
105 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106 return HeapConstant(Handle<HeapObject>::cast(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 }
108}
109
110
111Node* JSGraph::Constant(double value) {
112 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
113 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
114 return NumberConstant(value);
115}
116
117
118Node* JSGraph::Constant(int32_t value) {
119 if (value == 0) return ZeroConstant();
120 if (value == 1) return OneConstant();
121 return NumberConstant(value);
122}
123
124
125Node* JSGraph::Int32Constant(int32_t value) {
126 Node** loc = cache_.FindInt32Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400128 *loc = graph()->NewNode(common()->Int32Constant(value));
129 }
130 return *loc;
131}
132
133
134Node* JSGraph::Int64Constant(int64_t value) {
135 Node** loc = cache_.FindInt64Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400137 *loc = graph()->NewNode(common()->Int64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138 }
139 return *loc;
140}
141
142
143Node* JSGraph::NumberConstant(double value) {
144 Node** loc = cache_.FindNumberConstant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400146 *loc = graph()->NewNode(common()->NumberConstant(value));
147 }
148 return *loc;
149}
150
151
152Node* JSGraph::Float32Constant(float value) {
153 Node** loc = cache_.FindFloat32Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400155 *loc = graph()->NewNode(common()->Float32Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156 }
157 return *loc;
158}
159
160
161Node* JSGraph::Float64Constant(double value) {
162 Node** loc = cache_.FindFloat64Constant(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400164 *loc = graph()->NewNode(common()->Float64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165 }
166 return *loc;
167}
168
169
170Node* JSGraph::ExternalConstant(ExternalReference reference) {
171 Node** loc = cache_.FindExternalConstant(reference);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 if (*loc == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 *loc = graph()->NewNode(common()->ExternalConstant(reference));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000174 }
175 return *loc;
176}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400177
178
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
180 return ExternalConstant(ExternalReference(function_id, isolate()));
181}
182
183
184Node* JSGraph::EmptyFrameState() {
185 Node* empty_frame_state = cached_nodes_[kEmptyFrameState];
186 if (!empty_frame_state || empty_frame_state->IsDead()) {
187 Node* state_values = graph()->NewNode(common()->StateValues(0));
188 empty_frame_state = graph()->NewNode(
189 common()->FrameState(BailoutId::None(),
190 OutputFrameStateCombine::Ignore(), nullptr),
191 state_values, state_values, state_values, NoContextConstant(),
192 UndefinedConstant(), graph()->start());
193 cached_nodes_[kEmptyFrameState] = empty_frame_state;
194 }
195 return empty_frame_state;
196}
197
198
199Node* JSGraph::Dead() {
200 return CACHED(kDead, graph()->NewNode(common()->Dead()));
201}
202
203
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400204void JSGraph::GetCachedNodes(NodeVector* nodes) {
205 cache_.GetCachedNodes(nodes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
207 if (Node* node = cached_nodes_[i]) {
208 if (!node->IsDead()) nodes->push_back(node);
209 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400210 }
211}
212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213} // namespace compiler
214} // namespace internal
215} // namespace v8