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/code-stubs.h" 6 #include "src/compiler/js-graph.h" 7 #include "src/compiler/node-properties.h" 8 #include "src/compiler/typer.h" 9 10 namespace v8 { 11 namespace internal { 12 namespace compiler { 13 14 #define CACHED(name, expr) \ 15 cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr)) 16 17 Node* JSGraph::AllocateInNewSpaceStubConstant() { 18 return CACHED(kAllocateInNewSpaceStubConstant, 19 HeapConstant(isolate()->builtins()->AllocateInNewSpace())); 20 } 21 22 Node* JSGraph::AllocateInOldSpaceStubConstant() { 23 return CACHED(kAllocateInOldSpaceStubConstant, 24 HeapConstant(isolate()->builtins()->AllocateInOldSpace())); 25 } 26 27 Node* JSGraph::ToNumberBuiltinConstant() { 28 return CACHED(kToNumberBuiltinConstant, 29 HeapConstant(isolate()->builtins()->ToNumber())); 30 } 31 32 Node* JSGraph::CEntryStubConstant(int result_size) { 33 if (result_size == 1) { 34 return CACHED(kCEntryStubConstant, 35 HeapConstant(CEntryStub(isolate(), 1).GetCode())); 36 } 37 return HeapConstant(CEntryStub(isolate(), result_size).GetCode()); 38 } 39 40 41 Node* JSGraph::EmptyFixedArrayConstant() { 42 return CACHED(kEmptyFixedArrayConstant, 43 HeapConstant(factory()->empty_fixed_array())); 44 } 45 46 Node* JSGraph::EmptyLiteralsArrayConstant() { 47 return CACHED(kEmptyLiteralsArrayConstant, 48 HeapConstant(factory()->empty_literals_array())); 49 } 50 51 Node* JSGraph::HeapNumberMapConstant() { 52 return CACHED(kHeapNumberMapConstant, 53 HeapConstant(factory()->heap_number_map())); 54 } 55 56 Node* JSGraph::OptimizedOutConstant() { 57 return CACHED(kOptimizedOutConstant, 58 HeapConstant(factory()->optimized_out())); 59 } 60 61 Node* JSGraph::StaleRegisterConstant() { 62 return CACHED(kStaleRegisterConstant, 63 HeapConstant(factory()->stale_register())); 64 } 65 66 Node* JSGraph::UndefinedConstant() { 67 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value())); 68 } 69 70 71 Node* JSGraph::TheHoleConstant() { 72 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value())); 73 } 74 75 76 Node* JSGraph::TrueConstant() { 77 return CACHED(kTrueConstant, HeapConstant(factory()->true_value())); 78 } 79 80 81 Node* JSGraph::FalseConstant() { 82 return CACHED(kFalseConstant, HeapConstant(factory()->false_value())); 83 } 84 85 86 Node* JSGraph::NullConstant() { 87 return CACHED(kNullConstant, HeapConstant(factory()->null_value())); 88 } 89 90 91 Node* JSGraph::ZeroConstant() { 92 return CACHED(kZeroConstant, NumberConstant(0.0)); 93 } 94 95 96 Node* JSGraph::OneConstant() { 97 return CACHED(kOneConstant, NumberConstant(1.0)); 98 } 99 100 101 Node* JSGraph::NaNConstant() { 102 return CACHED(kNaNConstant, 103 NumberConstant(std::numeric_limits<double>::quiet_NaN())); 104 } 105 106 107 Node* JSGraph::HeapConstant(Handle<HeapObject> value) { 108 Node** loc = cache_.FindHeapConstant(value); 109 if (*loc == nullptr) { 110 *loc = graph()->NewNode(common()->HeapConstant(value)); 111 } 112 return *loc; 113 } 114 115 116 Node* JSGraph::Constant(Handle<Object> value) { 117 // Dereference the handle to determine if a number constant or other 118 // canonicalized node can be used. 119 if (value->IsNumber()) { 120 return Constant(value->Number()); 121 } else if (value->IsUndefined(isolate())) { 122 return UndefinedConstant(); 123 } else if (value->IsTrue(isolate())) { 124 return TrueConstant(); 125 } else if (value->IsFalse(isolate())) { 126 return FalseConstant(); 127 } else if (value->IsNull(isolate())) { 128 return NullConstant(); 129 } else if (value->IsTheHole(isolate())) { 130 return TheHoleConstant(); 131 } else { 132 return HeapConstant(Handle<HeapObject>::cast(value)); 133 } 134 } 135 136 137 Node* JSGraph::Constant(double value) { 138 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant(); 139 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant(); 140 return NumberConstant(value); 141 } 142 143 144 Node* JSGraph::Constant(int32_t value) { 145 if (value == 0) return ZeroConstant(); 146 if (value == 1) return OneConstant(); 147 return NumberConstant(value); 148 } 149 150 151 Node* JSGraph::Int32Constant(int32_t value) { 152 Node** loc = cache_.FindInt32Constant(value); 153 if (*loc == nullptr) { 154 *loc = graph()->NewNode(common()->Int32Constant(value)); 155 } 156 return *loc; 157 } 158 159 160 Node* JSGraph::Int64Constant(int64_t value) { 161 Node** loc = cache_.FindInt64Constant(value); 162 if (*loc == nullptr) { 163 *loc = graph()->NewNode(common()->Int64Constant(value)); 164 } 165 return *loc; 166 } 167 168 Node* JSGraph::RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) { 169 Node** loc = cache_.FindRelocatableInt32Constant( 170 value, static_cast<RelocInfoMode>(rmode)); 171 if (*loc == nullptr) { 172 *loc = graph()->NewNode(common()->RelocatableInt32Constant(value, rmode)); 173 } 174 return *loc; 175 } 176 177 Node* JSGraph::RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) { 178 Node** loc = cache_.FindRelocatableInt64Constant( 179 value, static_cast<RelocInfoMode>(rmode)); 180 if (*loc == nullptr) { 181 *loc = graph()->NewNode(common()->RelocatableInt64Constant(value, rmode)); 182 } 183 return *loc; 184 } 185 186 Node* JSGraph::RelocatableIntPtrConstant(intptr_t value, 187 RelocInfo::Mode rmode) { 188 return kPointerSize == 8 189 ? RelocatableInt64Constant(value, rmode) 190 : RelocatableInt32Constant(static_cast<int>(value), rmode); 191 } 192 193 Node* JSGraph::NumberConstant(double value) { 194 Node** loc = cache_.FindNumberConstant(value); 195 if (*loc == nullptr) { 196 *loc = graph()->NewNode(common()->NumberConstant(value)); 197 } 198 return *loc; 199 } 200 201 202 Node* JSGraph::Float32Constant(float value) { 203 Node** loc = cache_.FindFloat32Constant(value); 204 if (*loc == nullptr) { 205 *loc = graph()->NewNode(common()->Float32Constant(value)); 206 } 207 return *loc; 208 } 209 210 211 Node* JSGraph::Float64Constant(double value) { 212 Node** loc = cache_.FindFloat64Constant(value); 213 if (*loc == nullptr) { 214 *loc = graph()->NewNode(common()->Float64Constant(value)); 215 } 216 return *loc; 217 } 218 219 220 Node* JSGraph::ExternalConstant(ExternalReference reference) { 221 Node** loc = cache_.FindExternalConstant(reference); 222 if (*loc == nullptr) { 223 *loc = graph()->NewNode(common()->ExternalConstant(reference)); 224 } 225 return *loc; 226 } 227 228 229 Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) { 230 return ExternalConstant(ExternalReference(function_id, isolate())); 231 } 232 233 Node* JSGraph::EmptyStateValues() { 234 return CACHED(kEmptyStateValues, graph()->NewNode(common()->StateValues(0))); 235 } 236 237 Node* JSGraph::Dead() { 238 return CACHED(kDead, graph()->NewNode(common()->Dead())); 239 } 240 241 242 void JSGraph::GetCachedNodes(NodeVector* nodes) { 243 cache_.GetCachedNodes(nodes); 244 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 } 248 } 249 } 250 251 } // namespace compiler 252 } // namespace internal 253 } // namespace v8 254