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
12namespace v8 {
13namespace internal {
14namespace 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
21Node* 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
50Node* 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
78Node* 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
84Node* 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
92Node* 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
100void 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
110DEFINE_GETTER(AllocateInYoungGenerationStubConstant,
111              HeapConstant(BUILTIN_CODE(isolate(), AllocateInYoungGeneration)))
112
113DEFINE_GETTER(AllocateRegularInYoungGenerationStubConstant,
114              HeapConstant(BUILTIN_CODE(isolate(),
115                                        AllocateRegularInYoungGeneration)))
116
117DEFINE_GETTER(AllocateInOldGenerationStubConstant,
118              HeapConstant(BUILTIN_CODE(isolate(), AllocateInOldGeneration)))
119
120DEFINE_GETTER(AllocateRegularInOldGenerationStubConstant,
121              HeapConstant(BUILTIN_CODE(isolate(),
122                                        AllocateRegularInOldGeneration)))
123
124DEFINE_GETTER(ArrayConstructorStubConstant,
125              HeapConstant(BUILTIN_CODE(isolate(), ArrayConstructorImpl)))
126
127DEFINE_GETTER(BigIntMapConstant, HeapConstant(factory()->bigint_map()))
128
129DEFINE_GETTER(BooleanMapConstant, HeapConstant(factory()->boolean_map()))
130
131DEFINE_GETTER(ToNumberBuiltinConstant,
132              HeapConstant(BUILTIN_CODE(isolate(), ToNumber)))
133
134DEFINE_GETTER(PlainPrimitiveToNumberBuiltinConstant,
135              HeapConstant(BUILTIN_CODE(isolate(), PlainPrimitiveToNumber)))
136
137DEFINE_GETTER(EmptyFixedArrayConstant,
138              HeapConstant(factory()->empty_fixed_array()))
139
140DEFINE_GETTER(EmptyStringConstant, HeapConstant(factory()->empty_string()))
141
142DEFINE_GETTER(FixedArrayMapConstant, HeapConstant(factory()->fixed_array_map()))
143
144DEFINE_GETTER(PropertyArrayMapConstant,
145              HeapConstant(factory()->property_array_map()))
146
147DEFINE_GETTER(FixedDoubleArrayMapConstant,
148              HeapConstant(factory()->fixed_double_array_map()))
149
150DEFINE_GETTER(WeakFixedArrayMapConstant,
151              HeapConstant(factory()->weak_fixed_array_map()))
152
153DEFINE_GETTER(HeapNumberMapConstant, HeapConstant(factory()->heap_number_map()))
154
155DEFINE_GETTER(OptimizedOutConstant, HeapConstant(factory()->optimized_out()))
156
157DEFINE_GETTER(StaleRegisterConstant, HeapConstant(factory()->stale_register()))
158
159DEFINE_GETTER(UndefinedConstant, HeapConstant(factory()->undefined_value()))
160
161DEFINE_GETTER(TheHoleConstant, HeapConstant(factory()->the_hole_value()))
162
163DEFINE_GETTER(TrueConstant, HeapConstant(factory()->true_value()))
164
165DEFINE_GETTER(FalseConstant, HeapConstant(factory()->false_value()))
166
167DEFINE_GETTER(NullConstant, HeapConstant(factory()->null_value()))
168
169DEFINE_GETTER(ZeroConstant, NumberConstant(0.0))
170
171DEFINE_GETTER(MinusZeroConstant, NumberConstant(-0.0))
172
173DEFINE_GETTER(OneConstant, NumberConstant(1.0))
174
175DEFINE_GETTER(MinusOneConstant, NumberConstant(-1.0))
176
177DEFINE_GETTER(NaNConstant,
178              NumberConstant(std::numeric_limits<double>::quiet_NaN()))
179
180DEFINE_GETTER(EmptyStateValues,
181              graph()->NewNode(common()->StateValues(0,
182                                                     SparseInputMask::Dense())))
183
184DEFINE_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