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>
AddSlot(FeedbackVectorSlotKind kind)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
cast(Object * obj)30 TypeFeedbackMetadata* TypeFeedbackMetadata::cast(Object* obj) {
31 DCHECK(obj->IsTypeFeedbackVector());
32 return reinterpret_cast<TypeFeedbackMetadata*>(obj);
33 }
34
35
slot_count()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
cast(Object * obj)44 TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
45 DCHECK(obj->IsTypeFeedbackVector());
46 return reinterpret_cast<TypeFeedbackVector*>(obj);
47 }
48
49
GetSlotSize(FeedbackVectorSlotKind kind)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
is_empty()57 bool TypeFeedbackVector::is_empty() const {
58 if (length() == 0) return true;
59 DCHECK(length() > kReservedIndexCount);
60 return false;
61 }
62
63
slot_count()64 int TypeFeedbackVector::slot_count() const {
65 if (length() == 0) return 0;
66 DCHECK(length() > kReservedIndexCount);
67 return length() - kReservedIndexCount;
68 }
69
70
metadata()71 TypeFeedbackMetadata* TypeFeedbackVector::metadata() const {
72 return is_empty() ? TypeFeedbackMetadata::cast(GetHeap()->empty_fixed_array())
73 : TypeFeedbackMetadata::cast(get(kMetadataIndex));
74 }
75
76
GetKind(FeedbackVectorSlot slot)77 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
78 FeedbackVectorSlot slot) const {
79 DCHECK(!is_empty());
80 return metadata()->GetKind(slot);
81 }
82
83
GetIndex(FeedbackVectorSlot slot)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.
ToSlot(int index)92 FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const {
93 DCHECK(index >= kReservedIndexCount && index < length());
94 return FeedbackVectorSlot(index - kReservedIndexCount);
95 }
96
97
Get(FeedbackVectorSlot slot)98 Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const {
99 return get(GetIndex(slot));
100 }
101
102
Set(FeedbackVectorSlot slot,Object * value,WriteBarrierMode mode)103 void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value,
104 WriteBarrierMode mode) {
105 set(GetIndex(slot), value, mode);
106 }
107
108
ComputeCounts(int * with_type_info,int * generic)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
UninitializedSentinel(Isolate * isolate)137 Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
138 return isolate->factory()->uninitialized_symbol();
139 }
140
141
MegamorphicSentinel(Isolate * isolate)142 Handle<Object> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) {
143 return isolate->factory()->megamorphic_symbol();
144 }
145
146
PremonomorphicSentinel(Isolate * isolate)147 Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
148 return isolate->factory()->premonomorphic_symbol();
149 }
150
151
RawUninitializedSentinel(Isolate * isolate)152 Object* TypeFeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
153 return isolate->heap()->uninitialized_symbol();
154 }
155
156
GetFeedback()157 Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
158
159
GetFeedbackExtra()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
SetFeedback(Object * feedback,WriteBarrierMode mode)170 void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
171 vector()->Set(slot(), feedback, mode);
172 }
173
174
SetFeedbackExtra(Object * feedback_extra,WriteBarrierMode mode)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
GetIsolate()186 Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
187 } // namespace internal
188 } // namespace v8
189
190 #endif // V8_TYPE_FEEDBACK_VECTOR_INL_H_
191