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 18 Node* JSGraph::CEntryStubConstant(int result_size) { 19 if (result_size == 1) { 20 return CACHED(kCEntryStubConstant, 21 HeapConstant(CEntryStub(isolate(), 1).GetCode())); 22 } 23 return HeapConstant(CEntryStub(isolate(), result_size).GetCode()); 24 } 25 26 27 Node* JSGraph::EmptyFixedArrayConstant() { 28 return CACHED(kEmptyFixedArrayConstant, 29 HeapConstant(factory()->empty_fixed_array())); 30 } 31 32 33 Node* JSGraph::UndefinedConstant() { 34 return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value())); 35 } 36 37 38 Node* JSGraph::TheHoleConstant() { 39 return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value())); 40 } 41 42 43 Node* JSGraph::TrueConstant() { 44 return CACHED(kTrueConstant, HeapConstant(factory()->true_value())); 45 } 46 47 48 Node* JSGraph::FalseConstant() { 49 return CACHED(kFalseConstant, HeapConstant(factory()->false_value())); 50 } 51 52 53 Node* JSGraph::NullConstant() { 54 return CACHED(kNullConstant, HeapConstant(factory()->null_value())); 55 } 56 57 58 Node* JSGraph::ZeroConstant() { 59 return CACHED(kZeroConstant, NumberConstant(0.0)); 60 } 61 62 63 Node* JSGraph::OneConstant() { 64 return CACHED(kOneConstant, NumberConstant(1.0)); 65 } 66 67 68 Node* JSGraph::NaNConstant() { 69 return CACHED(kNaNConstant, 70 NumberConstant(std::numeric_limits<double>::quiet_NaN())); 71 } 72 73 74 Node* JSGraph::HeapConstant(Handle<HeapObject> value) { 75 if (value->IsConsString()) { 76 value = String::Flatten(Handle<String>::cast(value), TENURED); 77 } 78 Node** loc = cache_.FindHeapConstant(value); 79 if (*loc == nullptr) { 80 *loc = graph()->NewNode(common()->HeapConstant(value)); 81 } 82 return *loc; 83 } 84 85 86 Node* JSGraph::Constant(Handle<Object> value) { 87 // Dereference the handle to determine if a number constant or other 88 // canonicalized node can be used. 89 if (value->IsNumber()) { 90 return Constant(value->Number()); 91 } else if (value->IsUndefined()) { 92 return UndefinedConstant(); 93 } else if (value->IsTrue()) { 94 return TrueConstant(); 95 } else if (value->IsFalse()) { 96 return FalseConstant(); 97 } else if (value->IsNull()) { 98 return NullConstant(); 99 } else if (value->IsTheHole()) { 100 return TheHoleConstant(); 101 } else { 102 return HeapConstant(Handle<HeapObject>::cast(value)); 103 } 104 } 105 106 107 Node* JSGraph::Constant(double value) { 108 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant(); 109 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant(); 110 return NumberConstant(value); 111 } 112 113 114 Node* JSGraph::Constant(int32_t value) { 115 if (value == 0) return ZeroConstant(); 116 if (value == 1) return OneConstant(); 117 return NumberConstant(value); 118 } 119 120 121 Node* JSGraph::Int32Constant(int32_t value) { 122 Node** loc = cache_.FindInt32Constant(value); 123 if (*loc == nullptr) { 124 *loc = graph()->NewNode(common()->Int32Constant(value)); 125 } 126 return *loc; 127 } 128 129 130 Node* JSGraph::Int64Constant(int64_t value) { 131 Node** loc = cache_.FindInt64Constant(value); 132 if (*loc == nullptr) { 133 *loc = graph()->NewNode(common()->Int64Constant(value)); 134 } 135 return *loc; 136 } 137 138 139 Node* JSGraph::NumberConstant(double value) { 140 Node** loc = cache_.FindNumberConstant(value); 141 if (*loc == nullptr) { 142 *loc = graph()->NewNode(common()->NumberConstant(value)); 143 } 144 return *loc; 145 } 146 147 148 Node* JSGraph::Float32Constant(float value) { 149 Node** loc = cache_.FindFloat32Constant(value); 150 if (*loc == nullptr) { 151 *loc = graph()->NewNode(common()->Float32Constant(value)); 152 } 153 return *loc; 154 } 155 156 157 Node* JSGraph::Float64Constant(double value) { 158 Node** loc = cache_.FindFloat64Constant(value); 159 if (*loc == nullptr) { 160 *loc = graph()->NewNode(common()->Float64Constant(value)); 161 } 162 return *loc; 163 } 164 165 166 Node* JSGraph::ExternalConstant(ExternalReference reference) { 167 Node** loc = cache_.FindExternalConstant(reference); 168 if (*loc == nullptr) { 169 *loc = graph()->NewNode(common()->ExternalConstant(reference)); 170 } 171 return *loc; 172 } 173 174 175 Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) { 176 return ExternalConstant(ExternalReference(function_id, isolate())); 177 } 178 179 180 Node* JSGraph::EmptyFrameState() { 181 Node* empty_frame_state = cached_nodes_[kEmptyFrameState]; 182 if (!empty_frame_state || empty_frame_state->IsDead()) { 183 Node* state_values = graph()->NewNode(common()->StateValues(0)); 184 empty_frame_state = graph()->NewNode( 185 common()->FrameState(BailoutId::None(), 186 OutputFrameStateCombine::Ignore(), nullptr), 187 state_values, state_values, state_values, NoContextConstant(), 188 UndefinedConstant(), graph()->start()); 189 cached_nodes_[kEmptyFrameState] = empty_frame_state; 190 } 191 return empty_frame_state; 192 } 193 194 195 Node* JSGraph::Dead() { 196 return CACHED(kDead, graph()->NewNode(common()->Dead())); 197 } 198 199 200 void JSGraph::GetCachedNodes(NodeVector* nodes) { 201 cache_.GetCachedNodes(nodes); 202 for (size_t i = 0; i < arraysize(cached_nodes_); i++) { 203 if (Node* node = cached_nodes_[i]) { 204 if (!node->IsDead()) nodes->push_back(node); 205 } 206 } 207 } 208 209 } // namespace compiler 210 } // namespace internal 211 } // namespace v8 212