Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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/graph-assembler.h" | |
| 6 | |
| 7 #include "src/code-factory.h" | |
| 8 #include "src/compiler/linkage.h" | |
| 9 | |
| 10 namespace v8 { | |
| 11 namespace internal { | |
| 12 namespace compiler { | |
| 13 | |
| 14 GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control, | |
| 15 Zone* zone) | |
| 16 : temp_zone_(zone), | |
| 17 jsgraph_(jsgraph), | |
| 18 current_effect_(effect), | |
| 19 current_control_(control) {} | |
| 20 | |
| 21 Node* GraphAssembler::TrueConstant() { return jsgraph()->TrueConstant(); } | |
| 22 | |
| 23 Node* GraphAssembler::FalseConstant() { return jsgraph()->FalseConstant(); } | |
| 24 | |
| 25 Node* GraphAssembler::HeapNumberMapConstant() { | |
| 26 return jsgraph()->HeapNumberMapConstant(); | |
| 27 } | |
| 28 | |
| 29 Node* GraphAssembler::IntPtrConstant(intptr_t value) { | |
| 30 return jsgraph()->IntPtrConstant(value); | |
| 31 } | |
| 32 | |
| 33 Node* GraphAssembler::Int32Constant(int32_t value) { | |
| 34 return jsgraph()->Int32Constant(value); | |
| 35 } | |
| 36 | |
| 37 Node* GraphAssembler::SmiConstant(int32_t value) { | |
| 38 return jsgraph()->SmiConstant(value); | |
| 39 } | |
| 40 | |
| 41 Node* GraphAssembler::Uint32Constant(int32_t value) { | |
| 42 return jsgraph()->Uint32Constant(value); | |
| 43 } | |
| 44 | |
| 45 Node* GraphAssembler::Float64Constant(double value) { | |
| 46 return jsgraph()->Float64Constant(value); | |
| 47 } | |
| 48 | |
| 49 Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) { | |
| 50 return jsgraph()->HeapConstant(object); | |
| 51 } | |
| 52 | |
| 53 Node* GraphAssembler::NoContextConstant() { | |
| 54 return jsgraph()->NoContextConstant(); | |
| 55 } | |
| 56 | |
| 57 Node* GraphAssembler::ExternalConstant(ExternalReference ref) { | |
| 58 return jsgraph()->ExternalConstant(ref); | |
| 59 } | |
| 60 | |
| 61 Node* GraphAssembler::CEntryStubConstant(int result_size) { | |
| 62 return jsgraph()->CEntryStubConstant(result_size); | |
| 63 } | |
| 64 | |
| 65 Node* GraphAssembler::EmptyStringConstant() { | |
| 66 return jsgraph()->EmptyStringConstant(); | |
| 67 } | |
| 68 | |
| 69 Node* GraphAssembler::UndefinedConstant() { | |
| 70 return jsgraph()->UndefinedConstant(); | |
| 71 } | |
| 72 | |
| 73 Node* GraphAssembler::TheHoleConstant() { return jsgraph()->TheHoleConstant(); } | |
| 74 | |
| 75 Node* GraphAssembler::FixedArrayMapConstant() { | |
| 76 return jsgraph()->FixedArrayMapConstant(); | |
| 77 } | |
| 78 | |
| 79 #define PURE_UNOP_DEF(Name) \ | |
| 80 Node* GraphAssembler::Name(Node* input) { \ | |
| 81 return graph()->NewNode(machine()->Name(), input); \ | |
| 82 } | |
| 83 PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF) | |
| 84 #undef PURE_UNOP_DEF | |
| 85 | |
| 86 #define PURE_BINOP_DEF(Name) \ | |
| 87 Node* GraphAssembler::Name(Node* left, Node* right) { \ | |
| 88 return graph()->NewNode(machine()->Name(), left, right); \ | |
| 89 } | |
| 90 PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF) | |
| 91 #undef PURE_BINOP_DEF | |
| 92 | |
| 93 #define CHECKED_BINOP_DEF(Name) \ | |
| 94 Node* GraphAssembler::Name(Node* left, Node* right) { \ | |
| 95 return graph()->NewNode(machine()->Name(), left, right, current_control_); \ | |
| 96 } | |
| 97 CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF) | |
| 98 #undef CHECKED_BINOP_DEF | |
| 99 | |
| 100 Node* GraphAssembler::Float64RoundDown(Node* value) { | |
| 101 if (machine()->Float64RoundDown().IsSupported()) { | |
| 102 return graph()->NewNode(machine()->Float64RoundDown().op(), value); | |
| 103 } | |
| 104 return nullptr; | |
| 105 } | |
| 106 | |
| 107 Node* GraphAssembler::Projection(int index, Node* value) { | |
| 108 return graph()->NewNode(common()->Projection(index), value, current_control_); | |
| 109 } | |
| 110 | |
| 111 Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) { | |
| 112 return current_effect_ = | |
| 113 graph()->NewNode(simplified()->Allocate(NOT_TENURED), size, | |
| 114 current_effect_, current_control_); | |
| 115 } | |
| 116 | |
| 117 Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) { | |
| 118 return current_effect_ = | |
| 119 graph()->NewNode(simplified()->LoadField(access), object, | |
| 120 current_effect_, current_control_); | |
| 121 } | |
| 122 | |
| 123 Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object, | |
| 124 Node* index) { | |
| 125 return current_effect_ = | |
| 126 graph()->NewNode(simplified()->LoadElement(access), object, index, | |
| 127 current_effect_, current_control_); | |
| 128 } | |
| 129 | |
| 130 Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object, | |
| 131 Node* value) { | |
| 132 return current_effect_ = | |
| 133 graph()->NewNode(simplified()->StoreField(access), object, value, | |
| 134 current_effect_, current_control_); | |
| 135 } | |
| 136 | |
| 137 Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object, | |
| 138 Node* index, Node* value) { | |
| 139 return current_effect_ = | |
| 140 graph()->NewNode(simplified()->StoreElement(access), object, index, | |
| 141 value, current_effect_, current_control_); | |
| 142 } | |
| 143 | |
| 144 Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset, | |
| 145 Node* value) { | |
| 146 return current_effect_ = | |
| 147 graph()->NewNode(machine()->Store(rep), object, offset, value, | |
| 148 current_effect_, current_control_); | |
| 149 } | |
| 150 | |
| 151 Node* GraphAssembler::Retain(Node* buffer) { | |
| 152 return current_effect_ = | |
| 153 graph()->NewNode(common()->Retain(), buffer, current_effect_); | |
| 154 } | |
| 155 | |
| 156 Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) { | |
| 157 return current_effect_ = | |
| 158 graph()->NewNode(machine()->UnsafePointerAdd(), base, external, | |
| 159 current_effect_, current_control_); | |
| 160 } | |
| 161 | |
| 162 Node* GraphAssembler::ToNumber(Node* value) { | |
| 163 return current_effect_ = graph()->NewNode( | |
| 164 ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, | |
| 165 jsgraph()->NoContextConstant(), current_effect_); | |
| 166 } | |
| 167 | |
| 168 Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition, | |
| 169 Node* frame_state) { | |
| 170 return current_control_ = current_effect_ = | |
| 171 graph()->NewNode(common()->DeoptimizeIf(reason), condition, | |
| 172 frame_state, current_effect_, current_control_); | |
| 173 } | |
| 174 | |
| 175 Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition, | |
| 176 Node* frame_state) { | |
| 177 return current_control_ = current_effect_ = | |
| 178 graph()->NewNode(common()->DeoptimizeUnless(reason), condition, | |
| 179 frame_state, current_effect_, current_control_); | |
| 180 } | |
| 181 | |
| 182 void GraphAssembler::Branch(Node* condition, | |
| 183 GraphAssemblerStaticLabel<1>* if_true, | |
| 184 GraphAssemblerStaticLabel<1>* if_false) { | |
| 185 DCHECK_NOT_NULL(current_control_); | |
| 186 | |
| 187 BranchHint hint = BranchHint::kNone; | |
| 188 if (if_true->IsDeferred() != if_false->IsDeferred()) { | |
| 189 hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse; | |
| 190 } | |
| 191 | |
| 192 Node* branch = | |
| 193 graph()->NewNode(common()->Branch(hint), condition, current_control_); | |
| 194 | |
| 195 current_control_ = graph()->NewNode(common()->IfTrue(), branch); | |
| 196 MergeState(if_true); | |
| 197 | |
| 198 current_control_ = graph()->NewNode(common()->IfFalse(), branch); | |
| 199 MergeState(if_false); | |
| 200 | |
| 201 current_control_ = nullptr; | |
| 202 current_effect_ = nullptr; | |
| 203 } | |
| 204 | |
| 205 // Extractors (should be only used when destructing the assembler. | |
| 206 Node* GraphAssembler::ExtractCurrentControl() { | |
| 207 Node* result = current_control_; | |
| 208 current_control_ = nullptr; | |
| 209 return result; | |
| 210 } | |
| 211 | |
| 212 Node* GraphAssembler::ExtractCurrentEffect() { | |
| 213 Node* result = current_effect_; | |
| 214 current_effect_ = nullptr; | |
| 215 return result; | |
| 216 } | |
| 217 | |
| 218 void GraphAssembler::Reset(Node* effect, Node* control) { | |
| 219 current_effect_ = effect; | |
| 220 current_control_ = control; | |
| 221 } | |
| 222 | |
| 223 Operator const* GraphAssembler::ToNumberOperator() { | |
| 224 if (!to_number_operator_.is_set()) { | |
| 225 Callable callable = CodeFactory::ToNumber(jsgraph()->isolate()); | |
| 226 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | |
| 227 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 228 jsgraph()->isolate(), graph()->zone(), callable.descriptor(), 0, flags, | |
| 229 Operator::kEliminatable); | |
| 230 to_number_operator_.set(common()->Call(desc)); | |
| 231 } | |
| 232 return to_number_operator_.get(); | |
| 233 } | |
| 234 | |
| 235 Node* GraphAssemblerLabel::PhiAt(size_t index) { | |
| 236 DCHECK(IsBound()); | |
| 237 return GetBindingsPtrFor(index)[0]; | |
| 238 } | |
| 239 | |
| 240 GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred, | |
| 241 size_t merge_count, size_t var_count, | |
| 242 MachineRepresentation* representations, | |
| 243 Zone* zone) | |
| 244 : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred), | |
| 245 max_merge_count_(merge_count), | |
| 246 var_count_(var_count) { | |
| 247 effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1); | |
| 248 for (size_t i = 0; i < MaxMergeCount() + 1; i++) { | |
| 249 effects_[i] = nullptr; | |
| 250 } | |
| 251 | |
| 252 controls_ = zone->NewArray<Node*>(MaxMergeCount()); | |
| 253 for (size_t i = 0; i < MaxMergeCount(); i++) { | |
| 254 controls_[i] = nullptr; | |
| 255 } | |
| 256 | |
| 257 size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1; | |
| 258 bindings_ = zone->NewArray<Node*>(num_bindings); | |
| 259 for (size_t i = 0; i < num_bindings; i++) { | |
| 260 bindings_[i] = nullptr; | |
| 261 } | |
| 262 | |
| 263 representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1); | |
| 264 for (size_t i = 0; i < PhiCount(); i++) { | |
| 265 representations_[i] = representations[i]; | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 GraphAssemblerLabel::~GraphAssemblerLabel() { | |
| 270 DCHECK(IsBound() || MergedCount() == 0); | |
| 271 } | |
| 272 | |
| 273 Node** GraphAssemblerLabel::GetBindingsPtrFor(size_t phi_index) { | |
|
Igor Sheludko
2017/01/02 13:23:27
Please add bounds checks here and in other getters
Jarin
2017/01/03 09:27:55
Done.
| |
| 274 return &bindings_[phi_index * (MaxMergeCount() + 1)]; | |
| 275 } | |
| 276 | |
| 277 MachineRepresentation GraphAssemblerLabel::GetRepresentationFor( | |
| 278 size_t phi_index) { | |
| 279 return representations_[phi_index]; | |
| 280 } | |
| 281 | |
| 282 Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; } | |
| 283 | |
| 284 Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; } | |
| 285 | |
| 286 } // namespace compiler | |
| 287 } // namespace internal | |
| 288 } // namespace v8 | |
| OLD | NEW |