LCOV - code coverage report
Current view: top level - src - feedback-vector-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 71 74 95.9 %
Date: 2017-04-26 Functions: 16 16 100.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_FEEDBACK_VECTOR_INL_H_
       6             : #define V8_FEEDBACK_VECTOR_INL_H_
       7             : 
       8             : #include "src/factory.h"
       9             : #include "src/feedback-vector.h"
      10             : #include "src/globals.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : template <typename Derived>
      16    31521086 : FeedbackSlot FeedbackVectorSpecBase<Derived>::AddSlot(FeedbackSlotKind kind) {
      17             :   int slot = This()->slots();
      18    31521086 :   int entries_per_slot = FeedbackMetadata::GetSlotSize(kind);
      19             :   This()->append(kind);
      20    50868480 :   for (int i = 1; i < entries_per_slot; i++) {
      21             :     This()->append(FeedbackSlotKind::kInvalid);
      22             :   }
      23    31521097 :   return FeedbackSlot(slot);
      24             : }
      25             : 
      26             : template <typename Derived>
      27         102 : FeedbackSlot FeedbackVectorSpecBase<Derived>::AddTypeProfileSlot() {
      28             :   DCHECK(FLAG_type_profile);
      29         102 :   FeedbackSlot slot = AddSlot(FeedbackSlotKind::kTypeProfile);
      30         102 :   CHECK_EQ(FeedbackVectorSpec::kTypeProfileSlotIndex,
      31             :            FeedbackVector::GetIndex(slot));
      32         102 :   return slot;
      33             : }
      34             : 
      35             : // static
      36             : FeedbackMetadata* FeedbackMetadata::cast(Object* obj) {
      37             :   DCHECK(obj->IsFeedbackMetadata());
      38             :   return reinterpret_cast<FeedbackMetadata*>(obj);
      39             : }
      40             : 
      41             : bool FeedbackMetadata::is_empty() const {
      42           0 :   if (length() == 0) return true;
      43             :   return false;
      44             : }
      45             : 
      46    19263790 : int FeedbackMetadata::slot_count() const {
      47    19263790 :   if (length() == 0) return 0;
      48             :   DCHECK(length() > kReservedIndexCount);
      49    12887915 :   return Smi::cast(get(kSlotsCountIndex))->value();
      50             : }
      51             : 
      52             : // static
      53             : FeedbackVector* FeedbackVector::cast(Object* obj) {
      54             :   DCHECK(obj->IsFeedbackVector());
      55             :   return reinterpret_cast<FeedbackVector*>(obj);
      56             : }
      57             : 
      58   107864780 : int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
      59             :   switch (kind) {
      60             :     case FeedbackSlotKind::kGeneral:
      61             :     case FeedbackSlotKind::kCompareOp:
      62             :     case FeedbackSlotKind::kBinaryOp:
      63             :     case FeedbackSlotKind::kToBoolean:
      64             :     case FeedbackSlotKind::kLiteral:
      65             :     case FeedbackSlotKind::kCreateClosure:
      66             :     case FeedbackSlotKind::kTypeProfile:
      67             :       return 1;
      68             : 
      69             :     case FeedbackSlotKind::kCall:
      70             :     case FeedbackSlotKind::kLoadProperty:
      71             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
      72             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
      73             :     case FeedbackSlotKind::kLoadKeyed:
      74             :     case FeedbackSlotKind::kStoreNamedSloppy:
      75             :     case FeedbackSlotKind::kStoreNamedStrict:
      76             :     case FeedbackSlotKind::kStoreOwnNamed:
      77             :     case FeedbackSlotKind::kStoreGlobalSloppy:
      78             :     case FeedbackSlotKind::kStoreGlobalStrict:
      79             :     case FeedbackSlotKind::kStoreKeyedSloppy:
      80             :     case FeedbackSlotKind::kStoreKeyedStrict:
      81             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
      82    66919611 :       return 2;
      83             : 
      84             :     case FeedbackSlotKind::kInvalid:
      85             :     case FeedbackSlotKind::kKindsNumber:
      86           0 :       UNREACHABLE();
      87             :       break;
      88             :   }
      89             :   return 1;
      90             : }
      91             : 
      92             : bool FeedbackVector::is_empty() const {
      93             :   return length() == kReservedIndexCount;
      94             : }
      95             : 
      96     5419817 : int FeedbackVector::slot_count() const {
      97     7345739 :   return length() - kReservedIndexCount;
      98             : }
      99             : 
     100          98 : FeedbackMetadata* FeedbackVector::metadata() const {
     101          98 :   return shared_function_info()->feedback_metadata();
     102             : }
     103             : 
     104             : SharedFunctionInfo* FeedbackVector::shared_function_info() const {
     105             :   return SharedFunctionInfo::cast(get(kSharedFunctionInfoIndex));
     106             : }
     107             : 
     108             : int FeedbackVector::invocation_count() const {
     109             :   return Smi::cast(get(kInvocationCountIndex))->value();
     110             : }
     111             : 
     112             : void FeedbackVector::clear_invocation_count() {
     113             :   set(kInvocationCountIndex, Smi::kZero);
     114             : }
     115             : 
     116             : // Conversion from an integer index to either a slot or an ic slot.
     117             : // static
     118    39098874 : FeedbackSlot FeedbackVector::ToSlot(int index) {
     119             :   DCHECK_GE(index, kReservedIndexCount);
     120    47225053 :   return FeedbackSlot(index - kReservedIndexCount);
     121             : }
     122             : 
     123    21417549 : Object* FeedbackVector::Get(FeedbackSlot slot) const {
     124    21417549 :   return get(GetIndex(slot));
     125             : }
     126             : 
     127      727267 : void FeedbackVector::Set(FeedbackSlot slot, Object* value,
     128             :                          WriteBarrierMode mode) {
     129    15641528 :   set(GetIndex(slot), value, mode);
     130      727267 : }
     131             : 
     132             : // Helper function to transform the feedback to BinaryOperationHint.
     133             : BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
     134             :   switch (type_feedback) {
     135             :     case BinaryOperationFeedback::kNone:
     136             :       return BinaryOperationHint::kNone;
     137             :     case BinaryOperationFeedback::kSignedSmall:
     138             :       return BinaryOperationHint::kSignedSmall;
     139             :     case BinaryOperationFeedback::kNumber:
     140             :     case BinaryOperationFeedback::kNumberOrOddball:
     141             :       return BinaryOperationHint::kNumberOrOddball;
     142             :     case BinaryOperationFeedback::kString:
     143             :       return BinaryOperationHint::kString;
     144             :     case BinaryOperationFeedback::kAny:
     145             :     default:
     146             :       return BinaryOperationHint::kAny;
     147             :   }
     148             :   UNREACHABLE();
     149             :   return BinaryOperationHint::kNone;
     150             : }
     151             : 
     152             : // Helper function to transform the feedback to CompareOperationHint.
     153             : CompareOperationHint CompareOperationHintFromFeedback(int type_feedback) {
     154             :   switch (type_feedback) {
     155             :     case CompareOperationFeedback::kNone:
     156             :       return CompareOperationHint::kNone;
     157             :     case CompareOperationFeedback::kSignedSmall:
     158             :       return CompareOperationHint::kSignedSmall;
     159             :     case CompareOperationFeedback::kNumber:
     160             :       return CompareOperationHint::kNumber;
     161             :     case CompareOperationFeedback::kNumberOrOddball:
     162             :       return CompareOperationHint::kNumberOrOddball;
     163             :     case CompareOperationFeedback::kInternalizedString:
     164             :       return CompareOperationHint::kInternalizedString;
     165             :     case CompareOperationFeedback::kString:
     166             :       return CompareOperationHint::kString;
     167             :     case CompareOperationFeedback::kReceiver:
     168             :       return CompareOperationHint::kReceiver;
     169             :     default:
     170             :       return CompareOperationHint::kAny;
     171             :   }
     172             :   UNREACHABLE();
     173             :   return CompareOperationHint::kNone;
     174             : }
     175             : 
     176      179274 : void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
     177             :                                    int* vector_ic_count,
     178             :                                    bool code_is_interpreted) {
     179             :   Object* megamorphic_sentinel =
     180             :       *FeedbackVector::MegamorphicSentinel(GetIsolate());
     181             :   int with = 0;
     182             :   int gen = 0;
     183             :   int total = 0;
     184             :   FeedbackMetadataIterator iter(metadata());
     185     2604395 :   while (iter.HasNext()) {
     186     2425121 :     FeedbackSlot slot = iter.Next();
     187     2425121 :     FeedbackSlotKind kind = iter.kind();
     188             : 
     189             :     Object* const obj = Get(slot);
     190     2425121 :     switch (kind) {
     191             :       case FeedbackSlotKind::kCall:
     192             :       case FeedbackSlotKind::kLoadProperty:
     193             :       case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     194             :       case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     195             :       case FeedbackSlotKind::kLoadKeyed:
     196             :       case FeedbackSlotKind::kStoreNamedSloppy:
     197             :       case FeedbackSlotKind::kStoreNamedStrict:
     198             :       case FeedbackSlotKind::kStoreOwnNamed:
     199             :       case FeedbackSlotKind::kStoreGlobalSloppy:
     200             :       case FeedbackSlotKind::kStoreGlobalStrict:
     201             :       case FeedbackSlotKind::kStoreKeyedSloppy:
     202             :       case FeedbackSlotKind::kStoreKeyedStrict:
     203             :       case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     204             :       case FeedbackSlotKind::kTypeProfile: {
     205     2394893 :         if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
     206      598629 :           with++;
     207      583297 :         } else if (obj == megamorphic_sentinel) {
     208       70825 :           gen++;
     209       70825 :           if (code_is_interpreted) with++;
     210             :         }
     211     1181926 :         total++;
     212     1181926 :         break;
     213             :       }
     214             :       case FeedbackSlotKind::kBinaryOp:
     215             :         // If we are not running interpreted code, we need to ignore the special
     216             :         // IC slots for binaryop/compare used by the interpreter.
     217             :         // TODO(mvstanton): Remove code_is_interpreted when full code is retired
     218             :         // from service.
     219      816818 :         if (code_is_interpreted) {
     220             :           int const feedback = Smi::cast(obj)->value();
     221             :           BinaryOperationHint hint = BinaryOperationHintFromFeedback(feedback);
     222      181915 :           if (hint == BinaryOperationHint::kAny) {
     223        1559 :             gen++;
     224             :           }
     225      181915 :           if (hint != BinaryOperationHint::kNone) {
     226      138781 :             with++;
     227             :           }
     228      181915 :           total++;
     229             :         }
     230             :         break;
     231             :       case FeedbackSlotKind::kCompareOp: {
     232             :         // If we are not running interpreted code, we need to ignore the special
     233             :         // IC slots for binaryop/compare used by the interpreter.
     234             :         // TODO(mvstanton): Remove code_is_interpreted when full code is retired
     235             :         // from service.
     236      374723 :         if (code_is_interpreted) {
     237             :           int const feedback = Smi::cast(obj)->value();
     238             :           CompareOperationHint hint =
     239             :               CompareOperationHintFromFeedback(feedback);
     240       87275 :           if (hint == CompareOperationHint::kAny) {
     241        7681 :             gen++;
     242             :           }
     243       87275 :           if (hint != CompareOperationHint::kNone) {
     244       55581 :             with++;
     245             :           }
     246       87275 :           total++;
     247             :         }
     248             :         break;
     249             :       }
     250             :       case FeedbackSlotKind::kToBoolean:
     251             :       case FeedbackSlotKind::kCreateClosure:
     252             :       case FeedbackSlotKind::kGeneral:
     253             :       case FeedbackSlotKind::kLiteral:
     254             :         break;
     255             :       case FeedbackSlotKind::kInvalid:
     256             :       case FeedbackSlotKind::kKindsNumber:
     257           0 :         UNREACHABLE();
     258             :         break;
     259             :     }
     260             :   }
     261             : 
     262      179274 :   *with_type_info = with;
     263      179274 :   *generic = gen;
     264      179274 :   *vector_ic_count = total;
     265      179274 : }
     266             : 
     267             : Handle<Symbol> FeedbackVector::UninitializedSentinel(Isolate* isolate) {
     268             :   return isolate->factory()->uninitialized_symbol();
     269             : }
     270             : 
     271             : Handle<Symbol> FeedbackVector::MegamorphicSentinel(Isolate* isolate) {
     272             :   return isolate->factory()->megamorphic_symbol();
     273             : }
     274             : 
     275             : Handle<Symbol> FeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
     276             :   return isolate->factory()->premonomorphic_symbol();
     277             : }
     278             : 
     279             : Symbol* FeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
     280       92305 :   return isolate->heap()->uninitialized_symbol();
     281             : }
     282             : 
     283     2976204 : bool FeedbackMetadataIterator::HasNext() const {
     284     2976204 :   return next_slot_.ToInt() < metadata()->slot_count();
     285             : }
     286             : 
     287     2704625 : FeedbackSlot FeedbackMetadataIterator::Next() {
     288             :   DCHECK(HasNext());
     289     2704625 :   cur_slot_ = next_slot_;
     290     2704625 :   slot_kind_ = metadata()->GetKind(cur_slot_);
     291     2704625 :   next_slot_ = FeedbackSlot(next_slot_.ToInt() + entry_size());
     292     2704625 :   return cur_slot_;
     293             : }
     294             : 
     295             : int FeedbackMetadataIterator::entry_size() const {
     296     2704625 :   return FeedbackMetadata::GetSlotSize(kind());
     297             : }
     298             : 
     299    54696672 : Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
     300             : 
     301     3529351 : Object* FeedbackNexus::GetFeedbackExtra() const {
     302             : #ifdef DEBUG
     303             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     304             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     305             : #endif
     306     3529351 :   int extra_index = vector()->GetIndex(slot()) + 1;
     307     3529351 :   return vector()->get(extra_index);
     308             : }
     309             : 
     310    14598800 : void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
     311             :   vector()->Set(slot(), feedback, mode);
     312    14598804 : }
     313             : 
     314    14635804 : void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
     315             :                                      WriteBarrierMode mode) {
     316             : #ifdef DEBUG
     317             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     318             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     319             : #endif
     320    14635804 :   int index = vector()->GetIndex(slot()) + 1;
     321    14635804 :   vector()->set(index, feedback_extra, mode);
     322    14635801 : }
     323             : 
     324             : Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
     325             : }  // namespace internal
     326             : }  // namespace v8
     327             : 
     328             : #endif  // V8_FEEDBACK_VECTOR_INL_H_

Generated by: LCOV version 1.10