diff options
Diffstat (limited to 'deps/v8/src/type-info.cc')
-rw-r--r-- | deps/v8/src/type-info.cc | 134 |
1 files changed, 107 insertions, 27 deletions
diff --git a/deps/v8/src/type-info.cc b/deps/v8/src/type-info.cc index 8289d91125..ce0ab6ca6a 100644 --- a/deps/v8/src/type-info.cc +++ b/deps/v8/src/type-info.cc @@ -6,7 +6,6 @@ #include "src/ast/ast.h" #include "src/code-stubs.h" -#include "src/compiler.h" #include "src/ic/ic.h" #include "src/ic/stub-cache.h" #include "src/objects-inl.h" @@ -192,58 +191,129 @@ Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( return Handle<AllocationSite>::null(); } +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: + return AstType::Number(); + case BinaryOperationHint::kString: + return AstType::String(); + case BinaryOperationHint::kAny: + return AstType::Any(); + } + UNREACHABLE(); + return AstType::None(); +} -void TypeFeedbackOracle::CompareType(TypeFeedbackId id, - Type** left_type, - Type** right_type, - Type** combined_type) { +} // 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()) { - // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. - *left_type = *right_type = *combined_type = Type::None(); + // 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, - Type** left, - Type** right, - Type** 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 = Type::None(); + *left = *right = *result = AstType::None(); *fixed_right_arg = Nothing<int>(); *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(); @@ -254,14 +324,24 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, } } - -Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) { +AstType* TypeFeedbackOracle::CountType(TypeFeedbackId id, + FeedbackVectorSlot slot) { Handle<Object> object = GetInfo(id); - if (!object->IsCode()) return Type::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()); } |