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 #include "src/compiler/node-properties-inl.h" 7 #include "src/compiler/typer.h" 8 9 namespace v8 { 10 namespace internal { 11 namespace compiler { 12 13 Node* JSGraph::ImmovableHeapConstant(Handle<Object> object) { 14 Unique<Object> unique = Unique<Object>::CreateImmovable(object); 15 return NewNode(common()->HeapConstant(unique)); 16 } 17 18 19 Node* JSGraph::NewNode(const Operator* op) { 20 Node* node = graph()->NewNode(op); 21 typer_->Init(node); 22 return node; 23 } 24 25 26 Node* JSGraph::CEntryStubConstant() { 27 if (!c_entry_stub_constant_.is_set()) { 28 c_entry_stub_constant_.set( 29 ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode())); 30 } 31 return c_entry_stub_constant_.get(); 32 } 33 34 35 Node* JSGraph::UndefinedConstant() { 36 if (!undefined_constant_.is_set()) { 37 undefined_constant_.set( 38 ImmovableHeapConstant(factory()->undefined_value())); 39 } 40 return undefined_constant_.get(); 41 } 42 43 44 Node* JSGraph::TheHoleConstant() { 45 if (!the_hole_constant_.is_set()) { 46 the_hole_constant_.set(ImmovableHeapConstant(factory()->the_hole_value())); 47 } 48 return the_hole_constant_.get(); 49 } 50 51 52 Node* JSGraph::TrueConstant() { 53 if (!true_constant_.is_set()) { 54 true_constant_.set(ImmovableHeapConstant(factory()->true_value())); 55 } 56 return true_constant_.get(); 57 } 58 59 60 Node* JSGraph::FalseConstant() { 61 if (!false_constant_.is_set()) { 62 false_constant_.set(ImmovableHeapConstant(factory()->false_value())); 63 } 64 return false_constant_.get(); 65 } 66 67 68 Node* JSGraph::NullConstant() { 69 if (!null_constant_.is_set()) { 70 null_constant_.set(ImmovableHeapConstant(factory()->null_value())); 71 } 72 return null_constant_.get(); 73 } 74 75 76 Node* JSGraph::ZeroConstant() { 77 if (!zero_constant_.is_set()) zero_constant_.set(NumberConstant(0.0)); 78 return zero_constant_.get(); 79 } 80 81 82 Node* JSGraph::OneConstant() { 83 if (!one_constant_.is_set()) one_constant_.set(NumberConstant(1.0)); 84 return one_constant_.get(); 85 } 86 87 88 Node* JSGraph::NaNConstant() { 89 if (!nan_constant_.is_set()) { 90 nan_constant_.set(NumberConstant(base::OS::nan_value())); 91 } 92 return nan_constant_.get(); 93 } 94 95 96 Node* JSGraph::HeapConstant(Unique<Object> value) { 97 // TODO(turbofan): canonicalize heap constants using Unique<T> 98 return NewNode(common()->HeapConstant(value)); 99 } 100 101 102 Node* JSGraph::HeapConstant(Handle<Object> value) { 103 // TODO(titzer): We could also match against the addresses of immortable 104 // immovables here, even without access to the heap, thus always 105 // canonicalizing references to them. 106 // return HeapConstant(Unique<Object>::CreateUninitialized(value)); 107 // TODO(turbofan): This is a work-around to make Unique::HashCode() work for 108 // value numbering. We need some sane way to compute a unique hash code for 109 // arbitrary handles here. 110 Unique<Object> unique(reinterpret_cast<Address>(*value.location()), value); 111 return HeapConstant(unique); 112 } 113 114 115 Node* JSGraph::Constant(Handle<Object> value) { 116 // Dereference the handle to determine if a number constant or other 117 // canonicalized node can be used. 118 if (value->IsNumber()) { 119 return Constant(value->Number()); 120 } else if (value->IsUndefined()) { 121 return UndefinedConstant(); 122 } else if (value->IsTrue()) { 123 return TrueConstant(); 124 } else if (value->IsFalse()) { 125 return FalseConstant(); 126 } else if (value->IsNull()) { 127 return NullConstant(); 128 } else if (value->IsTheHole()) { 129 return TheHoleConstant(); 130 } else { 131 return HeapConstant(value); 132 } 133 } 134 135 136 Node* JSGraph::Constant(double value) { 137 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant(); 138 if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant(); 139 return NumberConstant(value); 140 } 141 142 143 Node* JSGraph::Constant(int32_t value) { 144 if (value == 0) return ZeroConstant(); 145 if (value == 1) return OneConstant(); 146 return NumberConstant(value); 147 } 148 149 150 Node* JSGraph::Int32Constant(int32_t value) { 151 Node** loc = cache_.FindInt32Constant(value); 152 if (*loc == NULL) { 153 *loc = NewNode(common()->Int32Constant(value)); 154 } 155 return *loc; 156 } 157 158 159 Node* JSGraph::NumberConstant(double value) { 160 Node** loc = cache_.FindNumberConstant(value); 161 if (*loc == NULL) { 162 *loc = NewNode(common()->NumberConstant(value)); 163 } 164 return *loc; 165 } 166 167 168 Node* JSGraph::Float64Constant(double value) { 169 Node** loc = cache_.FindFloat64Constant(value); 170 if (*loc == NULL) { 171 *loc = NewNode(common()->Float64Constant(value)); 172 } 173 return *loc; 174 } 175 176 177 Node* JSGraph::ExternalConstant(ExternalReference reference) { 178 Node** loc = cache_.FindExternalConstant(reference); 179 if (*loc == NULL) { 180 *loc = NewNode(common()->ExternalConstant(reference)); 181 } 182 return *loc; 183 } 184 } // namespace compiler 185 } // namespace internal 186 } // namespace v8 187