Index: src/type-info.cc |
diff --git a/src/type-info.cc b/src/type-info.cc |
index f76bb591f1109eda3a0386f457b72e9d3cb70393..e05d87227fb3846c1fe97004fb8f9813059848e6 100644 |
--- a/src/type-info.cc |
+++ b/src/type-info.cc |
@@ -191,17 +191,66 @@ Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( |
return Handle<AllocationSite>::null(); |
} |
-void TypeFeedbackOracle::CompareType(TypeFeedbackId id, AstType** left_type, |
- AstType** right_type, |
- AstType** combined_type) { |
+namespace { |
+ |
+AstType* CompareOpHintToType(CompareOperationHint hint) { |
mythria
2016/09/22 14:09:42
I actually wanted to move it to the CompareICNexus
|
+ switch (hint) { |
+ case CompareOperationHint::kNone: |
+ return AstType::None(); |
+ case CompareOperationHint::kSignedSmall: |
+ return AstType::SignedSmall(); |
+ case CompareOperationHint::kNumberOrOddball: |
+ return AstType::Number(); |
+ case CompareOperationHint::kAny: |
+ default: |
+ return AstType::Any(); |
+ } |
+ UNREACHABLE(); |
+ return AstType::None(); |
+} |
+ |
+AstType* BinaryOpHintToType(BinaryOperationHint hint) { |
+ switch (hint) { |
+ case BinaryOperationHint::kNone: |
+ return AstType::None(); |
+ case BinaryOperationHint::kSignedSmall: |
+ return AstType::SignedSmall(); |
+ case BinaryOperationHint::kNumberOrOddball: |
+ return AstType::Number(); |
+ case BinaryOperationHint::kAny: |
+ default: |
+ return AstType::Any(); |
+ } |
+ UNREACHABLE(); |
+ return AstType::None(); |
+} |
+ |
+} // end anonymous namespace |
+ |
+void TypeFeedbackOracle::CompareType(TypeFeedbackId id, FeedbackVectorSlot slot, |
+ AstType** left_type, AstType** right_type, |
+ AstType** combined_type, |
+ bool feedback_from_ignition) { |
Handle<Object> info = GetInfo(id); |
if (!info->IsCode()) { |
// For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. |
*left_type = *right_type = *combined_type = AstType::None(); |
return; |
} |
- Handle<Code> code = Handle<Code>::cast(info); |
+ // Feedback from Ignition. The feedback slot will be allocated and initialized |
+ // to AstType::None() even when ignition is not enabled. So it is safe to get |
+ // feedback from the type feedback vector. |
+ if (feedback_from_ignition) { |
+ DCHECK(!slot.IsInvalid()); |
+ CompareICNexus nexus(feedback_vector_, slot); |
+ *left_type = *right_type = *combined_type = |
+ CompareOpHintToType(nexus.GetCompareOperationFeedback()); |
+ return; |
+ } |
+ |
+ // Feedback from IC. |
+ Handle<Code> code = Handle<Code>::cast(info); |
Handle<Map> map; |
Map* raw_map = code->FindFirstMap(); |
if (raw_map != NULL) Map::TryUpdate(handle(raw_map)).ToHandle(&map); |
@@ -211,18 +260,24 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id, AstType** left_type, |
*left_type = CompareICState::StateToType(zone(), stub.left()); |
*right_type = CompareICState::StateToType(zone(), stub.right()); |
*combined_type = CompareICState::StateToType(zone(), stub.state(), map); |
+ } else { |
+ *left_type = *right_type = *combined_type = AstType::None(); |
} |
} |
-void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, AstType** left, |
- AstType** right, AstType** result, |
+void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, FeedbackVectorSlot slot, |
+ AstType** left, AstType** right, |
+ AstType** result, |
Maybe<int>* fixed_right_arg, |
Handle<AllocationSite>* allocation_site, |
- Token::Value op) { |
+ Token::Value op, |
+ bool feedback_from_ignition) { |
Handle<Object> object = GetInfo(id); |
if (!object->IsCode()) { |
- // For some binary ops we don't have ICs, e.g. Token::COMMA, but for the |
- // operations covered by the BinaryOpIC we should always have them. |
+ // For some binary ops we don't have ICs or feedback slots, |
+ // e.g. Token::COMMA, but for the operations covered by the BinaryOpIC we |
+ // should always have them. |
+ DCHECK(slot.IsInvalid()); |
DCHECK(op < BinaryOpICState::FIRST_TOKEN || |
op > BinaryOpICState::LAST_TOKEN); |
*left = *right = *result = AstType::None(); |
@@ -230,6 +285,19 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, AstType** left, |
*allocation_site = Handle<AllocationSite>::null(); |
return; |
} |
+ |
+ // Feedback from Ignition. |
+ if (feedback_from_ignition) { |
+ DCHECK(!slot.IsInvalid()); |
+ BinaryOpICNexus nexus(feedback_vector_, slot); |
+ *left = *right = *result = |
+ BinaryOpHintToType(nexus.GetBinaryOperationFeedback()); |
+ *fixed_right_arg = Nothing<int>(); |
+ *allocation_site = Handle<AllocationSite>::null(); |
+ return; |
+ } |
+ |
+ // Feedback from IC. |
Handle<Code> code = Handle<Code>::cast(object); |
DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); |
BinaryOpICState state(isolate(), code->extra_ic_state()); |
@@ -248,9 +316,22 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, AstType** left, |
} |
} |
-AstType* TypeFeedbackOracle::CountType(TypeFeedbackId id) { |
+AstType* TypeFeedbackOracle::CountType(TypeFeedbackId id, |
+ FeedbackVectorSlot slot, |
+ bool feedback_from_ignition) { |
Handle<Object> object = GetInfo(id); |
- if (!object->IsCode()) return AstType::None(); |
+ if (!object->IsCode()) { |
+ DCHECK(slot.IsInvalid()); |
+ return AstType::None(); |
+ } |
+ |
+ if (feedback_from_ignition) { |
+ DCHECK(!slot.IsInvalid()); |
+ BinaryOpICNexus nexus(feedback_vector_, slot); |
+ return BinaryOpHintToType(nexus.GetBinaryOperationFeedback()); |
+ } |
+ |
+ // Feedback from IC. |
Handle<Code> code = Handle<Code>::cast(object); |
DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); |
BinaryOpICState state(isolate(), code->extra_ic_state()); |