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