| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/type-hint-analyzer.h" | 5 #include "src/compiler/type-hint-analyzer.h" |
| 6 | 6 |
| 7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compiler/type-hints.h" | 9 #include "src/compiler/type-hints.h" |
| 10 #include "src/ic/ic-state.h" | 10 #include "src/ic/ic-state.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 namespace compiler { | 14 namespace compiler { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 // TODO(bmeurer): This detour via types is ugly. | 18 BinaryOperationHint ToBinaryOperationHint(BinaryOpICState::Kind kind) { |
| 19 BinaryOperationHints::Hint ToBinaryOperationHint(Type* type) { | 19 switch (kind) { |
| 20 if (type->Is(Type::None())) return BinaryOperationHints::kNone; | 20 case BinaryOpICState::NONE: |
| 21 if (type->Is(Type::SignedSmall())) return BinaryOperationHints::kSignedSmall; | 21 return BinaryOperationHint::kNone; |
| 22 if (type->Is(Type::Signed32())) return BinaryOperationHints::kSigned32; | 22 case BinaryOpICState::SMI: |
| 23 if (type->Is(Type::Number())) return BinaryOperationHints::kNumberOrOddball; | 23 return BinaryOperationHint::kSignedSmall; |
| 24 if (type->Is(Type::String())) return BinaryOperationHints::kString; | 24 case BinaryOpICState::INT32: |
| 25 return BinaryOperationHints::kAny; | 25 return BinaryOperationHint::kSigned32; |
| 26 case BinaryOpICState::NUMBER: |
| 27 return BinaryOperationHint::kNumberOrOddball; |
| 28 case BinaryOpICState::STRING: |
| 29 case BinaryOpICState::GENERIC: |
| 30 return BinaryOperationHint::kAny; |
| 31 } |
| 32 UNREACHABLE(); |
| 33 return BinaryOperationHint::kNone; |
| 26 } | 34 } |
| 27 | 35 |
| 28 CompareOperationHints::Hint ToCompareOperationHint( | 36 CompareOperationHint ToCompareOperationHint(Token::Value op, |
| 29 Token::Value op, CompareICState::State state) { | 37 CompareICState::State state) { |
| 30 switch (state) { | 38 switch (state) { |
| 31 case CompareICState::UNINITIALIZED: | 39 case CompareICState::UNINITIALIZED: |
| 32 return CompareOperationHints::kNone; | 40 return CompareOperationHint::kNone; |
| 33 case CompareICState::BOOLEAN: | |
| 34 return CompareOperationHints::kBoolean; | |
| 35 case CompareICState::SMI: | 41 case CompareICState::SMI: |
| 36 return CompareOperationHints::kSignedSmall; | 42 return CompareOperationHint::kSignedSmall; |
| 37 case CompareICState::NUMBER: | 43 case CompareICState::NUMBER: |
| 38 return Token::IsOrderedRelationalCompareOp(op) | 44 return Token::IsOrderedRelationalCompareOp(op) |
| 39 ? CompareOperationHints::kNumberOrOddball | 45 ? CompareOperationHint::kNumberOrOddball |
| 40 : CompareOperationHints::kNumber; | 46 : CompareOperationHint::kNumber; |
| 41 case CompareICState::STRING: | 47 case CompareICState::STRING: |
| 42 return CompareOperationHints::kString; | |
| 43 case CompareICState::INTERNALIZED_STRING: | 48 case CompareICState::INTERNALIZED_STRING: |
| 44 return CompareOperationHints::kInternalizedString; | |
| 45 case CompareICState::UNIQUE_NAME: | 49 case CompareICState::UNIQUE_NAME: |
| 46 return CompareOperationHints::kUniqueName; | |
| 47 case CompareICState::RECEIVER: | 50 case CompareICState::RECEIVER: |
| 48 case CompareICState::KNOWN_RECEIVER: | 51 case CompareICState::KNOWN_RECEIVER: |
| 49 return CompareOperationHints::kReceiver; | 52 case CompareICState::BOOLEAN: |
| 50 case CompareICState::GENERIC: | 53 case CompareICState::GENERIC: |
| 51 return CompareOperationHints::kAny; | 54 return CompareOperationHint::kAny; |
| 52 } | 55 } |
| 53 UNREACHABLE(); | 56 UNREACHABLE(); |
| 54 return CompareOperationHints::kAny; | 57 return CompareOperationHint::kNone; |
| 55 } | 58 } |
| 56 | 59 |
| 57 } // namespace | 60 } // namespace |
| 58 | 61 |
| 59 bool TypeHintAnalysis::GetBinaryOperationHints( | 62 bool TypeHintAnalysis::GetBinaryOperationHint(TypeFeedbackId id, |
| 60 TypeFeedbackId id, BinaryOperationHints* hints) const { | 63 BinaryOperationHint* hint) const { |
| 61 auto i = infos_.find(id); | 64 auto i = infos_.find(id); |
| 62 if (i == infos_.end()) return false; | 65 if (i == infos_.end()) return false; |
| 63 Handle<Code> code = i->second; | 66 Handle<Code> code = i->second; |
| 64 DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); | 67 DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); |
| 65 BinaryOpICState state(code->GetIsolate(), code->extra_ic_state()); | 68 BinaryOpICState state(code->GetIsolate(), code->extra_ic_state()); |
| 66 *hints = BinaryOperationHints(ToBinaryOperationHint(state.GetLeftType()), | 69 *hint = ToBinaryOperationHint(state.kind()); |
| 67 ToBinaryOperationHint(state.GetRightType()), | |
| 68 ToBinaryOperationHint(state.GetResultType())); | |
| 69 return true; | 70 return true; |
| 70 } | 71 } |
| 71 | 72 |
| 72 bool TypeHintAnalysis::GetCompareOperationHints( | 73 bool TypeHintAnalysis::GetCompareOperationHint( |
| 73 TypeFeedbackId id, CompareOperationHints* hints) const { | 74 TypeFeedbackId id, CompareOperationHint* hint) const { |
| 74 auto i = infos_.find(id); | 75 auto i = infos_.find(id); |
| 75 if (i == infos_.end()) return false; | 76 if (i == infos_.end()) return false; |
| 76 Handle<Code> code = i->second; | 77 Handle<Code> code = i->second; |
| 77 DCHECK_EQ(Code::COMPARE_IC, code->kind()); | 78 DCHECK_EQ(Code::COMPARE_IC, code->kind()); |
| 78 | |
| 79 Handle<Map> map; | |
| 80 Map* raw_map = code->FindFirstMap(); | |
| 81 if (raw_map != nullptr) Map::TryUpdate(handle(raw_map)).ToHandle(&map); | |
| 82 | |
| 83 CompareICStub stub(code->stub_key(), code->GetIsolate()); | 79 CompareICStub stub(code->stub_key(), code->GetIsolate()); |
| 84 *hints = | 80 *hint = ToCompareOperationHint(stub.op(), stub.state()); |
| 85 CompareOperationHints(ToCompareOperationHint(stub.op(), stub.left()), | |
| 86 ToCompareOperationHint(stub.op(), stub.right()), | |
| 87 ToCompareOperationHint(stub.op(), stub.state())); | |
| 88 return true; | 81 return true; |
| 89 } | 82 } |
| 90 | 83 |
| 91 bool TypeHintAnalysis::GetToBooleanHints(TypeFeedbackId id, | 84 bool TypeHintAnalysis::GetToBooleanHints(TypeFeedbackId id, |
| 92 ToBooleanHints* hints) const { | 85 ToBooleanHints* hints) const { |
| 93 auto i = infos_.find(id); | 86 auto i = infos_.find(id); |
| 94 if (i == infos_.end()) return false; | 87 if (i == infos_.end()) return false; |
| 95 Handle<Code> code = i->second; | 88 Handle<Code> code = i->second; |
| 96 DCHECK_EQ(Code::TO_BOOLEAN_IC, code->kind()); | 89 DCHECK_EQ(Code::TO_BOOLEAN_IC, code->kind()); |
| 97 ToBooleanICStub stub(code->GetIsolate(), code->extra_ic_state()); | 90 ToBooleanICStub stub(code->GetIsolate(), code->extra_ic_state()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 break; | 125 break; |
| 133 } | 126 } |
| 134 default: | 127 default: |
| 135 // Ignore the remaining code objects. | 128 // Ignore the remaining code objects. |
| 136 break; | 129 break; |
| 137 } | 130 } |
| 138 } | 131 } |
| 139 return new (zone()) TypeHintAnalysis(infos, zone()); | 132 return new (zone()) TypeHintAnalysis(infos, zone()); |
| 140 } | 133 } |
| 141 | 134 |
| 142 // Helper function to transform the feedback to BinaryOperationHints | 135 // Helper function to transform the feedback to BinaryOperationHint. |
| 143 BinaryOperationHints::Hint BinaryOperationHintFromFeedback(int type_feedback) { | 136 BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) { |
| 144 switch (type_feedback) { | 137 switch (type_feedback) { |
| 145 case BinaryOperationFeedback::kSignedSmall: | 138 case BinaryOperationFeedback::kSignedSmall: |
| 146 return BinaryOperationHints::kSigned32; | 139 return BinaryOperationHint::kSigned32; |
| 147 case BinaryOperationFeedback::kNumber: | 140 case BinaryOperationFeedback::kNumber: |
| 148 return BinaryOperationHints::kNumberOrOddball; | 141 return BinaryOperationHint::kNumberOrOddball; |
| 149 case BinaryOperationFeedback::kAny: | 142 case BinaryOperationFeedback::kAny: |
| 150 default: | 143 default: |
| 151 return BinaryOperationHints::kAny; | 144 return BinaryOperationHint::kAny; |
| 152 } | 145 } |
| 153 return BinaryOperationHints::kAny; | 146 UNREACHABLE(); |
| 147 return BinaryOperationHint::kNone; |
| 154 } | 148 } |
| 155 | 149 |
| 156 } // namespace compiler | 150 } // namespace compiler |
| 157 } // namespace internal | 151 } // namespace internal |
| 158 } // namespace v8 | 152 } // namespace v8 |
| OLD | NEW |