LCOV - code coverage report
Current view: top level - src - feedback-vector-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 52 90 57.8 %
Date: 2017-10-20 Functions: 16 18 88.9 %

          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-inl.h"
       9             : #include "src/feedback-vector.h"
      10             : #include "src/globals.h"
      11             : #include "src/heap/heap-inl.h"
      12             : #include "src/heap/heap.h"
      13             : #include "src/objects/shared-function-info.h"
      14             : 
      15             : // Has to be the last include (doesn't have include guards):
      16             : #include "src/objects/object-macros.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : 
      21             : // static
      22             : FeedbackMetadata* FeedbackMetadata::cast(Object* obj) {
      23             :   DCHECK(obj->IsFeedbackMetadata());
      24             :   return reinterpret_cast<FeedbackMetadata*>(obj);
      25             : }
      26             : 
      27             : bool FeedbackMetadata::is_empty() const {
      28         400 :   if (length() == 0) return true;
      29             :   return false;
      30             : }
      31             : 
      32    17230494 : int FeedbackMetadata::slot_count() const {
      33    17230494 :   if (length() == 0) return 0;
      34             :   DCHECK_GT(length(), kReservedIndexCount);
      35     8608335 :   return Smi::ToInt(get(kSlotsCountIndex));
      36             : }
      37             : 
      38             : // static
      39     7442042 : FeedbackVector* FeedbackVector::cast(Object* obj) {
      40             :   DCHECK(obj->IsFeedbackVector());
      41     7442042 :   return reinterpret_cast<FeedbackVector*>(obj);
      42             : }
      43             : 
      44    69311119 : int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
      45             :   switch (kind) {
      46             :     case FeedbackSlotKind::kForIn:
      47             :     case FeedbackSlotKind::kCompareOp:
      48             :     case FeedbackSlotKind::kBinaryOp:
      49             :     case FeedbackSlotKind::kLiteral:
      50             :     case FeedbackSlotKind::kCreateClosure:
      51             :     case FeedbackSlotKind::kTypeProfile:
      52             :       return 1;
      53             : 
      54             :     case FeedbackSlotKind::kCall:
      55             :     case FeedbackSlotKind::kLoadProperty:
      56             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
      57             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
      58             :     case FeedbackSlotKind::kLoadKeyed:
      59             :     case FeedbackSlotKind::kStoreNamedSloppy:
      60             :     case FeedbackSlotKind::kStoreNamedStrict:
      61             :     case FeedbackSlotKind::kStoreOwnNamed:
      62             :     case FeedbackSlotKind::kStoreGlobalSloppy:
      63             :     case FeedbackSlotKind::kStoreGlobalStrict:
      64             :     case FeedbackSlotKind::kStoreKeyedSloppy:
      65             :     case FeedbackSlotKind::kStoreKeyedStrict:
      66             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
      67    45339234 :       return 2;
      68             : 
      69             :     case FeedbackSlotKind::kInvalid:
      70             :     case FeedbackSlotKind::kKindsNumber:
      71           0 :       UNREACHABLE();
      72             :       break;
      73             :   }
      74             :   return 1;
      75             : }
      76             : 
      77    52795149 : ACCESSORS(FeedbackVector, shared_function_info, SharedFunctionInfo,
      78             :           kSharedFunctionInfoOffset)
      79    53105547 : ACCESSORS(FeedbackVector, optimized_code_cell, Object, kOptimizedCodeOffset)
      80    39547817 : INT32_ACCESSORS(FeedbackVector, length, kLengthOffset)
      81     6970041 : INT32_ACCESSORS(FeedbackVector, invocation_count, kInvocationCountOffset)
      82    12812087 : INT32_ACCESSORS(FeedbackVector, profiler_ticks, kProfilerTicksOffset)
      83     6398808 : INT32_ACCESSORS(FeedbackVector, deopt_count, kDeoptCountOffset)
      84             : 
      85           9 : bool FeedbackVector::is_empty() const { return length() == 0; }
      86             : 
      87           0 : FeedbackMetadata* FeedbackVector::metadata() const {
      88           0 :   return shared_function_info()->feedback_metadata();
      89             : }
      90             : 
      91             : void FeedbackVector::clear_invocation_count() { set_invocation_count(0); }
      92             : 
      93             : void FeedbackVector::increment_deopt_count() {
      94             :   int count = deopt_count();
      95       34444 :   if (count < std::numeric_limits<int32_t>::max()) {
      96       34444 :     set_deopt_count(count + 1);
      97             :   }
      98             : }
      99             : 
     100             : Code* FeedbackVector::optimized_code() const {
     101             :   Object* slot = optimized_code_cell();
     102    10934604 :   if (slot->IsSmi()) return nullptr;
     103             :   WeakCell* cell = WeakCell::cast(slot);
     104     1051172 :   return cell->cleared() ? nullptr : Code::cast(cell->value());
     105             : }
     106             : 
     107             : OptimizationMarker FeedbackVector::optimization_marker() const {
     108             :   Object* slot = optimized_code_cell();
     109      712989 :   if (!slot->IsSmi()) return OptimizationMarker::kNone;
     110             :   Smi* value = Smi::cast(slot);
     111             :   return static_cast<OptimizationMarker>(value->value());
     112             : }
     113             : 
     114             : bool FeedbackVector::has_optimized_code() const {
     115             :   return optimized_code() != nullptr;
     116             : }
     117             : 
     118             : bool FeedbackVector::has_optimization_marker() const {
     119             :   return optimization_marker() != OptimizationMarker::kNone;
     120             : }
     121             : 
     122             : // Conversion from an integer index to either a slot or an ic slot.
     123             : // static
     124    17899423 : FeedbackSlot FeedbackVector::ToSlot(int index) {
     125             :   DCHECK_GE(index, 0);
     126    17899423 :   return FeedbackSlot(index);
     127             : }
     128             : 
     129     7334287 : Object* FeedbackVector::Get(FeedbackSlot slot) const {
     130     7334287 :   return get(GetIndex(slot));
     131             : }
     132             : 
     133             : Object* FeedbackVector::get(int index) const {
     134             :   DCHECK_GE(index, 0);
     135             :   DCHECK_LT(index, this->length());
     136    28722807 :   int offset = kFeedbackSlotsOffset + index * kPointerSize;
     137    57445680 :   return RELAXED_READ_FIELD(this, offset);
     138             : }
     139             : 
     140       15754 : void FeedbackVector::Set(FeedbackSlot slot, Object* value,
     141             :                          WriteBarrierMode mode) {
     142    10160322 :   set(GetIndex(slot), value, mode);
     143       15754 : }
     144             : 
     145    69945680 : void FeedbackVector::set(int index, Object* value, WriteBarrierMode mode) {
     146             :   DCHECK_GE(index, 0);
     147             :   DCHECK_LT(index, this->length());
     148    69945680 :   int offset = kFeedbackSlotsOffset + index * kPointerSize;
     149    69945680 :   RELAXED_WRITE_FIELD(this, offset, value);
     150    99638277 :   CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
     151    69945682 : }
     152             : 
     153             : inline Object** FeedbackVector::slots_start() {
     154             :   return HeapObject::RawField(this, kFeedbackSlotsOffset);
     155             : }
     156             : 
     157             : // Helper function to transform the feedback to BinaryOperationHint.
     158             : BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
     159             :   switch (type_feedback) {
     160             :     case BinaryOperationFeedback::kNone:
     161             :       return BinaryOperationHint::kNone;
     162             :     case BinaryOperationFeedback::kSignedSmall:
     163             :       return BinaryOperationHint::kSignedSmall;
     164             :     case BinaryOperationFeedback::kSignedSmallInputs:
     165             :       return BinaryOperationHint::kSignedSmallInputs;
     166             :     case BinaryOperationFeedback::kNumber:
     167             :       return BinaryOperationHint::kNumber;
     168             :     case BinaryOperationFeedback::kNumberOrOddball:
     169             :       return BinaryOperationHint::kNumberOrOddball;
     170             :     case BinaryOperationFeedback::kString:
     171             :       return BinaryOperationHint::kString;
     172             :     case BinaryOperationFeedback::kBigInt:
     173             :     // TODO(jarin/jkummerow/neis): Support BigInts in TF.
     174             :     // Fall through for now.
     175             :     case BinaryOperationFeedback::kAny:
     176             :     default:
     177             :       return BinaryOperationHint::kAny;
     178             :   }
     179             :   UNREACHABLE();
     180             : }
     181             : 
     182             : // Helper function to transform the feedback to CompareOperationHint.
     183             : CompareOperationHint CompareOperationHintFromFeedback(int type_feedback) {
     184             :   switch (type_feedback) {
     185             :     case CompareOperationFeedback::kNone:
     186             :       return CompareOperationHint::kNone;
     187             :     case CompareOperationFeedback::kSignedSmall:
     188             :       return CompareOperationHint::kSignedSmall;
     189             :     case CompareOperationFeedback::kNumber:
     190             :       return CompareOperationHint::kNumber;
     191             :     case CompareOperationFeedback::kNumberOrOddball:
     192             :       return CompareOperationHint::kNumberOrOddball;
     193             :     case CompareOperationFeedback::kInternalizedString:
     194             :       return CompareOperationHint::kInternalizedString;
     195             :     case CompareOperationFeedback::kString:
     196             :       return CompareOperationHint::kString;
     197             :     case CompareOperationFeedback::kSymbol:
     198             :       return CompareOperationHint::kSymbol;
     199             :     case CompareOperationFeedback::kReceiver:
     200             :       return CompareOperationHint::kReceiver;
     201             :     default:
     202             :       return CompareOperationHint::kAny;
     203             :   }
     204             :   UNREACHABLE();
     205             : }
     206             : 
     207             : // Helper function to transform the feedback to ForInHint.
     208             : ForInHint ForInHintFromFeedback(int type_feedback) {
     209             :   switch (type_feedback) {
     210             :     case ForInFeedback::kNone:
     211             :       return ForInHint::kNone;
     212             :     case ForInFeedback::kEnumCacheKeys:
     213             :       return ForInHint::kEnumCacheKeys;
     214             :     case ForInFeedback::kEnumCacheKeysAndIndices:
     215             :       return ForInHint::kEnumCacheKeysAndIndices;
     216             :     default:
     217             :       return ForInHint::kAny;
     218             :   }
     219             :   UNREACHABLE();
     220             : }
     221             : 
     222           0 : void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
     223             :                                    int* vector_ic_count) {
     224             :   Object* megamorphic_sentinel =
     225             :       *FeedbackVector::MegamorphicSentinel(GetIsolate());
     226             :   int with = 0;
     227             :   int gen = 0;
     228             :   int total = 0;
     229             :   FeedbackMetadataIterator iter(metadata());
     230           0 :   while (iter.HasNext()) {
     231           0 :     FeedbackSlot slot = iter.Next();
     232           0 :     FeedbackSlotKind kind = iter.kind();
     233             : 
     234             :     Object* const obj = Get(slot);
     235           0 :     switch (kind) {
     236             :       case FeedbackSlotKind::kCall:
     237             :       case FeedbackSlotKind::kLoadProperty:
     238             :       case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     239             :       case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     240             :       case FeedbackSlotKind::kLoadKeyed:
     241             :       case FeedbackSlotKind::kStoreNamedSloppy:
     242             :       case FeedbackSlotKind::kStoreNamedStrict:
     243             :       case FeedbackSlotKind::kStoreOwnNamed:
     244             :       case FeedbackSlotKind::kStoreGlobalSloppy:
     245             :       case FeedbackSlotKind::kStoreGlobalStrict:
     246             :       case FeedbackSlotKind::kStoreKeyedSloppy:
     247             :       case FeedbackSlotKind::kStoreKeyedStrict:
     248             :       case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     249             :       case FeedbackSlotKind::kTypeProfile: {
     250           0 :         if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
     251           0 :           with++;
     252           0 :         } else if (obj == megamorphic_sentinel) {
     253           0 :           gen++;
     254           0 :           with++;
     255             :         }
     256           0 :         total++;
     257           0 :         break;
     258             :       }
     259             :       case FeedbackSlotKind::kBinaryOp: {
     260             :         int const feedback = Smi::ToInt(obj);
     261             :         BinaryOperationHint hint = BinaryOperationHintFromFeedback(feedback);
     262           0 :         if (hint == BinaryOperationHint::kAny) {
     263           0 :           gen++;
     264             :         }
     265           0 :         if (hint != BinaryOperationHint::kNone) {
     266           0 :           with++;
     267             :         }
     268           0 :         total++;
     269           0 :         break;
     270             :       }
     271             :       case FeedbackSlotKind::kCompareOp: {
     272             :           int const feedback = Smi::ToInt(obj);
     273             :           CompareOperationHint hint =
     274             :               CompareOperationHintFromFeedback(feedback);
     275           0 :           if (hint == CompareOperationHint::kAny) {
     276           0 :             gen++;
     277             :           }
     278           0 :           if (hint != CompareOperationHint::kNone) {
     279           0 :             with++;
     280             :           }
     281           0 :           total++;
     282           0 :         break;
     283             :       }
     284             :       case FeedbackSlotKind::kForIn: {
     285             :         int const feedback = Smi::ToInt(obj);
     286             :         ForInHint hint = ForInHintFromFeedback(feedback);
     287           0 :         if (hint == ForInHint::kAny) {
     288           0 :           gen++;
     289             :         }
     290           0 :         if (hint != ForInHint::kNone) {
     291           0 :           with++;
     292             :         }
     293           0 :         total++;
     294           0 :         break;
     295             :       }
     296             :       case FeedbackSlotKind::kCreateClosure:
     297             :       case FeedbackSlotKind::kLiteral:
     298             :         break;
     299             :       case FeedbackSlotKind::kInvalid:
     300             :       case FeedbackSlotKind::kKindsNumber:
     301           0 :         UNREACHABLE();
     302             :         break;
     303             :     }
     304             :   }
     305             : 
     306           0 :   *with_type_info = with;
     307           0 :   *generic = gen;
     308           0 :   *vector_ic_count = total;
     309           0 : }
     310             : 
     311             : Handle<Symbol> FeedbackVector::UninitializedSentinel(Isolate* isolate) {
     312             :   return isolate->factory()->uninitialized_symbol();
     313             : }
     314             : 
     315             : Handle<Symbol> FeedbackVector::GenericSentinel(Isolate* isolate) {
     316             :   return isolate->factory()->generic_symbol();
     317             : }
     318             : 
     319             : Handle<Symbol> FeedbackVector::MegamorphicSentinel(Isolate* isolate) {
     320             :   return isolate->factory()->megamorphic_symbol();
     321             : }
     322             : 
     323             : Handle<Symbol> FeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
     324             :   return isolate->factory()->premonomorphic_symbol();
     325             : }
     326             : 
     327             : Symbol* FeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
     328       67308 :   return isolate->heap()->uninitialized_symbol();
     329             : }
     330             : 
     331      301066 : bool FeedbackMetadataIterator::HasNext() const {
     332      301066 :   return next_slot_.ToInt() < metadata()->slot_count();
     333             : }
     334             : 
     335      233655 : FeedbackSlot FeedbackMetadataIterator::Next() {
     336             :   DCHECK(HasNext());
     337      233655 :   cur_slot_ = next_slot_;
     338      233655 :   slot_kind_ = metadata()->GetKind(cur_slot_);
     339      233655 :   next_slot_ = FeedbackSlot(next_slot_.ToInt() + entry_size());
     340      233655 :   return cur_slot_;
     341             : }
     342             : 
     343             : int FeedbackMetadataIterator::entry_size() const {
     344      233655 :   return FeedbackMetadata::GetSlotSize(kind());
     345             : }
     346             : 
     347    31697392 : Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
     348             : 
     349     2988609 : Object* FeedbackNexus::GetFeedbackExtra() const {
     350             : #ifdef DEBUG
     351             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     352             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     353             : #endif
     354             :   int extra_index = vector()->GetIndex(slot()) + 1;
     355     2988609 :   return vector()->get(extra_index);
     356             : }
     357             : 
     358     9535376 : void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
     359             :   vector()->Set(slot(), feedback, mode);
     360     9535379 : }
     361             : 
     362     9539671 : void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
     363             :                                      WriteBarrierMode mode) {
     364             : #ifdef DEBUG
     365             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     366             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     367             : #endif
     368     9539671 :   int index = vector()->GetIndex(slot()) + 1;
     369     9539671 :   vector()->set(index, feedback_extra, mode);
     370     9539670 : }
     371             : 
     372             : Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
     373             : }  // namespace internal
     374             : }  // namespace v8
     375             : 
     376             : #include "src/objects/object-macros-undef.h"
     377             : 
     378             : #endif  // V8_FEEDBACK_VECTOR_INL_H_

Generated by: LCOV version 1.10