Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: src/type-feedback-vector.h

Issue 1370303004: Distinction between FeedbackVectorICSlot and FeedbackVectorSlot eliminated. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed release builds Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/prettyprinter.cc ('k') | src/type-feedback-vector.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_
6 #define V8_TYPE_FEEDBACK_VECTOR_H_ 6 #define V8_TYPE_FEEDBACK_VECTOR_H_
7 7
8 #include <vector> 8 #include <vector>
9 9
10 #include "src/checks.h" 10 #include "src/checks.h"
11 #include "src/elements-kind.h" 11 #include "src/elements-kind.h"
12 #include "src/heap/heap.h" 12 #include "src/heap/heap.h"
13 #include "src/isolate.h" 13 #include "src/isolate.h"
14 #include "src/objects.h" 14 #include "src/objects.h"
15 #include "src/zone-containers.h" 15 #include "src/zone-containers.h"
16 16
17 namespace v8 { 17 namespace v8 {
18 namespace internal { 18 namespace internal {
19 19
20 20
21 enum class FeedbackVectorSlotKind { 21 enum class FeedbackVectorSlotKind {
22 UNUSED, 22 // This kind means that the slot points to the middle of other slot
23 // which occupies more than one feedback vector element.
24 // There must be no such slots in the system.
25 INVALID,
26
23 CALL_IC, 27 CALL_IC,
24 LOAD_IC, 28 LOAD_IC,
25 KEYED_LOAD_IC, 29 KEYED_LOAD_IC,
26 STORE_IC, 30 STORE_IC,
27 KEYED_STORE_IC, 31 KEYED_STORE_IC,
28 32
33 // This is a general purpose slot that occupies one feedback vector element.
34 GENERAL,
35
29 KINDS_NUMBER // Last value indicating number of kinds. 36 KINDS_NUMBER // Last value indicating number of kinds.
30 }; 37 };
31 38
32 39
33 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind); 40 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
34 41
35 42
36 class StaticFeedbackVectorSpec { 43 template <typename Derived>
44 class FeedbackVectorSpecBase {
37 public: 45 public:
38 StaticFeedbackVectorSpec() : slots_(0), ic_slots_(0), ic_kinds_(NULL) {} 46 inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind);
39 StaticFeedbackVectorSpec(int slots, int ic_slots, 47
40 FeedbackVectorSlotKind* ic_slot_kinds) 48 FeedbackVectorSlot AddCallICSlot() {
41 : slots_(slots), ic_slots_(ic_slots), ic_kinds_(ic_slot_kinds) {} 49 return AddSlot(FeedbackVectorSlotKind::CALL_IC);
50 }
51
52 FeedbackVectorSlot AddLoadICSlot() {
53 return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
54 }
55
56 FeedbackVectorSlot AddKeyedLoadICSlot() {
57 return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
58 }
59
60 FeedbackVectorSlot AddStoreICSlot() {
61 return AddSlot(FeedbackVectorSlotKind::STORE_IC);
62 }
63
64 FeedbackVectorSlot AddKeyedStoreICSlot() {
65 return AddSlot(FeedbackVectorSlotKind::KEYED_STORE_IC);
66 }
67
68 FeedbackVectorSlot AddGeneralSlot() {
69 return AddSlot(FeedbackVectorSlotKind::GENERAL);
70 }
71 };
72
73
74 class StaticFeedbackVectorSpec
75 : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
76 public:
77 StaticFeedbackVectorSpec() : slots_(0) {}
42 78
43 int slots() const { return slots_; } 79 int slots() const { return slots_; }
44 80
45 int ic_slots() const { return ic_slots_; } 81 FeedbackVectorSlotKind GetKind(int slot) const {
46 82 DCHECK(slot >= 0 && slot < slots_);
47 FeedbackVectorSlotKind GetKind(int ic_slot) const { 83 return kinds_[slot];
48 DCHECK(ic_slots_ > 0 && ic_slot < ic_slots_);
49 return ic_kinds_[ic_slot];
50 } 84 }
51 85
52 private: 86 private:
87 friend class FeedbackVectorSpecBase<StaticFeedbackVectorSpec>;
88
89 void append(FeedbackVectorSlotKind kind) {
90 DCHECK(slots_ < kMaxLength);
91 kinds_[slots_++] = kind;
92 }
93
94 static const int kMaxLength = 12;
95
53 int slots_; 96 int slots_;
54 int ic_slots_; 97 FeedbackVectorSlotKind kinds_[kMaxLength];
55 FeedbackVectorSlotKind* ic_kinds_;
56 }; 98 };
57 99
58 100
59 class FeedbackVectorSpec { 101 class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
60 public: 102 public:
61 explicit FeedbackVectorSpec(Zone* zone) 103 explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone) {
62 : slots_(0), ic_slots_(0), ic_slot_kinds_(zone) {} 104 slot_kinds_.reserve(16);
63
64 int slots() const { return slots_; }
65 void increase_slots(int count) {
66 DCHECK_LT(0, count);
67 slots_ += count;
68 } 105 }
69 106
70 int ic_slots() const { return ic_slots_; } 107 int slots() const { return static_cast<int>(slot_kinds_.size()); }
71 void increase_ic_slots(int count) {
72 DCHECK_LT(0, count);
73 ic_slots_ += count;
74 ic_slot_kinds_.resize(ic_slots_);
75 }
76 108
77 FeedbackVectorICSlot AddSlot(FeedbackVectorSlotKind kind) { 109 FeedbackVectorSlotKind GetKind(int slot) const {
78 int slot = ic_slots_; 110 return static_cast<FeedbackVectorSlotKind>(slot_kinds_.at(slot));
79 increase_ic_slots(1);
80 ic_slot_kinds_[slot] = static_cast<unsigned char>(kind);
81 return FeedbackVectorICSlot(slot);
82 }
83
84 FeedbackVectorICSlot AddSlots(FeedbackVectorSlotKind kind, int count) {
85 int slot = ic_slots_;
86 increase_ic_slots(count);
87 for (int i = 0; i < count; i++) {
88 ic_slot_kinds_[slot + i] = static_cast<unsigned char>(kind);
89 }
90 return FeedbackVectorICSlot(slot);
91 }
92
93 FeedbackVectorICSlot AddCallICSlot() {
94 return AddSlot(FeedbackVectorSlotKind::CALL_IC);
95 }
96
97 FeedbackVectorICSlot AddLoadICSlot() {
98 return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
99 }
100
101 FeedbackVectorICSlot AddLoadICSlots(int count) {
102 return AddSlots(FeedbackVectorSlotKind::LOAD_IC, count);
103 }
104
105 FeedbackVectorICSlot AddKeyedLoadICSlot() {
106 return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
107 }
108
109 FeedbackVectorICSlot AddStoreICSlot() {
110 return AddSlot(FeedbackVectorSlotKind::STORE_IC);
111 }
112
113 FeedbackVectorSlot AddStubSlot() {
114 int slot = slots_;
115 increase_slots(1);
116 return FeedbackVectorSlot(slot);
117 }
118
119 FeedbackVectorSlot AddStubSlots(int count) {
120 int slot = slots_;
121 increase_slots(count);
122 return FeedbackVectorSlot(slot);
123 }
124
125 FeedbackVectorSlotKind GetKind(int ic_slot) const {
126 return static_cast<FeedbackVectorSlotKind>(ic_slot_kinds_.at(ic_slot));
127 } 111 }
128 112
129 private: 113 private:
130 int slots_; 114 friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
131 int ic_slots_; 115
132 ZoneVector<unsigned char> ic_slot_kinds_; 116 void append(FeedbackVectorSlotKind kind) {
117 slot_kinds_.push_back(static_cast<unsigned char>(kind));
118 }
119
120 ZoneVector<unsigned char> slot_kinds_;
133 }; 121 };
134 122
135 123
136 // The shape of the TypeFeedbackVector is an array with: 124 // The shape of the TypeFeedbackVector is an array with:
137 // 0: first_ic_slot_index (== length() if no ic slots are present) 125 // 0: slot_count
138 // 1: ics_with_types 126 // 1: ics_with_types
139 // 2: ics_with_generic_info 127 // 2: ics_with_generic_info
140 // 3: type information for ic slots, if any 128 // 3: slots metadata (a bit vector of slot kinds)
141 // ... 129 // ...
142 // N: first feedback slot (N >= 3) 130 // N: feedback slot #0 (N >= 3)
143 // ... 131 // ...
144 // [<first_ic_slot_index>: feedback slot] 132 // N + slot_count - 1: feedback slot #(slot_count-1)
145 // ...to length() - 1
146 // 133 //
147 class TypeFeedbackVector : public FixedArray { 134 class TypeFeedbackVector : public FixedArray {
148 public: 135 public:
149 // Casting. 136 // Casting.
150 static inline TypeFeedbackVector* cast(Object* obj); 137 static inline TypeFeedbackVector* cast(Object* obj);
151 138
152 static const int kReservedIndexCount = 3; 139 static const int kSlotsCountIndex = 0;
153 static const int kFirstICSlotIndex = 0;
154 static const int kWithTypesIndex = 1; 140 static const int kWithTypesIndex = 1;
155 static const int kGenericCountIndex = 2; 141 static const int kGenericCountIndex = 2;
142 static const int kReservedIndexCount = 3;
156 143
157 static int elements_per_ic_slot() { return 2; } 144 // Returns number of feedback vector elements used by given slot kind.
145 static inline int GetSlotSize(FeedbackVectorSlotKind kind);
158 146
159 inline int first_ic_slot_index() const;
160 inline int ic_with_type_info_count(); 147 inline int ic_with_type_info_count();
161 inline void change_ic_with_type_info_count(int delta); 148 inline void change_ic_with_type_info_count(int delta);
162 inline int ic_generic_count(); 149 inline int ic_generic_count();
163 inline void change_ic_generic_count(int delta); 150 inline void change_ic_generic_count(int delta);
164 inline int ic_metadata_length() const; 151 inline int ic_metadata_length() const;
165 152
166 bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const; 153 bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
167 154
155 inline bool is_empty() const;
156
157 // Returns number of slots in the vector.
168 inline int Slots() const; 158 inline int Slots() const;
169 inline int ICSlots() const;
170 159
171 // Conversion from a slot or ic slot to an integer index to the underlying 160 // Conversion from a slot to an integer index to the underlying array.
172 // array.
173 inline int GetIndex(FeedbackVectorSlot slot) const; 161 inline int GetIndex(FeedbackVectorSlot slot) const;
174 inline int GetIndex(FeedbackVectorICSlot slot) const; 162 static int GetIndexFromSpec(const FeedbackVectorSpec* spec,
163 FeedbackVectorSlot slot);
175 164
176 template <typename Spec> 165 // Conversion from an integer index to the underlying array to a slot.
177 static int GetIndexFromSpec(const Spec* spec, FeedbackVectorSlot slot);
178 template <typename Spec>
179 static int GetIndexFromSpec(const Spec* spec, FeedbackVectorICSlot slot);
180
181 // Conversion from an integer index to either a slot or an ic slot. The caller
182 // should know what kind she expects.
183 inline FeedbackVectorSlot ToSlot(int index) const; 166 inline FeedbackVectorSlot ToSlot(int index) const;
184 inline FeedbackVectorICSlot ToICSlot(int index) const;
185 inline Object* Get(FeedbackVectorSlot slot) const; 167 inline Object* Get(FeedbackVectorSlot slot) const;
186 inline void Set(FeedbackVectorSlot slot, Object* value, 168 inline void Set(FeedbackVectorSlot slot, Object* value,
187 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 169 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
188 inline Object* Get(FeedbackVectorICSlot slot) const;
189 inline void Set(FeedbackVectorICSlot slot, Object* value,
190 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
191 170
192 // IC slots need metadata to recognize the type of IC. 171 // Returns slot kind for given slot.
193 FeedbackVectorSlotKind GetKind(FeedbackVectorICSlot slot) const; 172 FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
194 173
195 template <typename Spec> 174 template <typename Spec>
196 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, 175 static Handle<TypeFeedbackVector> New(Isolate* isolate, const Spec* spec);
197 const Spec* spec);
198 176
199 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, 177 static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
200 Handle<TypeFeedbackVector> vector); 178 Handle<TypeFeedbackVector> vector);
201 179
202 #ifdef OBJECT_PRINT 180 #ifdef OBJECT_PRINT
203 // For gdb debugging. 181 // For gdb debugging.
204 void Print(); 182 void Print();
205 #endif // OBJECT_PRINT 183 #endif // OBJECT_PRINT
206 184
207 DECLARE_PRINTER(TypeFeedbackVector) 185 DECLARE_PRINTER(TypeFeedbackVector)
208 186
209 // Clears the vector slots and the vector ic slots. 187 // Clears the vector slots.
210 void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); } 188 void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); }
189
211 void ClearSlotsAtGCTime(SharedFunctionInfo* shared) { 190 void ClearSlotsAtGCTime(SharedFunctionInfo* shared) {
212 ClearSlotsImpl(shared, false); 191 ClearSlotsImpl(shared, false);
213 } 192 }
214 193
215 void ClearICSlots(SharedFunctionInfo* shared) {
216 ClearICSlotsImpl(shared, true);
217 }
218 void ClearICSlotsAtGCTime(SharedFunctionInfo* shared) {
219 ClearICSlotsImpl(shared, false);
220 }
221
222 static void ClearAllKeyedStoreICs(Isolate* isolate); 194 static void ClearAllKeyedStoreICs(Isolate* isolate);
223 void ClearKeyedStoreICs(SharedFunctionInfo* shared); 195 void ClearKeyedStoreICs(SharedFunctionInfo* shared);
224 196
225 // The object that indicates an uninitialized cache. 197 // The object that indicates an uninitialized cache.
226 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); 198 static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
227 199
228 // The object that indicates a megamorphic state. 200 // The object that indicates a megamorphic state.
229 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate); 201 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
230 202
231 // The object that indicates a premonomorphic state. 203 // The object that indicates a premonomorphic state.
232 static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate); 204 static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate);
233 205
234 // A raw version of the uninitialized sentinel that's safe to read during 206 // A raw version of the uninitialized sentinel that's safe to read during
235 // garbage collection (e.g., for patching the cache). 207 // garbage collection (e.g., for patching the cache).
236 static inline Object* RawUninitializedSentinel(Heap* heap); 208 static inline Object* RawUninitializedSentinel(Isolate* isolate);
237 209
238 static const int kDummyLoadICSlot = 0; 210 static const int kDummyLoadICSlot = 0;
239 static const int kDummyKeyedLoadICSlot = 1; 211 static const int kDummyKeyedLoadICSlot = 2;
240 static const int kDummyStoreICSlot = 2; 212 static const int kDummyStoreICSlot = 4;
241 static const int kDummyKeyedStoreICSlot = 3; 213 static const int kDummyKeyedStoreICSlot = 6;
242 214
243 static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate); 215 static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate);
244 static FeedbackVectorICSlot DummySlot(int dummyIndex) { 216 static FeedbackVectorSlot DummySlot(int dummyIndex) {
245 DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot); 217 DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot);
246 return FeedbackVectorICSlot(dummyIndex); 218 return FeedbackVectorSlot(dummyIndex);
247 } 219 }
248 220
249 static int PushAppliedArgumentsIndex(); 221 static int PushAppliedArgumentsIndex();
250 static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector( 222 static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector(
251 Isolate* isolate); 223 Isolate* isolate);
252 224
253 static const char* Kind2String(FeedbackVectorSlotKind kind); 225 static const char* Kind2String(FeedbackVectorSlotKind kind);
254 226
255 private: 227 private:
256 static const int kFeedbackVectorSlotKindBits = 3; 228 static const int kFeedbackVectorSlotKindBits = 3;
257 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) < 229 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
258 (1 << kFeedbackVectorSlotKindBits)); 230 (1 << kFeedbackVectorSlotKindBits));
259 231
260 void SetKind(FeedbackVectorICSlot slot, FeedbackVectorSlotKind kind); 232 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
261 233
262 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits, 234 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
263 kSmiValueSize, uint32_t> VectorICComputer; 235 kSmiValueSize, uint32_t> VectorICComputer;
264 236
265 void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear); 237 void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
266 void ClearICSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
267 238
268 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); 239 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
269 }; 240 };
270 241
271 242
272 // The following asserts protect an optimization in type feedback vector 243 // The following asserts protect an optimization in type feedback vector
273 // code that looks into the contents of a slot assuming to find a String, 244 // code that looks into the contents of a slot assuming to find a String,
274 // a Symbol, an AllocationSite, a WeakCell, or a FixedArray. 245 // a Symbol, an AllocationSite, a WeakCell, or a FixedArray.
275 STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize); 246 STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
276 STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset); 247 STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
277 STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset); 248 STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
278 STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot); 249 STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot);
279 // Verify that an empty hash field looks like a tagged object, but can't 250 // Verify that an empty hash field looks like a tagged object, but can't
280 // possibly be confused with a pointer. 251 // possibly be confused with a pointer.
281 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag); 252 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
282 STATIC_ASSERT(Name::kEmptyHashField == 0x3); 253 STATIC_ASSERT(Name::kEmptyHashField == 0x3);
283 // Verify that a set hash field will not look like a tagged object. 254 // Verify that a set hash field will not look like a tagged object.
284 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag); 255 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
285 256
286 257
258 class TypeFeedbackMetadataIterator {
259 public:
260 explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackVector> metadata)
261 : metadata_handle_(metadata),
262 slot_(FeedbackVectorSlot(0)),
263 slot_kind_(FeedbackVectorSlotKind::INVALID) {}
264
265 explicit TypeFeedbackMetadataIterator(TypeFeedbackVector* metadata)
266 : metadata_(metadata),
267 slot_(FeedbackVectorSlot(0)),
268 slot_kind_(FeedbackVectorSlotKind::INVALID) {}
269
270 bool HasNext() const { return slot_.ToInt() < metadata()->Slots(); }
271
272 FeedbackVectorSlot Next() {
273 DCHECK(HasNext());
274 FeedbackVectorSlot slot = slot_;
275 slot_kind_ = metadata()->GetKind(slot);
276 slot_ = FeedbackVectorSlot(slot_.ToInt() + entry_size());
277 return slot;
278 }
279
280 // Returns slot kind of the last slot returned by Next().
281 FeedbackVectorSlotKind kind() const {
282 DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_);
283 DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_);
284 return slot_kind_;
285 }
286
287 // Returns entry size of the last slot returned by Next().
288 int entry_size() const { return TypeFeedbackVector::GetSlotSize(kind()); }
289
290 private:
291 TypeFeedbackVector* metadata() const {
292 return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
293 }
294
295 // The reason for having a handle and a raw pointer to the meta data is
296 // to have a single iterator implementation for both "handlified" and raw
297 // pointer use cases.
298 Handle<TypeFeedbackVector> metadata_handle_;
299 TypeFeedbackVector* metadata_;
300 FeedbackVectorSlot slot_;
301 FeedbackVectorSlotKind slot_kind_;
302 };
303
304
287 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. 305 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot.
288 // Derived classes customize the update and retrieval of feedback. 306 // Derived classes customize the update and retrieval of feedback.
289 class FeedbackNexus { 307 class FeedbackNexus {
290 public: 308 public:
291 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) 309 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
292 : vector_handle_(vector), vector_(NULL), slot_(slot) {} 310 : vector_handle_(vector), vector_(NULL), slot_(slot) {}
293 FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 311 FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
294 : vector_(vector), slot_(slot) {} 312 : vector_(vector), slot_(slot) {}
295 virtual ~FeedbackNexus() {} 313 virtual ~FeedbackNexus() {}
296 314
297 Handle<TypeFeedbackVector> vector_handle() const { 315 Handle<TypeFeedbackVector> vector_handle() const {
298 DCHECK(vector_ == NULL); 316 DCHECK(vector_ == NULL);
299 return vector_handle_; 317 return vector_handle_;
300 } 318 }
301 TypeFeedbackVector* vector() const { 319 TypeFeedbackVector* vector() const {
302 return vector_handle_.is_null() ? vector_ : *vector_handle_; 320 return vector_handle_.is_null() ? vector_ : *vector_handle_;
303 } 321 }
304 FeedbackVectorICSlot slot() const { return slot_; } 322 FeedbackVectorSlot slot() const { return slot_; }
305 323
306 InlineCacheState ic_state() const { return StateFromFeedback(); } 324 InlineCacheState ic_state() const { return StateFromFeedback(); }
307 Map* FindFirstMap() const { 325 Map* FindFirstMap() const {
308 MapHandleList maps; 326 MapHandleList maps;
309 ExtractMaps(&maps); 327 ExtractMaps(&maps);
310 if (maps.length() > 0) return *maps.at(0); 328 if (maps.length() > 0) return *maps.at(0);
311 return NULL; 329 return NULL;
312 } 330 }
313 331
314 // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review. 332 // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
(...skipping 25 matching lines...) Expand all
340 void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps, 358 void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
341 CodeHandleList* handlers); 359 CodeHandleList* handlers);
342 360
343 private: 361 private:
344 // The reason for having a vector handle and a raw pointer is that we can and 362 // The reason for having a vector handle and a raw pointer is that we can and
345 // should use handles during IC miss, but not during GC when we clear ICs. If 363 // should use handles during IC miss, but not during GC when we clear ICs. If
346 // you have a handle to the vector that is better because more operations can 364 // you have a handle to the vector that is better because more operations can
347 // be done, like allocation. 365 // be done, like allocation.
348 Handle<TypeFeedbackVector> vector_handle_; 366 Handle<TypeFeedbackVector> vector_handle_;
349 TypeFeedbackVector* vector_; 367 TypeFeedbackVector* vector_;
350 FeedbackVectorICSlot slot_; 368 FeedbackVectorSlot slot_;
351 }; 369 };
352 370
353 371
354 class CallICNexus : public FeedbackNexus { 372 class CallICNexus : public FeedbackNexus {
355 public: 373 public:
356 // Monomorphic call ics store call counts. Platform code needs to increment 374 // Monomorphic call ics store call counts. Platform code needs to increment
357 // the count appropriately (ie, by 2). 375 // the count appropriately (ie, by 2).
358 static const int kCallCountIncrement = 2; 376 static const int kCallCountIncrement = 2;
359 377
360 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) 378 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
361 : FeedbackNexus(vector, slot) { 379 : FeedbackNexus(vector, slot) {
362 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot)); 380 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
363 } 381 }
364 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 382 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
365 : FeedbackNexus(vector, slot) { 383 : FeedbackNexus(vector, slot) {
366 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot)); 384 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
367 } 385 }
368 386
369 void Clear(Code* host); 387 void Clear(Code* host);
370 388
371 void ConfigureMonomorphicArray(); 389 void ConfigureMonomorphicArray();
372 void ConfigureMonomorphic(Handle<JSFunction> function); 390 void ConfigureMonomorphic(Handle<JSFunction> function);
373 391
374 InlineCacheState StateFromFeedback() const override; 392 InlineCacheState StateFromFeedback() const override;
375 393
376 int ExtractMaps(MapHandleList* maps) const override { 394 int ExtractMaps(MapHandleList* maps) const override {
377 // CallICs don't record map feedback. 395 // CallICs don't record map feedback.
378 return 0; 396 return 0;
379 } 397 }
380 MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const override { 398 MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const override {
381 return MaybeHandle<Code>(); 399 return MaybeHandle<Code>();
382 } 400 }
383 bool FindHandlers(CodeHandleList* code_list, int length = -1) const override { 401 bool FindHandlers(CodeHandleList* code_list, int length = -1) const override {
384 return length == 0; 402 return length == 0;
385 } 403 }
386 404
387 int ExtractCallCount(); 405 int ExtractCallCount();
388 }; 406 };
389 407
390 408
391 class LoadICNexus : public FeedbackNexus { 409 class LoadICNexus : public FeedbackNexus {
392 public: 410 public:
393 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) 411 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
394 : FeedbackNexus(vector, slot) { 412 : FeedbackNexus(vector, slot) {
395 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot)); 413 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
396 } 414 }
397 explicit LoadICNexus(Isolate* isolate) 415 explicit LoadICNexus(Isolate* isolate)
398 : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate), 416 : FeedbackNexus(
399 TypeFeedbackVector::DummySlot( 417 TypeFeedbackVector::DummyVector(isolate),
400 TypeFeedbackVector::kDummyLoadICSlot)) {} 418 FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
401 LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 419 LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
402 : FeedbackNexus(vector, slot) { 420 : FeedbackNexus(vector, slot) {
403 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot)); 421 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
404 } 422 }
405 423
406 void Clear(Code* host); 424 void Clear(Code* host);
407 425
408 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); 426 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
409 427
410 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); 428 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
411 429
412 InlineCacheState StateFromFeedback() const override; 430 InlineCacheState StateFromFeedback() const override;
413 }; 431 };
414 432
415 433
416 class KeyedLoadICNexus : public FeedbackNexus { 434 class KeyedLoadICNexus : public FeedbackNexus {
417 public: 435 public:
418 KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) 436 KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
419 : FeedbackNexus(vector, slot) { 437 : FeedbackNexus(vector, slot) {
420 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); 438 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
421 } 439 }
422 KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 440 KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
423 : FeedbackNexus(vector, slot) { 441 : FeedbackNexus(vector, slot) {
424 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot)); 442 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
425 } 443 }
426 444
427 void Clear(Code* host); 445 void Clear(Code* host);
428 446
429 // name can be a null handle for element loads. 447 // name can be a null handle for element loads.
430 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, 448 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
431 Handle<Code> handler); 449 Handle<Code> handler);
432 // name can be null. 450 // name can be null.
433 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, 451 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
434 CodeHandleList* handlers); 452 CodeHandleList* handlers);
435 453
436 InlineCacheState StateFromFeedback() const override; 454 InlineCacheState StateFromFeedback() const override;
437 Name* FindFirstName() const override; 455 Name* FindFirstName() const override;
438 }; 456 };
439 457
440 458
441 class StoreICNexus : public FeedbackNexus { 459 class StoreICNexus : public FeedbackNexus {
442 public: 460 public:
443 StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) 461 StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
444 : FeedbackNexus(vector, slot) { 462 : FeedbackNexus(vector, slot) {
445 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot)); 463 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
446 } 464 }
447 explicit StoreICNexus(Isolate* isolate) 465 explicit StoreICNexus(Isolate* isolate)
448 : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate), 466 : FeedbackNexus(
449 TypeFeedbackVector::DummySlot( 467 TypeFeedbackVector::DummyVector(isolate),
450 TypeFeedbackVector::kDummyStoreICSlot)) {} 468 FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
451 StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 469 StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
452 : FeedbackNexus(vector, slot) { 470 : FeedbackNexus(vector, slot) {
453 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot)); 471 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
454 } 472 }
455 473
456 void Clear(Code* host); 474 void Clear(Code* host);
457 475
458 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); 476 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
459 477
460 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); 478 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
461 479
462 InlineCacheState StateFromFeedback() const override; 480 InlineCacheState StateFromFeedback() const override;
463 }; 481 };
464 482
465 483
466 class KeyedStoreICNexus : public FeedbackNexus { 484 class KeyedStoreICNexus : public FeedbackNexus {
467 public: 485 public:
468 KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, 486 KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
469 FeedbackVectorICSlot slot)
470 : FeedbackNexus(vector, slot) { 487 : FeedbackNexus(vector, slot) {
471 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot)); 488 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
472 } 489 }
473 explicit KeyedStoreICNexus(Isolate* isolate) 490 explicit KeyedStoreICNexus(Isolate* isolate)
474 : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate), 491 : FeedbackNexus(
475 TypeFeedbackVector::DummySlot( 492 TypeFeedbackVector::DummyVector(isolate),
476 TypeFeedbackVector::kDummyKeyedStoreICSlot)) {} 493 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
477 KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) 494 KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
478 : FeedbackNexus(vector, slot) { 495 : FeedbackNexus(vector, slot) {
479 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot)); 496 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
480 } 497 }
481 498
482 void Clear(Code* host); 499 void Clear(Code* host);
483 500
484 // name can be a null handle for element loads. 501 // name can be a null handle for element loads.
485 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, 502 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
486 Handle<Code> handler); 503 Handle<Code> handler);
487 // name can be null. 504 // name can be null.
488 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, 505 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
489 CodeHandleList* handlers); 506 CodeHandleList* handlers);
490 void ConfigurePolymorphic(MapHandleList* maps, 507 void ConfigurePolymorphic(MapHandleList* maps,
491 MapHandleList* transitioned_maps, 508 MapHandleList* transitioned_maps,
492 CodeHandleList* handlers); 509 CodeHandleList* handlers);
493 510
494 KeyedAccessStoreMode GetKeyedAccessStoreMode() const; 511 KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
495 IcCheckType GetKeyType() const; 512 IcCheckType GetKeyType() const;
496 513
497 InlineCacheState StateFromFeedback() const override; 514 InlineCacheState StateFromFeedback() const override;
498 Name* FindFirstName() const override; 515 Name* FindFirstName() const override;
499 }; 516 };
500 } // namespace internal 517 } // namespace internal
501 } // namespace v8 518 } // namespace v8
502 519
503 #endif // V8_TRANSITIONS_H_ 520 #endif // V8_TRANSITIONS_H_
OLDNEW
« no previous file with comments | « src/prettyprinter.cc ('k') | src/type-feedback-vector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698