Home | History | Annotate | Download | only in src
      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_TYPE_FEEDBACK_VECTOR_INL_H_
      6 #define V8_TYPE_FEEDBACK_VECTOR_INL_H_
      7 
      8 #include "src/type-feedback-vector.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 
     14 template <typename Derived>
     15 FeedbackVectorSlot FeedbackVectorSpecBase<Derived>::AddSlot(
     16     FeedbackVectorSlotKind kind) {
     17   Derived* derived = static_cast<Derived*>(this);
     18 
     19   int slot = derived->slots();
     20   int entries_per_slot = TypeFeedbackMetadata::GetSlotSize(kind);
     21   derived->append(kind);
     22   for (int i = 1; i < entries_per_slot; i++) {
     23     derived->append(FeedbackVectorSlotKind::INVALID);
     24   }
     25   return FeedbackVectorSlot(slot);
     26 }
     27 
     28 
     29 // static
     30 TypeFeedbackMetadata* TypeFeedbackMetadata::cast(Object* obj) {
     31   DCHECK(obj->IsTypeFeedbackVector());
     32   return reinterpret_cast<TypeFeedbackMetadata*>(obj);
     33 }
     34 
     35 
     36 int TypeFeedbackMetadata::slot_count() const {
     37   if (length() == 0) return 0;
     38   DCHECK(length() > kReservedIndexCount);
     39   return Smi::cast(get(kSlotsCountIndex))->value();
     40 }
     41 
     42 
     43 // static
     44 TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
     45   DCHECK(obj->IsTypeFeedbackVector());
     46   return reinterpret_cast<TypeFeedbackVector*>(obj);
     47 }
     48 
     49 
     50 int TypeFeedbackMetadata::GetSlotSize(FeedbackVectorSlotKind kind) {
     51   DCHECK_NE(FeedbackVectorSlotKind::INVALID, kind);
     52   DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, kind);
     53   return kind == FeedbackVectorSlotKind::GENERAL ? 1 : 2;
     54 }
     55 
     56 
     57 bool TypeFeedbackVector::is_empty() const {
     58   if (length() == 0) return true;
     59   DCHECK(length() > kReservedIndexCount);
     60   return false;
     61 }
     62 
     63 
     64 int TypeFeedbackVector::slot_count() const {
     65   if (length() == 0) return 0;
     66   DCHECK(length() > kReservedIndexCount);
     67   return length() - kReservedIndexCount;
     68 }
     69 
     70 
     71 TypeFeedbackMetadata* TypeFeedbackVector::metadata() const {
     72   return is_empty() ? TypeFeedbackMetadata::cast(GetHeap()->empty_fixed_array())
     73                     : TypeFeedbackMetadata::cast(get(kMetadataIndex));
     74 }
     75 
     76 
     77 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
     78     FeedbackVectorSlot slot) const {
     79   DCHECK(!is_empty());
     80   return metadata()->GetKind(slot);
     81 }
     82 
     83 
     84 int TypeFeedbackVector::GetIndex(FeedbackVectorSlot slot) const {
     85   DCHECK(slot.ToInt() < slot_count());
     86   return kReservedIndexCount + slot.ToInt();
     87 }
     88 
     89 
     90 // Conversion from an integer index to either a slot or an ic slot. The caller
     91 // should know what kind she expects.
     92 FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const {
     93   DCHECK(index >= kReservedIndexCount && index < length());
     94   return FeedbackVectorSlot(index - kReservedIndexCount);
     95 }
     96 
     97 
     98 Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const {
     99   return get(GetIndex(slot));
    100 }
    101 
    102 
    103 void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value,
    104                              WriteBarrierMode mode) {
    105   set(GetIndex(slot), value, mode);
    106 }
    107 
    108 
    109 void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic) {
    110   Object* uninitialized_sentinel =
    111       TypeFeedbackVector::RawUninitializedSentinel(GetIsolate());
    112   Object* megamorphic_sentinel =
    113       *TypeFeedbackVector::MegamorphicSentinel(GetIsolate());
    114   int with = 0;
    115   int gen = 0;
    116   TypeFeedbackMetadataIterator iter(metadata());
    117   while (iter.HasNext()) {
    118     FeedbackVectorSlot slot = iter.Next();
    119     FeedbackVectorSlotKind kind = iter.kind();
    120 
    121     Object* obj = Get(slot);
    122     if (obj != uninitialized_sentinel &&
    123         kind != FeedbackVectorSlotKind::GENERAL) {
    124       if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
    125         with++;
    126       } else if (obj == megamorphic_sentinel) {
    127         gen++;
    128       }
    129     }
    130   }
    131 
    132   *with_type_info = with;
    133   *generic = gen;
    134 }
    135 
    136 
    137 Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
    138   return isolate->factory()->uninitialized_symbol();
    139 }
    140 
    141 
    142 Handle<Object> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) {
    143   return isolate->factory()->megamorphic_symbol();
    144 }
    145 
    146 
    147 Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
    148   return isolate->factory()->premonomorphic_symbol();
    149 }
    150 
    151 
    152 Object* TypeFeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
    153   return isolate->heap()->uninitialized_symbol();
    154 }
    155 
    156 
    157 Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
    158 
    159 
    160 Object* FeedbackNexus::GetFeedbackExtra() const {
    161 #ifdef DEBUG
    162   FeedbackVectorSlotKind kind = vector()->GetKind(slot());
    163   DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
    164 #endif
    165   int extra_index = vector()->GetIndex(slot()) + 1;
    166   return vector()->get(extra_index);
    167 }
    168 
    169 
    170 void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
    171   vector()->Set(slot(), feedback, mode);
    172 }
    173 
    174 
    175 void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
    176                                      WriteBarrierMode mode) {
    177 #ifdef DEBUG
    178   FeedbackVectorSlotKind kind = vector()->GetKind(slot());
    179   DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
    180 #endif
    181   int index = vector()->GetIndex(slot()) + 1;
    182   vector()->set(index, feedback_extra, mode);
    183 }
    184 
    185 
    186 Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
    187 }  // namespace internal
    188 }  // namespace v8
    189 
    190 #endif  // V8_TYPE_FEEDBACK_VECTOR_INL_H_
    191