• 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/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