Chromium Code Reviews| Index: src/type-info.cc |
| diff --git a/src/type-info.cc b/src/type-info.cc |
| index f76bb591f1109eda3a0386f457b72e9d3cb70393..ce0ab6ca6a63e8d0321e110e7f4ffad60dac3d4d 100644 |
| --- a/src/type-info.cc |
| +++ b/src/type-info.cc |
| @@ -191,38 +191,100 @@ Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( |
| return Handle<AllocationSite>::null(); |
| } |
| -void TypeFeedbackOracle::CompareType(TypeFeedbackId id, AstType** left_type, |
| - AstType** right_type, |
| +namespace { |
| + |
| +AstType* CompareOpHintToType(CompareOperationHint hint) { |
| + switch (hint) { |
| + case CompareOperationHint::kNone: |
| + return AstType::None(); |
| + case CompareOperationHint::kSignedSmall: |
| + return AstType::SignedSmall(); |
| + case CompareOperationHint::kNumber: |
| + return AstType::Number(); |
| + case CompareOperationHint::kNumberOrOddball: |
| + return AstType::NumberOrOddball(); |
| + case CompareOperationHint::kAny: |
| + 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::kSigned32: |
| + return AstType::Signed32(); |
| + case BinaryOperationHint::kNumberOrOddball: |
|
mythria
2016/09/26 20:37:34
We only collect feedback about Number. We change i
|
| + return AstType::Number(); |
| + case BinaryOperationHint::kString: |
| + return AstType::String(); |
| + case BinaryOperationHint::kAny: |
| + 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) { |
| Handle<Object> info = GetInfo(id); |
| + // A check for a valid slot is not sufficient here. InstanceOf collects |
| + // type feedback in a General slot. |
| if (!info->IsCode()) { |
|
mythria
2016/09/26 20:37:34
I had to change this check because now instance of
|
| - // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. |
| + // For some comparisons we don't have type feedback, 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. |
| + DCHECK(!slot.IsInvalid()); |
| + CompareICNexus nexus(feedback_vector_, slot); |
| + *left_type = *right_type = *combined_type = |
| + CompareOpHintToType(nexus.GetCompareOperationFeedback()); |
| + |
| + // Merge the feedback from full-codegen if available. |
| + 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); |
| if (code->is_compare_ic_stub()) { |
| CompareICStub stub(code->stub_key(), isolate()); |
| - *left_type = CompareICState::StateToType(zone(), stub.left()); |
| - *right_type = CompareICState::StateToType(zone(), stub.right()); |
| - *combined_type = CompareICState::StateToType(zone(), stub.state(), map); |
| + AstType* left_type_from_ic = |
| + CompareICState::StateToType(zone(), stub.left()); |
| + *left_type = AstType::Union(*left_type, left_type_from_ic, zone()); |
| + AstType* right_type_from_ic = |
| + CompareICState::StateToType(zone(), stub.right()); |
| + *right_type = AstType::Union(*right_type, right_type_from_ic, zone()); |
| + AstType* combined_type_from_ic = |
| + CompareICState::StateToType(zone(), stub.state(), map); |
| + *combined_type = |
| + AstType::Union(*combined_type, combined_type_from_ic, zone()); |
| } |
| } |
| -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) { |
| 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. |
| + if (slot.IsInvalid()) { |
| + // 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(!object->IsCode()); |
| DCHECK(op < BinaryOpICState::FIRST_TOKEN || |
| op > BinaryOpICState::LAST_TOKEN); |
| *left = *right = *result = AstType::None(); |
| @@ -230,14 +292,28 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, AstType** left, |
| *allocation_site = Handle<AllocationSite>::null(); |
| return; |
| } |
| + |
| + // 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. |
| + DCHECK(!slot.IsInvalid()); |
| + BinaryOpICNexus nexus(feedback_vector_, slot); |
| + *left = *right = *result = |
| + BinaryOpHintToType(nexus.GetBinaryOperationFeedback()); |
| + *fixed_right_arg = Nothing<int>(); |
| + *allocation_site = Handle<AllocationSite>::null(); |
| + |
| + if (!object->IsCode()) return; |
| + |
| + // Merge the feedback from full-codegen if available. |
| Handle<Code> code = Handle<Code>::cast(object); |
| DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); |
| BinaryOpICState state(isolate(), code->extra_ic_state()); |
| DCHECK_EQ(op, state.op()); |
| - *left = state.GetLeftType(); |
| - *right = state.GetRightType(); |
| - *result = state.GetResultType(); |
| + *left = AstType::Union(*left, state.GetLeftType(), zone()); |
| + *right = AstType::Union(*right, state.GetRightType(), zone()); |
| + *result = AstType::Union(*result, state.GetResultType(), zone()); |
| *fixed_right_arg = state.fixed_right_arg(); |
| AllocationSite* first_allocation_site = code->FindFirstAllocationSite(); |
| @@ -248,13 +324,24 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, AstType** left, |
| } |
| } |
| -AstType* TypeFeedbackOracle::CountType(TypeFeedbackId id) { |
| +AstType* TypeFeedbackOracle::CountType(TypeFeedbackId id, |
| + FeedbackVectorSlot slot) { |
| Handle<Object> object = GetInfo(id); |
| - if (!object->IsCode()) return AstType::None(); |
| + if (slot.IsInvalid()) { |
| + DCHECK(!object->IsCode()); |
| + return AstType::None(); |
| + } |
| + |
| + DCHECK(!slot.IsInvalid()); |
| + BinaryOpICNexus nexus(feedback_vector_, slot); |
| + AstType* type = BinaryOpHintToType(nexus.GetBinaryOperationFeedback()); |
| + |
| + if (!object->IsCode()) return type; |
| + |
| Handle<Code> code = Handle<Code>::cast(object); |
| DCHECK_EQ(Code::BINARY_OP_IC, code->kind()); |
| BinaryOpICState state(isolate(), code->extra_ic_state()); |
| - return state.GetLeftType(); |
| + return AstType::Union(type, state.GetLeftType(), zone()); |
| } |