| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 | 6 |
| 7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
| 8 #include "src/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 UNREACHABLE(); | 28 UNREACHABLE(); |
| 29 return os; | 29 return os; |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 BranchHint BranchHintOf(const Operator* const op) { | 33 BranchHint BranchHintOf(const Operator* const op) { |
| 34 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); | 34 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); |
| 35 return OpParameter<BranchHint>(op); | 35 return OpParameter<BranchHint>(op); |
| 36 } | 36 } |
| 37 | 37 |
| 38 DeoptimizeReason DeoptimizeReasonOf(Operator const* const op) { |
| 39 DCHECK(op->opcode() == IrOpcode::kDeoptimizeIf || |
| 40 op->opcode() == IrOpcode::kDeoptimizeUnless); |
| 41 return OpParameter<DeoptimizeReason>(op); |
| 42 } |
| 38 | 43 |
| 39 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); } | 44 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); } |
| 40 | 45 |
| 41 | |
| 42 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) { | 46 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) { |
| 43 switch (kind) { | 47 switch (kind) { |
| 44 case DeoptimizeKind::kEager: | 48 case DeoptimizeKind::kEager: |
| 45 return os << "Eager"; | 49 return os << "Eager"; |
| 46 case DeoptimizeKind::kSoft: | 50 case DeoptimizeKind::kSoft: |
| 47 return os << "Soft"; | 51 return os << "Soft"; |
| 48 } | 52 } |
| 49 UNREACHABLE(); | 53 UNREACHABLE(); |
| 50 return os; | 54 return os; |
| 51 } | 55 } |
| 52 | 56 |
| 53 | 57 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { |
| 54 DeoptimizeKind DeoptimizeKindOf(const Operator* const op) { | 58 return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason(); |
| 55 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode()); | |
| 56 return OpParameter<DeoptimizeKind>(op); | |
| 57 } | 59 } |
| 58 | 60 |
| 61 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { |
| 62 return !(lhs == rhs); |
| 63 } |
| 64 |
| 65 size_t hash_value(DeoptimizeParameters p) { |
| 66 return base::hash_combine(p.kind(), p.reason()); |
| 67 } |
| 68 |
| 69 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) { |
| 70 return os << p.kind() << ":" << p.reason(); |
| 71 } |
| 72 |
| 73 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) { |
| 74 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode()); |
| 75 return OpParameter<DeoptimizeParameters>(op); |
| 76 } |
| 59 | 77 |
| 60 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); } | 78 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); } |
| 61 | 79 |
| 62 | 80 |
| 63 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) { | 81 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) { |
| 64 switch (hint) { | 82 switch (hint) { |
| 65 case IfExceptionHint::kLocallyCaught: | 83 case IfExceptionHint::kLocallyCaught: |
| 66 return os << "Caught"; | 84 return os << "Caught"; |
| 67 case IfExceptionHint::kLocallyUncaught: | 85 case IfExceptionHint::kLocallyUncaught: |
| 68 return os << "Uncaught"; | 86 return os << "Uncaught"; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 os << ", "; | 214 os << ", "; |
| 197 } | 215 } |
| 198 first = false; | 216 first = false; |
| 199 os << elem; | 217 os << elem; |
| 200 } | 218 } |
| 201 return os; | 219 return os; |
| 202 } | 220 } |
| 203 | 221 |
| 204 #define CACHED_OP_LIST(V) \ | 222 #define CACHED_OP_LIST(V) \ |
| 205 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ | 223 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \ |
| 206 V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 1, 1) \ | |
| 207 V(DeoptimizeUnless, Operator::kFoldable, 2, 1, 1, 0, 1, 1) \ | |
| 208 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 224 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
| 209 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 225 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
| 210 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 226 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
| 211 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ | 227 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \ |
| 212 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \ | 228 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \ |
| 213 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ | 229 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \ |
| 214 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ | 230 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ |
| 215 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ | 231 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \ |
| 216 V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \ | 232 V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \ |
| 217 V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \ | 233 V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \ |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 Name##Operator() \ | 329 Name##Operator() \ |
| 314 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \ | 330 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \ |
| 315 effect_input_count, control_input_count, \ | 331 effect_input_count, control_input_count, \ |
| 316 value_output_count, effect_output_count, \ | 332 value_output_count, effect_output_count, \ |
| 317 control_output_count) {} \ | 333 control_output_count) {} \ |
| 318 }; \ | 334 }; \ |
| 319 Name##Operator k##Name##Operator; | 335 Name##Operator k##Name##Operator; |
| 320 CACHED_OP_LIST(CACHED) | 336 CACHED_OP_LIST(CACHED) |
| 321 #undef CACHED | 337 #undef CACHED |
| 322 | 338 |
| 323 template <DeoptimizeKind kKind> | |
| 324 struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> { | |
| 325 DeoptimizeOperator() | |
| 326 : Operator1<DeoptimizeKind>( // -- | |
| 327 IrOpcode::kDeoptimize, Operator::kNoThrow, // opcode | |
| 328 "Deoptimize", // name | |
| 329 1, 1, 1, 0, 0, 1, // counts | |
| 330 kKind) {} // parameter | |
| 331 }; | |
| 332 DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator; | |
| 333 DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator; | |
| 334 | |
| 335 template <IfExceptionHint kCaughtLocally> | 339 template <IfExceptionHint kCaughtLocally> |
| 336 struct IfExceptionOperator final : public Operator1<IfExceptionHint> { | 340 struct IfExceptionOperator final : public Operator1<IfExceptionHint> { |
| 337 IfExceptionOperator() | 341 IfExceptionOperator() |
| 338 : Operator1<IfExceptionHint>( // -- | 342 : Operator1<IfExceptionHint>( // -- |
| 339 IrOpcode::kIfException, Operator::kKontrol, // opcode | 343 IrOpcode::kIfException, Operator::kKontrol, // opcode |
| 340 "IfException", // name | 344 "IfException", // name |
| 341 0, 1, 1, 1, 1, 1, // counts | 345 0, 1, 1, 1, 1, 1, // counts |
| 342 kCaughtLocally) {} // parameter | 346 kCaughtLocally) {} // parameter |
| 343 }; | 347 }; |
| 344 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator; | 348 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 return &cache_.kBranchNoneOperator; | 560 return &cache_.kBranchNoneOperator; |
| 557 case BranchHint::kTrue: | 561 case BranchHint::kTrue: |
| 558 return &cache_.kBranchTrueOperator; | 562 return &cache_.kBranchTrueOperator; |
| 559 case BranchHint::kFalse: | 563 case BranchHint::kFalse: |
| 560 return &cache_.kBranchFalseOperator; | 564 return &cache_.kBranchFalseOperator; |
| 561 } | 565 } |
| 562 UNREACHABLE(); | 566 UNREACHABLE(); |
| 563 return nullptr; | 567 return nullptr; |
| 564 } | 568 } |
| 565 | 569 |
| 566 | 570 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind, |
| 567 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) { | 571 DeoptimizeReason reason) { |
| 568 switch (kind) { | 572 // TODO(turbofan): Cache the most common versions of this. |
| 569 case DeoptimizeKind::kEager: | 573 DeoptimizeParameters parameter(kind, reason); |
| 570 return &cache_.kDeoptimizeEagerOperator; | 574 return new (zone()) Operator1<DeoptimizeParameters>( // -- |
| 571 case DeoptimizeKind::kSoft: | 575 IrOpcode::kDeoptimize, // opcodes |
| 572 return &cache_.kDeoptimizeSoftOperator; | 576 Operator::kFoldable | Operator::kNoThrow, // properties |
| 573 } | 577 "Deoptimize", // name |
| 574 UNREACHABLE(); | 578 1, 1, 1, 0, 0, 1, // counts |
| 575 return nullptr; | 579 parameter); // parameter |
| 576 } | 580 } |
| 577 | 581 |
| 582 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeReason reason) { |
| 583 // TODO(turbofan): Cache the most common versions of this. |
| 584 return new (zone()) Operator1<DeoptimizeReason>( // -- |
| 585 IrOpcode::kDeoptimizeIf, // opcode |
| 586 Operator::kFoldable | Operator::kNoThrow, // properties |
| 587 "DeoptimizeIf", // name |
| 588 2, 1, 1, 0, 1, 1, // counts |
| 589 reason); // parameter |
| 590 } |
| 591 |
| 592 const Operator* CommonOperatorBuilder::DeoptimizeUnless( |
| 593 DeoptimizeReason reason) { |
| 594 // TODO(turbofan): Cache the most common versions of this. |
| 595 return new (zone()) Operator1<DeoptimizeReason>( // -- |
| 596 IrOpcode::kDeoptimizeUnless, // opcode |
| 597 Operator::kFoldable | Operator::kNoThrow, // properties |
| 598 "DeoptimizeUnless", // name |
| 599 2, 1, 1, 0, 1, 1, // counts |
| 600 reason); // parameter |
| 601 } |
| 578 | 602 |
| 579 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) { | 603 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) { |
| 580 switch (hint) { | 604 switch (hint) { |
| 581 case IfExceptionHint::kLocallyCaught: | 605 case IfExceptionHint::kLocallyCaught: |
| 582 return &cache_.kIfExceptionCOperator; | 606 return &cache_.kIfExceptionCOperator; |
| 583 case IfExceptionHint::kLocallyUncaught: | 607 case IfExceptionHint::kLocallyUncaught: |
| 584 return &cache_.kIfExceptionUOperator; | 608 return &cache_.kIfExceptionUOperator; |
| 585 } | 609 } |
| 586 UNREACHABLE(); | 610 UNREACHABLE(); |
| 587 return nullptr; | 611 return nullptr; |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 CommonOperatorBuilder::CreateFrameStateFunctionInfo( | 972 CommonOperatorBuilder::CreateFrameStateFunctionInfo( |
| 949 FrameStateType type, int parameter_count, int local_count, | 973 FrameStateType type, int parameter_count, int local_count, |
| 950 Handle<SharedFunctionInfo> shared_info) { | 974 Handle<SharedFunctionInfo> shared_info) { |
| 951 return new (zone()->New(sizeof(FrameStateFunctionInfo))) | 975 return new (zone()->New(sizeof(FrameStateFunctionInfo))) |
| 952 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); | 976 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); |
| 953 } | 977 } |
| 954 | 978 |
| 955 } // namespace compiler | 979 } // namespace compiler |
| 956 } // namespace internal | 980 } // namespace internal |
| 957 } // namespace v8 | 981 } // namespace v8 |
| OLD | NEW |