blob: 770b5e5dedd7fdf66d603534a843d98b1928b7ea [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
5#ifndef V8_TYPE_FEEDBACK_VECTOR_H_
6#define V8_TYPE_FEEDBACK_VECTOR_H_
7
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include <vector>
9
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/base/logging.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/elements-kind.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012#include "src/objects.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/zone-containers.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
15namespace v8 {
16namespace internal {
17
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018
19enum class FeedbackVectorSlotKind {
20 // This kind means that the slot points to the middle of other slot
21 // which occupies more than one feedback vector element.
22 // There must be no such slots in the system.
23 INVALID,
24
25 CALL_IC,
26 LOAD_IC,
27 KEYED_LOAD_IC,
28 STORE_IC,
29 KEYED_STORE_IC,
30
31 // This is a general purpose slot that occupies one feedback vector element.
32 GENERAL,
33
34 KINDS_NUMBER // Last value indicating number of kinds.
35};
36
37
38std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
39
40
41template <typename Derived>
42class FeedbackVectorSpecBase {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040043 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind);
45
46 FeedbackVectorSlot AddCallICSlot() {
47 return AddSlot(FeedbackVectorSlotKind::CALL_IC);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048 }
49
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 FeedbackVectorSlot AddLoadICSlot() {
51 return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
52 }
53
54 FeedbackVectorSlot AddKeyedLoadICSlot() {
55 return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
56 }
57
58 FeedbackVectorSlot AddStoreICSlot() {
59 return AddSlot(FeedbackVectorSlotKind::STORE_IC);
60 }
61
62 FeedbackVectorSlot AddKeyedStoreICSlot() {
63 return AddSlot(FeedbackVectorSlotKind::KEYED_STORE_IC);
64 }
65
66 FeedbackVectorSlot AddGeneralSlot() {
67 return AddSlot(FeedbackVectorSlotKind::GENERAL);
68 }
69};
70
71
72class StaticFeedbackVectorSpec
73 : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
74 public:
75 StaticFeedbackVectorSpec() : slots_(0) {}
76
Emily Bernierd0a1eb72015-03-24 16:35:39 -040077 int slots() const { return slots_; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040078
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 FeedbackVectorSlotKind GetKind(int slot) const {
80 DCHECK(slot >= 0 && slot < slots_);
81 return kinds_[slot];
Emily Bernierd0a1eb72015-03-24 16:35:39 -040082 }
83
84 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 friend class FeedbackVectorSpecBase<StaticFeedbackVectorSpec>;
86
87 void append(FeedbackVectorSlotKind kind) {
88 DCHECK(slots_ < kMaxLength);
89 kinds_[slots_++] = kind;
90 }
91
92 static const int kMaxLength = 12;
93
Emily Bernierd0a1eb72015-03-24 16:35:39 -040094 int slots_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 FeedbackVectorSlotKind kinds_[kMaxLength];
96};
97
98
99class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
100 public:
101 explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone) {
102 slot_kinds_.reserve(16);
103 }
104
105 int slots() const { return static_cast<int>(slot_kinds_.size()); }
106
107 FeedbackVectorSlotKind GetKind(int slot) const {
108 return static_cast<FeedbackVectorSlotKind>(slot_kinds_.at(slot));
109 }
110
111 private:
112 friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
113
114 void append(FeedbackVectorSlotKind kind) {
115 slot_kinds_.push_back(static_cast<unsigned char>(kind));
116 }
117
118 ZoneVector<unsigned char> slot_kinds_;
119};
120
121
122// The shape of the TypeFeedbackMetadata is an array with:
123// 0: slot_count
124// 1..N: slot kinds packed into a bit vector
125//
126class TypeFeedbackMetadata : public FixedArray {
127 public:
128 // Casting.
129 static inline TypeFeedbackMetadata* cast(Object* obj);
130
131 static const int kSlotsCountIndex = 0;
132 static const int kReservedIndexCount = 1;
133
134 // Returns number of feedback vector elements used by given slot kind.
135 static inline int GetSlotSize(FeedbackVectorSlotKind kind);
136
137 bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
138
139 // Returns number of slots in the vector.
140 inline int slot_count() const;
141
142 // Returns slot kind for given slot.
143 FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
144
145 template <typename Spec>
146 static Handle<TypeFeedbackMetadata> New(Isolate* isolate, const Spec* spec);
147
148#ifdef OBJECT_PRINT
149 // For gdb debugging.
150 void Print();
151#endif // OBJECT_PRINT
152
153 DECLARE_PRINTER(TypeFeedbackMetadata)
154
155 static const char* Kind2String(FeedbackVectorSlotKind kind);
156
157 private:
158 static const int kFeedbackVectorSlotKindBits = 3;
159 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
160 (1 << kFeedbackVectorSlotKindBits));
161
162 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
163
164 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
165 kSmiValueSize, uint32_t> VectorICComputer;
166
167 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168};
169
170
171// The shape of the TypeFeedbackVector is an array with:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172// 0: feedback metadata
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173// 1: ics_with_types
174// 2: ics_with_generic_info
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175// 3: feedback slot #0 (N >= 3)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400176// ...
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177// N + slot_count - 1: feedback slot #(slot_count-1)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400178//
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179class TypeFeedbackVector : public FixedArray {
180 public:
181 // Casting.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 static inline TypeFeedbackVector* cast(Object* obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 static const int kMetadataIndex = 0;
185 static const int kReservedIndexCount = 1;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400186
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 inline void ComputeCounts(int* with_type_info, int* generic);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 inline bool is_empty() const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400190
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000191 // Returns number of slots in the vector.
192 inline int slot_count() const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000194 inline TypeFeedbackMetadata* metadata() const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000196 // Conversion from a slot to an integer index to the underlying array.
197 inline int GetIndex(FeedbackVectorSlot slot) const;
198 static int GetIndexFromSpec(const FeedbackVectorSpec* spec,
199 FeedbackVectorSlot slot);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 // Conversion from an integer index to the underlying array to a slot.
202 inline FeedbackVectorSlot ToSlot(int index) const;
203 inline Object* Get(FeedbackVectorSlot slot) const;
204 inline void Set(FeedbackVectorSlot slot, Object* value,
205 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400206
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 // Returns slot kind for given slot.
208 inline FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 static Handle<TypeFeedbackVector> New(Isolate* isolate,
211 Handle<TypeFeedbackMetadata> metadata);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
214 Handle<TypeFeedbackVector> vector);
215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216#ifdef OBJECT_PRINT
217 // For gdb debugging.
218 void Print();
219#endif // OBJECT_PRINT
220
221 DECLARE_PRINTER(TypeFeedbackVector)
222
223 // Clears the vector slots.
224 void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); }
225
226 void ClearSlotsAtGCTime(SharedFunctionInfo* shared) {
227 ClearSlotsImpl(shared, false);
228 }
229
230 static void ClearAllKeyedStoreICs(Isolate* isolate);
231 void ClearKeyedStoreICs(SharedFunctionInfo* shared);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400232
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 // The object that indicates an uninitialized cache.
Ben Murdochda12d292016-06-02 14:46:10 +0100234 static inline Handle<Symbol> UninitializedSentinel(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235
236 // The object that indicates a megamorphic state.
Ben Murdochda12d292016-06-02 14:46:10 +0100237 static inline Handle<Symbol> MegamorphicSentinel(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238
239 // The object that indicates a premonomorphic state.
Ben Murdochda12d292016-06-02 14:46:10 +0100240 static inline Handle<Symbol> PremonomorphicSentinel(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 // A raw version of the uninitialized sentinel that's safe to read during
243 // garbage collection (e.g., for patching the cache).
Ben Murdochda12d292016-06-02 14:46:10 +0100244 static inline Symbol* RawUninitializedSentinel(Isolate* isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245
246 static const int kDummyLoadICSlot = 0;
247 static const int kDummyKeyedLoadICSlot = 2;
248 static const int kDummyStoreICSlot = 4;
249 static const int kDummyKeyedStoreICSlot = 6;
250
251 static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate);
252 static FeedbackVectorSlot DummySlot(int dummyIndex) {
253 DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot);
254 return FeedbackVectorSlot(dummyIndex);
255 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000256
257 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258 void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
261};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400262
263
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000264// The following asserts protect an optimization in type feedback vector
265// code that looks into the contents of a slot assuming to find a String,
266// a Symbol, an AllocationSite, a WeakCell, or a FixedArray.
267STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
268STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
269STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
270STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot);
271// Verify that an empty hash field looks like a tagged object, but can't
272// possibly be confused with a pointer.
273STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
274STATIC_ASSERT(Name::kEmptyHashField == 0x3);
275// Verify that a set hash field will not look like a tagged object.
276STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
277
278
279class TypeFeedbackMetadataIterator {
280 public:
281 explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)
282 : metadata_handle_(metadata),
283 slot_(FeedbackVectorSlot(0)),
284 slot_kind_(FeedbackVectorSlotKind::INVALID) {}
285
286 explicit TypeFeedbackMetadataIterator(TypeFeedbackMetadata* metadata)
287 : metadata_(metadata),
288 slot_(FeedbackVectorSlot(0)),
289 slot_kind_(FeedbackVectorSlotKind::INVALID) {}
290
291 bool HasNext() const { return slot_.ToInt() < metadata()->slot_count(); }
292
293 FeedbackVectorSlot Next() {
294 DCHECK(HasNext());
295 FeedbackVectorSlot slot = slot_;
296 slot_kind_ = metadata()->GetKind(slot);
297 slot_ = FeedbackVectorSlot(slot_.ToInt() + entry_size());
298 return slot;
299 }
300
301 // Returns slot kind of the last slot returned by Next().
302 FeedbackVectorSlotKind kind() const {
303 DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_);
304 DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_);
305 return slot_kind_;
306 }
307
308 // Returns entry size of the last slot returned by Next().
309 int entry_size() const { return TypeFeedbackMetadata::GetSlotSize(kind()); }
310
311 private:
312 TypeFeedbackMetadata* metadata() const {
313 return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
314 }
315
316 // The reason for having a handle and a raw pointer to the meta data is
317 // to have a single iterator implementation for both "handlified" and raw
318 // pointer use cases.
319 Handle<TypeFeedbackMetadata> metadata_handle_;
320 TypeFeedbackMetadata* metadata_;
321 FeedbackVectorSlot slot_;
322 FeedbackVectorSlotKind slot_kind_;
323};
324
325
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400326// A FeedbackNexus is the combination of a TypeFeedbackVector and a slot.
327// Derived classes customize the update and retrieval of feedback.
328class FeedbackNexus {
329 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400331 : vector_handle_(vector), vector_(NULL), slot_(slot) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000332 FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400333 : vector_(vector), slot_(slot) {}
334 virtual ~FeedbackNexus() {}
335
336 Handle<TypeFeedbackVector> vector_handle() const {
337 DCHECK(vector_ == NULL);
338 return vector_handle_;
339 }
340 TypeFeedbackVector* vector() const {
341 return vector_handle_.is_null() ? vector_ : *vector_handle_;
342 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000343 FeedbackVectorSlot slot() const { return slot_; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400344
345 InlineCacheState ic_state() const { return StateFromFeedback(); }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100346 bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400347 Map* FindFirstMap() const {
348 MapHandleList maps;
349 ExtractMaps(&maps);
350 if (maps.length() > 0) return *maps.at(0);
351 return NULL;
352 }
353
354 // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
355 void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
356
357 virtual InlineCacheState StateFromFeedback() const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358 virtual int ExtractMaps(MapHandleList* maps) const;
359 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const;
360 virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400361 virtual Name* FindFirstName() const { return NULL; }
362
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000363 virtual void ConfigureUninitialized();
364 virtual void ConfigurePremonomorphic();
365 virtual void ConfigureMegamorphic();
366
367 inline Object* GetFeedback() const;
368 inline Object* GetFeedbackExtra() const;
369
370 inline Isolate* GetIsolate() const;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400371
372 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373 inline void SetFeedback(Object* feedback,
374 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
375 inline void SetFeedbackExtra(Object* feedback_extra,
376 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400377
378 Handle<FixedArray> EnsureArrayOfSize(int length);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 Handle<FixedArray> EnsureExtraArrayOfSize(int length);
380 void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400381 CodeHandleList* handlers);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400382
383 private:
384 // The reason for having a vector handle and a raw pointer is that we can and
385 // should use handles during IC miss, but not during GC when we clear ICs. If
386 // you have a handle to the vector that is better because more operations can
387 // be done, like allocation.
388 Handle<TypeFeedbackVector> vector_handle_;
389 TypeFeedbackVector* vector_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 FeedbackVectorSlot slot_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400391};
392
393
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000394class CallICNexus final : public FeedbackNexus {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400395 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000396 // Monomorphic call ics store call counts. Platform code needs to increment
397 // the count appropriately (ie, by 2).
398 static const int kCallCountIncrement = 2;
399
400 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400401 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000402 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400403 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400405 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000406 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400407 }
408
409 void Clear(Code* host);
410
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400411 void ConfigureMonomorphicArray();
412 void ConfigureMonomorphic(Handle<JSFunction> function);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413 void ConfigureMegamorphic() final;
414 void ConfigureMegamorphic(int call_count);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400415
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416 InlineCacheState StateFromFeedback() const final;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400417
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000418 int ExtractMaps(MapHandleList* maps) const final {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400419 // CallICs don't record map feedback.
420 return 0;
421 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000422 MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400423 return MaybeHandle<Code>();
424 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425 bool FindHandlers(CodeHandleList* code_list, int length = -1) const final {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400426 return length == 0;
427 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428
429 int ExtractCallCount();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400430};
431
432
433class LoadICNexus : public FeedbackNexus {
434 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400436 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400438 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 explicit LoadICNexus(Isolate* isolate)
440 : FeedbackNexus(
441 TypeFeedbackVector::DummyVector(isolate),
442 FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
443 LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400444 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400446 }
447
448 void Clear(Code* host);
449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400451
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400453
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000454 InlineCacheState StateFromFeedback() const override;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400455};
456
457
458class KeyedLoadICNexus : public FeedbackNexus {
459 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400461 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400463 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400465 : FeedbackNexus(vector, slot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000466 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400467 }
468
469 void Clear(Code* host);
470
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400471 // name can be a null handle for element loads.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000472 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400473 Handle<Code> handler);
474 // name can be null.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400476 CodeHandleList* handlers);
477
Ben Murdoch097c5b22016-05-18 11:27:45 +0100478 void ConfigureMegamorphicKeyed(IcCheckType property_type);
479
480 IcCheckType GetKeyType() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000481 InlineCacheState StateFromFeedback() const override;
482 Name* FindFirstName() const override;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400483};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484
485
486class StoreICNexus : public FeedbackNexus {
487 public:
488 StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
489 : FeedbackNexus(vector, slot) {
490 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
491 }
492 explicit StoreICNexus(Isolate* isolate)
493 : FeedbackNexus(
494 TypeFeedbackVector::DummyVector(isolate),
495 FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
496 StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
497 : FeedbackNexus(vector, slot) {
498 DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
499 }
500
501 void Clear(Code* host);
502
503 void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
504
505 void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
506
507 InlineCacheState StateFromFeedback() const override;
508};
509
510
511class KeyedStoreICNexus : public FeedbackNexus {
512 public:
513 KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
514 : FeedbackNexus(vector, slot) {
515 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
516 }
517 explicit KeyedStoreICNexus(Isolate* isolate)
518 : FeedbackNexus(
519 TypeFeedbackVector::DummyVector(isolate),
520 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
521 KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
522 : FeedbackNexus(vector, slot) {
523 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
524 }
525
526 void Clear(Code* host);
527
528 // name can be a null handle for element loads.
529 void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
530 Handle<Code> handler);
531 // name can be null.
532 void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
533 CodeHandleList* handlers);
534 void ConfigurePolymorphic(MapHandleList* maps,
535 MapHandleList* transitioned_maps,
536 CodeHandleList* handlers);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100537 void ConfigureMegamorphicKeyed(IcCheckType property_type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000538
539 KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
540 IcCheckType GetKeyType() const;
541
542 InlineCacheState StateFromFeedback() const override;
543 Name* FindFirstName() const override;
544};
545} // namespace internal
546} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000547
548#endif // V8_TRANSITIONS_H_