blob: 015104e96a538a396a515f38c98faa7d4b4cc306 [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) {
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
30TypeFeedbackMetadata* TypeFeedbackMetadata::cast(Object* obj) {
31 DCHECK(obj->IsTypeFeedbackVector());
32 return reinterpret_cast<TypeFeedbackMetadata*>(obj);
33}
34
35
36int 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
44TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) {
45 DCHECK(obj->IsTypeFeedbackVector());
46 return reinterpret_cast<TypeFeedbackVector*>(obj);
47}
48
49
50int 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
57bool TypeFeedbackVector::is_empty() const {
58 if (length() == 0) return true;
59 DCHECK(length() > kReservedIndexCount);
60 return false;
61}
62
63
64int TypeFeedbackVector::slot_count() const {
65 if (length() == 0) return 0;
66 DCHECK(length() > kReservedIndexCount);
67 return length() - kReservedIndexCount;
68}
69
70
71TypeFeedbackMetadata* TypeFeedbackVector::metadata() const {
72 return is_empty() ? TypeFeedbackMetadata::cast(GetHeap()->empty_fixed_array())
73 : TypeFeedbackMetadata::cast(get(kMetadataIndex));
74}
75
76
77FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
78 FeedbackVectorSlot slot) const {
79 DCHECK(!is_empty());
80 return metadata()->GetKind(slot);
81}
82
83
84int 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.
92FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const {
93 DCHECK(index >= kReservedIndexCount && index < length());
94 return FeedbackVectorSlot(index - kReservedIndexCount);
95}
96
97
98Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const {
99 return get(GetIndex(slot));
100}
101
102
103void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value,
104 WriteBarrierMode mode) {
105 set(GetIndex(slot), value, mode);
106}
107
108
109void 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;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400134}
135
Ben Murdochda12d292016-06-02 14:46:10 +0100136Handle<Symbol> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 return isolate->factory()->uninitialized_symbol();
138}
139
Ben Murdochda12d292016-06-02 14:46:10 +0100140Handle<Symbol> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141 return isolate->factory()->megamorphic_symbol();
142}
143
Ben Murdochda12d292016-06-02 14:46:10 +0100144Handle<Symbol> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145 return isolate->factory()->premonomorphic_symbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146}
147
Ben Murdochda12d292016-06-02 14:46:10 +0100148Symbol* TypeFeedbackVector::RawUninitializedSentinel(Isolate* isolate) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 return isolate->heap()->uninitialized_symbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150}
151
152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); }
154
155
156Object* FeedbackNexus::GetFeedbackExtra() const {
157#ifdef DEBUG
158 FeedbackVectorSlotKind kind = vector()->GetKind(slot());
159 DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
160#endif
161 int extra_index = vector()->GetIndex(slot()) + 1;
162 return vector()->get(extra_index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163}
164
165
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
167 vector()->Set(slot(), feedback, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169
170
171void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
172 WriteBarrierMode mode) {
173#ifdef DEBUG
174 FeedbackVectorSlotKind kind = vector()->GetKind(slot());
175 DCHECK_LT(1, TypeFeedbackMetadata::GetSlotSize(kind));
176#endif
177 int index = vector()->GetIndex(slot()) + 1;
178 vector()->set(index, feedback_extra, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180
181
182Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); }
183} // namespace internal
184} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
186#endif // V8_TYPE_FEEDBACK_VECTOR_INL_H_