blob: 771021fb99d410b56d7c7c45c553cef0624ab613 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
10namespace v8 {
11namespace internal {
12
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013
14template <typename Derived>
15FeedbackVectorSlot FeedbackVectorSpecBase<Derived>::AddSlot(
16 FeedbackVectorSlotKind kind) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010017 int slot = This()->slots();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018 int entries_per_slot = TypeFeedbackMetadata::GetSlotSize(kind);
Ben Murdoch61f157c2016-09-16 13:49:30 +010019 This()->append(kind);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 for (int i = 1; i < entries_per_slot; i++) {
Ben Murdoch61f157c2016-09-16 13:49:30 +010021 This()->append(FeedbackVectorSlotKind::INVALID);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022 }
23 return FeedbackVectorSlot(slot);
24}
25
26
27// static
28TypeFeedbackMetadata* TypeFeedbackMetadata::cast(Object* obj) {
29 DCHECK(obj->IsTypeFeedbackVector());
30 return reinterpret_cast<TypeFeedbackMetadata*>(obj);
31}
32
Ben Murdoch61f157c2016-09-16 13:49:30 +010033bool TypeFeedbackMetadata::is_empty() const {
34 if (length() == 0) return true;
35 return false;
36}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037
38int 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
46TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
47 DCHECK(obj->IsTypeFeedbackVector());
48 return reinterpret_cast<TypeFeedbackVector*>(obj);
49}
50
51
52int 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
Ben Murdoch61f157c2016-09-16 13:49:30 +010058bool 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}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078
79bool TypeFeedbackVector::is_empty() const {
80 if (length() == 0) return true;
81 DCHECK(length() > kReservedIndexCount);
82 return false;
83}
84
85
86int TypeFeedbackVector::slot_count() const {
87 if (length() == 0) return 0;
88 DCHECK(length() > kReservedIndexCount);
89 return length() - kReservedIndexCount;
90}
91
92
93TypeFeedbackMetadata* TypeFeedbackVector::metadata() const {
94 return is_empty() ? TypeFeedbackMetadata::cast(GetHeap()->empty_fixed_array())
95 : TypeFeedbackMetadata::cast(get(kMetadataIndex));
96}
97
Ben Murdoch61f157c2016-09-16 13:49:30 +010098// Conversion from an integer index to either a slot or an ic slot.
99// static
100FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) {
101 DCHECK(index >= kReservedIndexCount);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 return FeedbackVectorSlot(index - kReservedIndexCount);
103}
104
105
106Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const {
107 return get(GetIndex(slot));
108}
109
110
111void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value,
112 WriteBarrierMode mode) {
113 set(GetIndex(slot), value, mode);
114}
115
116
117void 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;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400142}
143
Ben Murdochda12d292016-06-02 14:46:10 +0100144Handle<Symbol> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 return isolate->factory()->uninitialized_symbol();
146}
147
Ben Murdochda12d292016-06-02 14:46:10 +0100148Handle<Symbol> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 return isolate->factory()->megamorphic_symbol();
150}
151
Ben Murdochda12d292016-06-02 14:46:10 +0100152Handle<Symbol> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400153 return isolate->factory()->premonomorphic_symbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000154}
155
Ben Murdochda12d292016-06-02 14:46:10 +0100156Symbol* TypeFeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157 return isolate->heap()->uninitialized_symbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158}
159
Ben Murdoch61f157c2016-09-16 13:49:30 +0100160bool TypeFeedbackMetadataIterator::HasNext() const {
161 return next_slot_.ToInt() < metadata()->slot_count();
162}
163
164FeedbackVectorSlot 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
172int TypeFeedbackMetadataIterator::entry_size() const {
173 return TypeFeedbackMetadata::GetSlotSize(kind());
174}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
177
178
179Object* 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186}
187
188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
190 vector()->Set(slot(), feedback, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192
193
194void 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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203
204
205Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
206} // namespace internal
207} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208
209#endif // V8_TYPE_FEEDBACK_VECTOR_INL_H_