LCOV - code coverage report
Current view: top level - src - feedback-vector-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 85 86 98.8 %
Date: 2019-04-17 Functions: 15 15 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     7948921 : INT32_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
      36             : 
      37     4714486 : INT32_ACCESSORS(FeedbackMetadata, closure_feedback_cell_count,
      38             :                 kFeedbackCellCountOffset)
      39             : 
      40             : int32_t FeedbackMetadata::synchronized_slot_count() const {
      41     5628074 :   return base::Acquire_Load(reinterpret_cast<const base::Atomic32*>(
      42     5628074 :       FIELD_ADDR(*this, kSlotCountOffset)));
      43             : }
      44             : 
      45             : int32_t FeedbackMetadata::get(int index) const {
      46             :   DCHECK(index >= 0 && index < length());
      47    70098832 :   int offset = kHeaderSize + index * kInt32Size;
      48    70099252 :   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    26069343 :   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    35772261 : 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    30365560 :       return 2;
      90             : 
      91             :     case FeedbackSlotKind::kInvalid:
      92             :     case FeedbackSlotKind::kKindsNumber:
      93           0 :       UNREACHABLE();
      94             :       break;
      95             :   }
      96             :   return 1;
      97             : }
      98             : 
      99      787792 : Handle<FeedbackCell> ClosureFeedbackCellArray::GetFeedbackCell(int index) {
     100      787792 :   return handle(FeedbackCell::cast(get(index)), GetIsolate());
     101             : }
     102             : 
     103    38523151 : ACCESSORS(FeedbackVector, shared_function_info, SharedFunctionInfo,
     104             :           kSharedFunctionInfoOffset)
     105    34813709 : WEAK_ACCESSORS(FeedbackVector, optimized_code_weak_or_smi, kOptimizedCodeOffset)
     106    16098830 : ACCESSORS(FeedbackVector, closure_feedback_cell_array, ClosureFeedbackCellArray,
     107             :           kClosureFeedbackCellArrayOffset)
     108    24378508 : INT32_ACCESSORS(FeedbackVector, length, kLengthOffset)
     109     3641095 : INT32_ACCESSORS(FeedbackVector, invocation_count, kInvocationCountOffset)
     110     7139468 : INT32_ACCESSORS(FeedbackVector, profiler_ticks, kProfilerTicksOffset)
     111     3165931 : 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       33061 :   if (count < std::numeric_limits<int32_t>::max()) {
     124       33061 :     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     7389885 :   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     1516095 :   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      489391 : bool FeedbackVector::has_optimization_marker() const {
     147      978781 :   return optimization_marker() != OptimizationMarker::kLogFirstExecution &&
     148      489391 :          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    26020272 :   int offset = kFeedbackSlotsOffset + index * kTaggedSize;
     166    26020302 :   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      441820 :       ClosureFeedbackCellArray::cast(closure_feedback_cell_array());
     173      441820 :   return cell_array->GetFeedbackCell(index);
     174             : }
     175             : 
     176             : void FeedbackVector::Set(FeedbackSlot slot, MaybeObject value,
     177             :                          WriteBarrierMode mode) {
     178     8804944 :   set(GetIndex(slot), value, mode);
     179             : }
     180             : 
     181    56663742 : void FeedbackVector::set(int index, MaybeObject value, WriteBarrierMode mode) {
     182             :   DCHECK_GE(index, 0);
     183             :   DCHECK_LT(index, this->length());
     184    56663742 :   int offset = kFeedbackSlotsOffset + index * kTaggedSize;
     185    56663742 :   RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
     186    80095370 :   CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);
     187    56663745 : }
     188             : 
     189             : void FeedbackVector::Set(FeedbackSlot slot, Object value,
     190             :                          WriteBarrierMode mode) {
     191      261827 :   set(GetIndex(slot), MaybeObject::FromObject(value), mode);
     192             : }
     193             : 
     194             : void FeedbackVector::set(int index, Object value, WriteBarrierMode mode) {
     195    32464798 :   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      945973 : BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback) {
     204      945973 :   switch (type_feedback) {
     205             :     case BinaryOperationFeedback::kNone:
     206             :       return BinaryOperationHint::kNone;
     207             :     case BinaryOperationFeedback::kSignedSmall:
     208      415290 :       return BinaryOperationHint::kSignedSmall;
     209             :     case BinaryOperationFeedback::kSignedSmallInputs:
     210       28039 :       return BinaryOperationHint::kSignedSmallInputs;
     211             :     case BinaryOperationFeedback::kNumber:
     212      204261 :       return BinaryOperationHint::kNumber;
     213             :     case BinaryOperationFeedback::kNumberOrOddball:
     214        6564 :       return BinaryOperationHint::kNumberOrOddball;
     215             :     case BinaryOperationFeedback::kConsOneByteString:
     216        6083 :       return BinaryOperationHint::kConsOneByteString;
     217             :     case BinaryOperationFeedback::kConsTwoByteString:
     218         518 :       return BinaryOperationHint::kConsTwoByteString;
     219             :     case BinaryOperationFeedback::kConsString:
     220          54 :       return BinaryOperationHint::kConsString;
     221             :     case BinaryOperationFeedback::kString:
     222       13174 :       return BinaryOperationHint::kString;
     223             :     case BinaryOperationFeedback::kBigInt:
     224         917 :       return BinaryOperationHint::kBigInt;
     225             :     default:
     226       10166 :       return BinaryOperationHint::kAny;
     227             :   }
     228             :   UNREACHABLE();
     229             : }
     230             : 
     231             : // Helper function to transform the feedback to CompareOperationHint.
     232      526602 : CompareOperationHint CompareOperationHintFromFeedback(int type_feedback) {
     233      526602 :   switch (type_feedback) {
     234             :     case CompareOperationFeedback::kNone:
     235             :       return CompareOperationHint::kNone;
     236             :     case CompareOperationFeedback::kSignedSmall:
     237      183030 :       return CompareOperationHint::kSignedSmall;
     238             :     case CompareOperationFeedback::kNumber:
     239       30544 :       return CompareOperationHint::kNumber;
     240             :     case CompareOperationFeedback::kNumberOrOddball:
     241          21 :       return CompareOperationHint::kNumberOrOddball;
     242             :     case CompareOperationFeedback::kInternalizedString:
     243       16985 :       return CompareOperationHint::kInternalizedString;
     244             :     case CompareOperationFeedback::kString:
     245       28050 :       return CompareOperationHint::kString;
     246             :     case CompareOperationFeedback::kSymbol:
     247         117 :       return CompareOperationHint::kSymbol;
     248             :     case CompareOperationFeedback::kBigInt:
     249         148 :       return CompareOperationHint::kBigInt;
     250             :     case CompareOperationFeedback::kReceiver:
     251        2103 :       return CompareOperationHint::kReceiver;
     252             :     case CompareOperationFeedback::kReceiverOrNullOrUndefined:
     253         347 :       return CompareOperationHint::kReceiverOrNullOrUndefined;
     254             :     default:
     255       73126 :       return CompareOperationHint::kAny;
     256             :   }
     257             :   UNREACHABLE();
     258             : }
     259             : 
     260             : // Helper function to transform the feedback to ForInHint.
     261             : ForInHint ForInHintFromFeedback(int type_feedback) {
     262             :   switch (type_feedback) {
     263             :     case ForInFeedback::kNone:
     264             :       return ForInHint::kNone;
     265             :     case ForInFeedback::kEnumCacheKeys:
     266             :       return ForInHint::kEnumCacheKeys;
     267             :     case ForInFeedback::kEnumCacheKeysAndIndices:
     268             :       return ForInHint::kEnumCacheKeysAndIndices;
     269             :     default:
     270             :       return ForInHint::kAny;
     271             :   }
     272             :   UNREACHABLE();
     273             : }
     274             : 
     275             : Handle<Symbol> FeedbackVector::UninitializedSentinel(Isolate* isolate) {
     276             :   return isolate->factory()->uninitialized_symbol();
     277             : }
     278             : 
     279             : Handle<Symbol> FeedbackVector::GenericSentinel(Isolate* isolate) {
     280             :   return isolate->factory()->generic_symbol();
     281             : }
     282             : 
     283             : Handle<Symbol> FeedbackVector::MegamorphicSentinel(Isolate* isolate) {
     284             :   return isolate->factory()->megamorphic_symbol();
     285             : }
     286             : 
     287             : Handle<Symbol> FeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
     288             :   return isolate->factory()->premonomorphic_symbol();
     289             : }
     290             : 
     291             : Symbol FeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
     292             :   return ReadOnlyRoots(isolate).uninitialized_symbol();
     293             : }
     294             : 
     295             : bool FeedbackMetadataIterator::HasNext() const {
     296             :   return next_slot_.ToInt() < metadata()->slot_count();
     297             : }
     298             : 
     299       81358 : FeedbackSlot FeedbackMetadataIterator::Next() {
     300             :   DCHECK(HasNext());
     301       81358 :   cur_slot_ = next_slot_;
     302       81358 :   slot_kind_ = metadata()->GetKind(cur_slot_);
     303       81358 :   next_slot_ = FeedbackSlot(next_slot_.ToInt() + entry_size());
     304       81358 :   return cur_slot_;
     305             : }
     306             : 
     307             : int FeedbackMetadataIterator::entry_size() const {
     308       81358 :   return FeedbackMetadata::GetSlotSize(kind());
     309             : }
     310             : 
     311    17089398 : MaybeObject FeedbackNexus::GetFeedback() const {
     312             :   MaybeObject feedback = vector()->Get(slot());
     313      418147 :   FeedbackVector::AssertNoLegacyTypes(feedback);
     314    17089398 :   return feedback;
     315             : }
     316             : 
     317     7277347 : MaybeObject FeedbackNexus::GetFeedbackExtra() const {
     318             : #ifdef DEBUG
     319             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     320             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     321             : #endif
     322             :   int extra_index = vector()->GetIndex(slot()) + 1;
     323     7277347 :   return vector()->get(extra_index);
     324             : }
     325             : 
     326             : void FeedbackNexus::SetFeedback(Object feedback, WriteBarrierMode mode) {
     327     1013043 :   SetFeedback(MaybeObject::FromObject(feedback));
     328             : }
     329             : 
     330     8804939 : void FeedbackNexus::SetFeedback(MaybeObject feedback, WriteBarrierMode mode) {
     331             :   FeedbackVector::AssertNoLegacyTypes(feedback);
     332    17609885 :   vector()->Set(slot(), feedback, mode);
     333     8804946 : }
     334             : 
     335     6133705 : void FeedbackNexus::SetFeedbackExtra(Object feedback_extra,
     336             :                                      WriteBarrierMode mode) {
     337             : #ifdef DEBUG
     338             :   FeedbackSlotKind kind = vector()->GetKind(slot());
     339             :   DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
     340             :   FeedbackVector::AssertNoLegacyTypes(MaybeObject::FromObject(feedback_extra));
     341             : #endif
     342     6133705 :   int index = vector()->GetIndex(slot()) + 1;
     343     6133705 :   vector()->set(index, MaybeObject::FromObject(feedback_extra), mode);
     344     6133708 : }
     345             : 
     346     2679047 : void FeedbackNexus::SetFeedbackExtra(MaybeObject feedback_extra,
     347             :                                      WriteBarrierMode mode) {
     348             : #ifdef DEBUG
     349             :   FeedbackVector::AssertNoLegacyTypes(feedback_extra);
     350             : #endif
     351     2679047 :   int index = vector()->GetIndex(slot()) + 1;
     352     2679047 :   vector()->set(index, feedback_extra, mode);
     353     2679022 : }
     354             : 
     355             : Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
     356             : }  // namespace internal
     357             : }  // namespace v8
     358             : 
     359             : #include "src/objects/object-macros-undef.h"
     360             : 
     361             : #endif  // V8_FEEDBACK_VECTOR_INL_H_

Generated by: LCOV version 1.10