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/compiler/js-graph.h"
6
7 #include "src/codegen/code-factory.h"
8 #include "src/compiler/node-properties.h"
9 #include "src/compiler/typer.h"
10 #include "src/objects/objects-inl.h"
11
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15
16 #define GET_CACHED_FIELD(ptr, expr) (*(ptr)) ? *(ptr) : (*(ptr) = (expr))
17
18 #define DEFINE_GETTER(name, expr) \
19 Node* JSGraph::name() { return GET_CACHED_FIELD(&name##_, expr); }
20
CEntryStubConstant(int result_size,SaveFPRegsMode save_doubles,ArgvMode argv_mode,bool builtin_exit_frame)21 Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
22 ArgvMode argv_mode, bool builtin_exit_frame) {
23 if (save_doubles == SaveFPRegsMode::kIgnore &&
24 argv_mode == ArgvMode::kStack) {
25 DCHECK(result_size >= 1 && result_size <= 3);
26 if (!builtin_exit_frame) {
27 Node** ptr = nullptr;
28 if (result_size == 1) {
29 ptr = &CEntryStub1Constant_;
30 } else if (result_size == 2) {
31 ptr = &CEntryStub2Constant_;
32 } else {
33 DCHECK_EQ(3, result_size);
34 ptr = &CEntryStub3Constant_;
35 }
36 return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
37 isolate(), result_size, save_doubles,
38 argv_mode, builtin_exit_frame)));
39 }
40 Node** ptr = builtin_exit_frame ? &CEntryStub1WithBuiltinExitFrameConstant_
41 : &CEntryStub1Constant_;
42 return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
43 isolate(), result_size, save_doubles,
44 argv_mode, builtin_exit_frame)));
45 }
46 return HeapConstant(CodeFactory::CEntry(isolate(), result_size, save_doubles,
47 argv_mode, builtin_exit_frame));
48 }
49
Constant(const ObjectRef & ref)50 Node* JSGraph::Constant(const ObjectRef& ref) {
51 if (ref.IsSmi()) return Constant(ref.AsSmi());
52 if (ref.IsHeapNumber()) {
53 return Constant(ref.AsHeapNumber().value());
54 }
55 OddballType oddball_type =
56 ref.AsHeapObject().GetHeapObjectType().oddball_type();
57 if (oddball_type == OddballType::kUndefined) {
58 DCHECK(ref.object().equals(isolate()->factory()->undefined_value()));
59 return UndefinedConstant();
60 } else if (oddball_type == OddballType::kNull) {
61 DCHECK(ref.object().equals(isolate()->factory()->null_value()));
62 return NullConstant();
63 } else if (oddball_type == OddballType::kHole) {
64 DCHECK(ref.object().equals(isolate()->factory()->the_hole_value()));
65 return TheHoleConstant();
66 } else if (oddball_type == OddballType::kBoolean) {
67 if (ref.object().equals(isolate()->factory()->true_value())) {
68 return TrueConstant();
69 } else {
70 DCHECK(ref.object().equals(isolate()->factory()->false_value()));
71 return FalseConstant();
72 }
73 } else {
74 return HeapConstant(ref.AsHeapObject().object());
75 }
76 }
77
Constant(double value)78 Node* JSGraph::Constant(double value) {
79 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
80 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
81 return NumberConstant(value);
82 }
83
NumberConstant(double value)84 Node* JSGraph::NumberConstant(double value) {
85 Node** loc = cache_.FindNumberConstant(value);
86 if (*loc == nullptr) {
87 *loc = graph()->NewNode(common()->NumberConstant(value));
88 }
89 return *loc;
90 }
91
HeapConstant(Handle<HeapObject> value)92 Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
93 Node** loc = cache_.FindHeapConstant(value);
94 if (*loc == nullptr) {
95 *loc = graph()->NewNode(common()->HeapConstant(value));
96 }
97 return *loc;
98 }
99
GetCachedNodes(NodeVector * nodes)100 void JSGraph::GetCachedNodes(NodeVector* nodes) {
101 cache_.GetCachedNodes(nodes);
102 #define DO_CACHED_FIELD(name) \
103 if (name##_) nodes->push_back(name##_);
104
105 CACHED_GLOBAL_LIST(DO_CACHED_FIELD)
106 CACHED_CENTRY_LIST(DO_CACHED_FIELD)
107 #undef DO_CACHED_FIELD
108 }
109
110 DEFINE_GETTER(AllocateInYoungGenerationStubConstant,
111 HeapConstant(BUILTIN_CODE(isolate(), AllocateInYoungGeneration)))
112
113 DEFINE_GETTER(AllocateRegularInYoungGenerationStubConstant,
114 HeapConstant(BUILTIN_CODE(isolate(),
115 AllocateRegularInYoungGeneration)))
116
117 DEFINE_GETTER(AllocateInOldGenerationStubConstant,
118 HeapConstant(BUILTIN_CODE(isolate(), AllocateInOldGeneration)))
119
120 DEFINE_GETTER(AllocateRegularInOldGenerationStubConstant,
121 HeapConstant(BUILTIN_CODE(isolate(),
122 AllocateRegularInOldGeneration)))
123
124 DEFINE_GETTER(ArrayConstructorStubConstant,
125 HeapConstant(BUILTIN_CODE(isolate(), ArrayConstructorImpl)))
126
127 DEFINE_GETTER(BigIntMapConstant, HeapConstant(factory()->bigint_map()))
128
129 DEFINE_GETTER(BooleanMapConstant, HeapConstant(factory()->boolean_map()))
130
131 DEFINE_GETTER(ToNumberBuiltinConstant,
132 HeapConstant(BUILTIN_CODE(isolate(), ToNumber)))
133
134 DEFINE_GETTER(PlainPrimitiveToNumberBuiltinConstant,
135 HeapConstant(BUILTIN_CODE(isolate(), PlainPrimitiveToNumber)))
136
137 DEFINE_GETTER(EmptyFixedArrayConstant,
138 HeapConstant(factory()->empty_fixed_array()))
139
140 DEFINE_GETTER(EmptyStringConstant, HeapConstant(factory()->empty_string()))
141
142 DEFINE_GETTER(FixedArrayMapConstant, HeapConstant(factory()->fixed_array_map()))
143
144 DEFINE_GETTER(PropertyArrayMapConstant,
145 HeapConstant(factory()->property_array_map()))
146
147 DEFINE_GETTER(FixedDoubleArrayMapConstant,
148 HeapConstant(factory()->fixed_double_array_map()))
149
150 DEFINE_GETTER(WeakFixedArrayMapConstant,
151 HeapConstant(factory()->weak_fixed_array_map()))
152
153 DEFINE_GETTER(HeapNumberMapConstant, HeapConstant(factory()->heap_number_map()))
154
155 DEFINE_GETTER(OptimizedOutConstant, HeapConstant(factory()->optimized_out()))
156
157 DEFINE_GETTER(StaleRegisterConstant, HeapConstant(factory()->stale_register()))
158
159 DEFINE_GETTER(UndefinedConstant, HeapConstant(factory()->undefined_value()))
160
161 DEFINE_GETTER(TheHoleConstant, HeapConstant(factory()->the_hole_value()))
162
163 DEFINE_GETTER(TrueConstant, HeapConstant(factory()->true_value()))
164
165 DEFINE_GETTER(FalseConstant, HeapConstant(factory()->false_value()))
166
167 DEFINE_GETTER(NullConstant, HeapConstant(factory()->null_value()))
168
169 DEFINE_GETTER(ZeroConstant, NumberConstant(0.0))
170
171 DEFINE_GETTER(MinusZeroConstant, NumberConstant(-0.0))
172
173 DEFINE_GETTER(OneConstant, NumberConstant(1.0))
174
175 DEFINE_GETTER(MinusOneConstant, NumberConstant(-1.0))
176
177 DEFINE_GETTER(NaNConstant,
178 NumberConstant(std::numeric_limits<double>::quiet_NaN()))
179
180 DEFINE_GETTER(EmptyStateValues,
181 graph()->NewNode(common()->StateValues(0,
182 SparseInputMask::Dense())))
183
184 DEFINE_GETTER(
185 SingleDeadTypedStateValues,
186 graph()->NewNode(common()->TypedStateValues(
187 graph()->zone()->New<ZoneVector<MachineType>>(0, graph()->zone()),
188 SparseInputMask(SparseInputMask::kEndMarker << 1))))
189
190 #undef DEFINE_GETTER
191 #undef GET_CACHED_FIELD
192
193 } // namespace compiler
194 } // namespace internal
195 } // namespace v8
196