LCOV - code coverage report
Current view: top level - src - feedback-vector-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 73 74 98.6 %
Date: 2019-04-19 Functions: 14 14 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/feedback-vector.h"
       9             : 
      10             : #include "src/globals.h"
      11             : #include "src/heap/factory-inl.h"
      12             : #include "src/heap/heap-write-barrier-inl.h"
      13             : #include "src/objects/code-inl.h"
      14             : #include "src/objects/maybe-object-inl.h"
      15             : #include "src/objects/shared-function-info.h"
      16             : #include "src/objects/smi.h"
      17             : 
      18             : // Has to be the last include (doesn't have include guards):
      19             : #include "src/objects/object-macros.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : OBJECT_CONSTRUCTORS_IMPL(FeedbackVector, HeapObject)
      25             : OBJECT_CONSTRUCTORS_IMPL(FeedbackMetadata, HeapObject)
      26             : OBJECT_CONSTRUCTORS_IMPL(ClosureFeedbackCellArray, FixedArray)
      27             : 
      28             : NEVER_READ_ONLY_SPACE_IMPL(FeedbackVector)
      29             : NEVER_READ_ONLY_SPACE_IMPL(ClosureFeedbackCellArray)
      30             : 
      31             : CAST_ACCESSOR(FeedbackVector)
      32             : CAST_ACCESSOR(FeedbackMetadata)
      33             : CAST_ACCESSOR(ClosureFeedbackCellArray)
      34             : 
      35     7952307 : INT32_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
      36             : 
      37     4715598 : INT32_ACCESSORS(FeedbackMetadata, closure_feedback_cell_count,
      38             :                 kFeedbackCellCountOffset)
      39             : 
      40             : int32_t FeedbackMetadata::synchronized_slot_count() const {
      41     5361501 :   return base::Acquire_Load(reinterpret_cast<const base::Atomic32*>(
      42     5361501 :       FIELD_ADDR(*this, kSlotCountOffset)));
      43             : }
      44             : 
      45             : int32_t FeedbackMetadata::get(int index) const {
      46             :   DCHECK(index >= 0 && index < length());
      47    69959508 :   int offset = kHeaderSize + index * kInt32Size;
      48    69959928 :   return READ_INT32_FIELD(*this, offset);
      49             : }
      50             : 
      51             : void FeedbackMetadata::set(int index, int32_t value) {
      52             :   DCHECK(index >= 0 && index < length());
      53             :   int offset = kHeaderSize + index * kInt32Size;
      54    25982185 :   WRITE_INT32_FIELD(*this, offset, value);
      55             : }
      56             : 
      57             : bool FeedbackMetadata::is_empty() const { return slot_count() == 0; }
      58             : 
      59             : int FeedbackMetadata::length() const {
      60             :   return FeedbackMetadata::length(slot_count());
      61             : }
      62             : 
      63    35711394 : int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
      64             :   switch (kind) {
      65             :     case FeedbackSlotKind::kForIn:
      66             :     case FeedbackSlotKind::kInstanceOf:
      67             :     case FeedbackSlotKind::kCompareOp:
      68             :     case FeedbackSlotKind::kBinaryOp:
      69             :     case FeedbackSlotKind::kLiteral:
      70             :     case FeedbackSlotKind::kTypeProfile:
      71             :       return 1;
      72             : 
      73             :     case FeedbackSlotKind::kCall:
      74             :     case FeedbackSlotKind::kCloneObject:
      75             :     case FeedbackSlotKind::kLoadProperty:
      76             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
      77             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
      78             :     case FeedbackSlotKind::kLoadKeyed:
      79             :     case FeedbackSlotKind::kHasKeyed:
      80             :     case FeedbackSlotKind::kStoreNamedSloppy:
      81             :     case FeedbackSlotKind::kStoreNamedStrict:
      82             :     case FeedbackSlotKind::kStoreOwnNamed:
      83             :     case FeedbackSlotKind::kStoreGlobalSloppy:
      84             :     case FeedbackSlotKind::kStoreGlobalStrict:
      85             :     case FeedbackSlotKind::kStoreKeyedSloppy:
      86             :     case FeedbackSlotKind::kStoreKeyedStrict:
      87             :     case FeedbackSlotKind::kStoreInArrayLiteral:
      88             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
      89    30314617 :       return 2;
      90             : 
      91             :     case FeedbackSlotKind::kInvalid:
      92             :     case FeedbackSlotKind::kKindsNumber:
      93           0 :       UNREACHABLE();
      94             :       break;
      95             :   }
      96             :   return 1;
      97             : }
      98             : 
      99      788051 : Handle<FeedbackCell> ClosureFeedbackCellArray::GetFeedbackCell(int index) {
     100      788051 :   return handle(FeedbackCell::cast(get(index)), GetIsolate());
     101             : }
     102             : 
     103    38496293 : ACCESSORS(FeedbackVector, shared_function_info, SharedFunctionInfo,
     104             :           kSharedFunctionInfoOffset)
     105    34799437 : WEAK_ACCESSORS(FeedbackVector, optimized_code_weak_or_smi, kOptimizedCodeOffset)
     106    16110368 : ACCESSORS(FeedbackVector, closure_feedback_cell_array, ClosureFeedbackCellArray,
     107             :           kClosureFeedbackCellArrayOffset)
     108    16070297 : INT32_ACCESSORS(FeedbackVector, length, kLengthOffset)
     109     3642269 : INT32_ACCESSORS(FeedbackVector, invocation_count, kInvocationCountOffset)
     110     7128080 : INT32_ACCESSORS(FeedbackVector, profiler_ticks, kProfilerTicksOffset)
     111     3168501 : INT32_ACCESSORS(FeedbackVector, deopt_count, kDeoptCountOffset)
     112             : 
     113           7 : bool FeedbackVector::is_empty() const { return length() == 0; }
     114             : 
     115             : FeedbackMetadata FeedbackVector::metadata() const {
     116             :   return shared_function_info()->feedback_metadata();
     117             : }
     118             : 
     119             : void FeedbackVector::clear_invocation_count() { set_invocation_count(0); }
     120             : 
     121             : void FeedbackVector::increment_deopt_count() {
     122             :   int count = deopt_count();
     123       33206 :   if (count < std::numeric_limits<int32_t>::max()) {
     124       33206 :     set_deopt_count(count + 1);
     125             :   }
     126             : }
     127             : 
     128             : Code FeedbackVector::optimized_code() const {
     129             :   MaybeObject slot = optimized_code_weak_or_smi();
     130             :   DCHECK(slot->IsSmi() || slot->IsWeakOrCleared());
     131             :   HeapObject heap_object;
     132     7384824 :   return slot->GetHeapObject(&heap_object) ? Code::cast(heap_object) : Code();
     133             : }
     134             : 
     135             : OptimizationMarker FeedbackVector::optimization_marker() const {
     136             :   MaybeObject slot = optimized_code_weak_or_smi();
     137             :   Smi value;
     138     1515974 :   if (!slot->ToSmi(&value)) return OptimizationMarker::kNone;
     139             :   return static_cast<OptimizationMarker>(value->value());
     140             : }
     141             : 
     142             : bool FeedbackVector::has_optimized_code() const {
     143             :   return !optimized_code().is_null();
     144             : }
     145             : 
     146      489609 : bool FeedbackVector::has_optimization_marker() const {
     147      979217 :   return optimization_marker() != OptimizationMarker::kLogFirstExecution &&
     148      489609 :          optimization_marker() != OptimizationMarker::kNone;
     149             : }
     150             : 
     151             : // Conversion from an integer index to either a slot or an ic slot.
     152             : // static
     153             : FeedbackSlot FeedbackVector::ToSlot(int index) {
     154             :   DCHECK_GE(index, 0);
     155             :   return FeedbackSlot(index);
     156             : }
     157             : 
     158             : MaybeObject FeedbackVector::Get(FeedbackSlot slot) const {
     159             :   return get(GetIndex(slot));
     160             : }
     161             : 
     162             : MaybeObject FeedbackVector::get(int index) const {
     163             :   DCHECK_GE(index, 0);
     164             :   DCHECK_LT(index, this->length());
     165    25957572 :   int offset = kFeedbackSlotsOffset + index * kTaggedSize;
     166    25957602 :   return RELAXED_READ_WEAK_FIELD(*this, offset);
     167             : }
     168             : 
     169             : Handle<FeedbackCell> FeedbackVector::GetClosureFeedbackCell(int index) const {
     170             :   DCHECK_GE(index, 0);
     171             :   ClosureFeedbackCellArray cell_array =
     172      441931 :       ClosureFeedbackCellArray::cast(closure_feedback_cell_array());
     173      441931 :   return cell_array->GetFeedbackCell(index);
     174             : }
     175             : 
     176             : void FeedbackVector::Set(FeedbackSlot slot, MaybeObject value,
     177             :                          WriteBarrierMode mode) {
     178     8791969 :   set(GetIndex(slot), value, mode);
     179             : }
     180             : 
     181    56612253 : void FeedbackVector::set(int index, MaybeObject value, WriteBarrierMode mode) {
     182             :   DCHECK_GE(index, 0);
     183             :   DCHECK_LT(index, this->length());
     184    56612253 :   int offset = kFeedbackSlotsOffset + index * kTaggedSize;
     185    56612253 :   RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
     186    79993647 :   CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);
     187    56612280 : }
     188             : 
     189             : void FeedbackVector::Set(FeedbackSlot slot, Object value,
     190             :                          WriteBarrierMode mode) {
     191      261548 :   set(GetIndex(slot), MaybeObject::FromObject(value), mode);
     192             : }
     193             : 
     194             : void FeedbackVector::set(int index, Object value, WriteBarrierMode mode) {
     195    32439954 :   set(index, MaybeObject::FromObject(value), mode);
     196             : }
     197             : 
     198             : inline MaybeObjectSlot FeedbackVector::slots_start() {
     199             :   return RawMaybeWeakField(kFeedbackSlotsOffset);
     200             : }
     201             : 
     202             : // Helper function to transform the feedback to BinaryOperationHint.
     203             : BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
     204             :   switch (type_feedback) {
     205             :     case BinaryOperationFeedback::kNone:
     206             :       return BinaryOperationHint::kNone;
     207             :     case BinaryOperationFeedback::kSignedSmall:
     208             :       return BinaryOperationHint::kSignedSmall;
     209             :     case BinaryOperationFeedback::kSignedSmallInputs:
     210             :       return BinaryOperationHint::kSignedSmallInputs;
     211             :     case BinaryOperationFeedback::kNumber:
     212             :       return BinaryOperationHint::kNumber;
     213             :     case BinaryOperationFeedback::kNumberOrOddball:
     214             :       return BinaryOperationHint::kNumberOrOddball;
     215             :     case BinaryOperationFeedback::kString:
     216             :       return BinaryOperationHint::kString;
     217             :     case BinaryOperationFeedback::kBigInt:
     218             :       return BinaryOperationHint::kBigInt;
     219             :     default:
     220             :       return BinaryOperationHint::kAny;
     221             :   }
     222             :   UNREACHABLE();
     223             : }
     224             : 
     225             : // Helper function to transform the feedback to CompareOperationHint.
     226      527087 : CompareOperationHint CompareOperationHintFromFeedback(int type_feedback) {
     227      527087 :   switch (type_feedback) {
     228             :     case CompareOperationFeedback::kNone:
     229             :       return CompareOperationHint::kNone;
     230             :     case CompareOperationFeedback::kSignedSmall:
     231      183891 :       return CompareOperationHint::kSignedSmall;
     232             :     case CompareOperationFeedback::kNumber:
     233       30509 :       return CompareOperationHint::kNumber;
     234             :     case CompareOperationFeedback::kNumberOrOddball:
     235          21 :       return CompareOperationHint::kNumberOrOddball;
     236             :     case CompareOperationFeedback::kInternalizedString:
     237       16908 :       return CompareOperationHint::kInternalizedString;
     238             :     case CompareOperationFeedback::kString:
     239       27975 :       return CompareOperationHint::kString;
     240             :     case CompareOperationFeedback::kSymbol:
     241         117 :       return CompareOperationHint::kSymbol;
     242             :     case CompareOperationFeedback::kBigInt:
     243         148 :       return CompareOperationHint::kBigInt;
     244             :     case CompareOperationFeedback::kReceiver:
     245        2113 :       return CompareOperationHint::kReceiver;
     246             :     case CompareOperationFeedback::kReceiverOrNullOrUndefined:
     247         347 :       return CompareOperationHint::kReceiverOrNullOrUndefined;
     248             :     default:
     249       73009 :       return CompareOperationHint::kAny;
     250             :   }
     251             :   UNREACHABLE();
     252             : }
     253             : 
     254             : // Helper function to transform the feedback to ForInHint.
     255             : ForInHint ForInHintFromFeedback(int type_feedback) {
     256             :   switch (type_feedback) {
     257             :     case ForInFeedback::kNone:
     258             :       return ForInHint::kNone;
     259             :     case ForInFeedback::kEnumCacheKeys:
     260             :       return ForInHint::kEnumCacheKeys;
     261             :     case ForInFeedback::kEnumCacheKeysAndIndices:
     262             :       return ForInHint::kEnumCacheKeysAndIndices;
     263             :     default:
     264             :       return ForInHint::kAny;
     265             :   }
     266             :   UNREACHABLE();
     267             : }
     268             : 
     269             : Handle<Symbol> FeedbackVector::UninitializedSentinel(Isolate* isolate) {
     270             :   return isolate->factory()->uninitialized_symbol();
     271             : }
     272             : 
     273             : Handle<Symbol> FeedbackVector::GenericSentinel(Isolate* isolate) {
     274             :   return isolate->factory()->generic_symbol();
     275             : }
     276             : 
     277             : Handle<Symbol> FeedbackVector::MegamorphicSentinel(Isolate* isolate) {
     278             :   return isolate->factory()->megamorphic_symbol();
     279             : }
     280             : 
     281             : Handle<Symbol> FeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
     282             :   return isolate->factory()->premonomorphic_symbol();
     283             : }
     284             : 
     285             : Symbol FeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
     286             :   return ReadOnlyRoots(isolate).uninitialized_symbol();
     287             : }
     288             : 
     289             : bool FeedbackMetadataIterator::HasNext() const {
     290             :   return next_slot_.ToInt() < metadata()->slot_count();
     291             : }
     292             : 
     293       81358 : FeedbackSlot FeedbackMetadataIterator::Next() {
     294             :   DCHECK(HasNext());
     295       81358 :   cur_slot_ = next_slot_;
     296       81358 :   slot_kind_ = metadata()->GetKind(cur_slot_);
     297       81358 :   next_slot_ = FeedbackSlot(next_slot_.ToInt() + entry_size());
     298       81358 :   return cur_slot_;
     299             : }
     300             : 
     301             : int FeedbackMetadataIterator::entry_size() const {
     302       81358 :   return FeedbackMetadata::GetSlotSize(kind());
     303             : }
     304             : 
     305    17035450 : MaybeObject FeedbackNexus::GetFeedback() const {
     306             :   MaybeObject feedback = vector()->Get(slot());
     307      415730 :   FeedbackVector::AssertNoLegacyTypes(feedback);
     308    17035450 :   return feedback;
     309             : }
     310             : 
     311     7272443 : MaybeObject FeedbackNexus::GetFeedbackExtra() const {
     312             : #ifdef DEBUG
     313             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     314             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     315             : #endif
     316             :   int extra_index = vector()->GetIndex(slot()) + 1;
     317     7272443 :   return vector()->get(extra_index);
     318             : }
     319             : 
     320             : void FeedbackNexus::SetFeedback(Object feedback, WriteBarrierMode mode) {
     321     1011565 :   SetFeedback(MaybeObject::FromObject(feedback));
     322             : }
     323             : 
     324     8791964 : void FeedbackNexus::SetFeedback(MaybeObject feedback, WriteBarrierMode mode) {
     325             :   FeedbackVector::AssertNoLegacyTypes(feedback);
     326    17583946 :   vector()->Set(slot(), feedback, mode);
     327     8791982 : }
     328             : 
     329     6132775 : void FeedbackNexus::SetFeedbackExtra(Object feedback_extra,
     330             :                                      WriteBarrierMode mode) {
     331             : #ifdef DEBUG
     332             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     333             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     334             :   FeedbackVector::AssertNoLegacyTypes(MaybeObject::FromObject(feedback_extra));
     335             : #endif
     336     6132775 :   int index = vector()->GetIndex(slot()) + 1;
     337     6132775 :   vector()->set(index, MaybeObject::FromObject(feedback_extra), mode);
     338     6132776 : }
     339             : 
     340     2667005 : void FeedbackNexus::SetFeedbackExtra(MaybeObject feedback_extra,
     341             :                                      WriteBarrierMode mode) {
     342             : #ifdef DEBUG
     343             :   FeedbackVector::AssertNoLegacyTypes(feedback_extra);
     344             : #endif
     345     2667005 :   int index = vector()->GetIndex(slot()) + 1;
     346     2667005 :   vector()->set(index, feedback_extra, mode);
     347     2666998 : }
     348             : 
     349             : Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
     350             : }  // namespace internal
     351             : }  // namespace v8
     352             : 
     353             : #include "src/objects/object-macros-undef.h"
     354             : 
     355             : #endif  // V8_FEEDBACK_VECTOR_INL_H_

Generated by: LCOV version 1.10