OLD | NEW |
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 "src/checks.h" | 8 #include "src/checks.h" |
9 #include "src/elements-kind.h" | 9 #include "src/elements-kind.h" |
10 #include "src/heap/heap.h" | 10 #include "src/heap/heap.h" |
11 #include "src/isolate.h" | 11 #include "src/isolate.h" |
12 #include "src/objects.h" | 12 #include "src/objects.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 | 16 |
17 // The shape of the TypeFeedbackVector is an array with: | 17 // The shape of the TypeFeedbackVector is an array with: |
18 // 0: first_ic_slot_index (== length() if no ic slots are present) | 18 // 0: first_ic_slot_index (== length() if no ic slots are present) |
19 // 1: ics_with_types | 19 // 1: ics_with_types |
20 // 2: ics_with_generic_info | 20 // 2: ics_with_generic_info |
21 // 3: first feedback slot | 21 // 3: type information for ic slots, if any |
| 22 // ... |
| 23 // N: first feedback slot (N >= 3) |
22 // ... | 24 // ... |
23 // [<first_ic_slot_index>: feedback slot] | 25 // [<first_ic_slot_index>: feedback slot] |
24 // ...to length() - 1 | 26 // ...to length() - 1 |
25 // | 27 // |
26 class TypeFeedbackVector : public FixedArray { | 28 class TypeFeedbackVector : public FixedArray { |
27 public: | 29 public: |
28 // Casting. | 30 // Casting. |
29 static TypeFeedbackVector* cast(Object* obj) { | 31 static TypeFeedbackVector* cast(Object* obj) { |
30 DCHECK(obj->IsTypeFeedbackVector()); | 32 DCHECK(obj->IsTypeFeedbackVector()); |
31 return reinterpret_cast<TypeFeedbackVector*>(obj); | 33 return reinterpret_cast<TypeFeedbackVector*>(obj); |
32 } | 34 } |
33 | 35 |
34 static const int kReservedIndexCount = 3; | 36 static const int kReservedIndexCount = 3; |
35 static const int kFirstICSlotIndex = 0; | 37 static const int kFirstICSlotIndex = 0; |
36 static const int kWithTypesIndex = 1; | 38 static const int kWithTypesIndex = 1; |
37 static const int kGenericCountIndex = 2; | 39 static const int kGenericCountIndex = 2; |
38 | 40 |
39 int first_ic_slot_index() { | 41 int first_ic_slot_index() const { |
40 DCHECK(length() >= kReservedIndexCount); | 42 DCHECK(length() >= kReservedIndexCount); |
41 return Smi::cast(get(kFirstICSlotIndex))->value(); | 43 return Smi::cast(get(kFirstICSlotIndex))->value(); |
42 } | 44 } |
43 | 45 |
44 int ic_with_type_info_count() { | 46 int ic_with_type_info_count() { |
45 return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 47 return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; |
46 } | 48 } |
47 | 49 |
48 void change_ic_with_type_info_count(int delta) { | 50 void change_ic_with_type_info_count(int delta) { |
49 if (delta == 0) return; | 51 if (delta == 0) return; |
50 int value = ic_with_type_info_count() + delta; | 52 int value = ic_with_type_info_count() + delta; |
51 // Could go negative because of the debugger. | 53 // Could go negative because of the debugger. |
52 if (value >= 0) { | 54 if (value >= 0) { |
53 set(kWithTypesIndex, Smi::FromInt(value)); | 55 set(kWithTypesIndex, Smi::FromInt(value)); |
54 } | 56 } |
55 } | 57 } |
56 | 58 |
57 int ic_generic_count() { | 59 int ic_generic_count() { |
58 return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; | 60 return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; |
59 } | 61 } |
60 | 62 |
61 void change_ic_generic_count(int delta) { | 63 void change_ic_generic_count(int delta) { |
62 if (delta == 0) return; | 64 if (delta == 0) return; |
63 int value = ic_generic_count() + delta; | 65 int value = ic_generic_count() + delta; |
64 if (value >= 0) { | 66 if (value >= 0) { |
65 set(kGenericCountIndex, Smi::FromInt(value)); | 67 set(kGenericCountIndex, Smi::FromInt(value)); |
66 } | 68 } |
67 } | 69 } |
68 | 70 |
69 int Slots() { | 71 inline int ic_metadata_length() const; |
| 72 |
| 73 int Slots() const { |
70 if (length() == 0) return 0; | 74 if (length() == 0) return 0; |
71 return Max(0, first_ic_slot_index() - kReservedIndexCount); | 75 return Max( |
| 76 0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount); |
72 } | 77 } |
73 | 78 |
74 int ICSlots() { | 79 int ICSlots() const { |
75 if (length() == 0) return 0; | 80 if (length() == 0) return 0; |
76 return length() - first_ic_slot_index(); | 81 return length() - first_ic_slot_index(); |
77 } | 82 } |
78 | 83 |
79 // Conversion from a slot or ic slot to an integer index to the underlying | 84 // Conversion from a slot or ic slot to an integer index to the underlying |
80 // array. | 85 // array. |
81 int GetIndex(FeedbackVectorSlot slot) { | 86 int GetIndex(FeedbackVectorSlot slot) const { |
82 return kReservedIndexCount + slot.ToInt(); | 87 return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); |
83 } | 88 } |
84 | 89 |
85 int GetIndex(FeedbackVectorICSlot slot) { | 90 int GetIndex(FeedbackVectorICSlot slot) const { |
86 int first_ic_slot = first_ic_slot_index(); | 91 int first_ic_slot = first_ic_slot_index(); |
87 DCHECK(slot.ToInt() < ICSlots()); | 92 DCHECK(slot.ToInt() < ICSlots()); |
88 return first_ic_slot + slot.ToInt(); | 93 return first_ic_slot + slot.ToInt(); |
89 } | 94 } |
90 | 95 |
91 | |
92 // Conversion from an integer index to either a slot or an ic slot. The caller | 96 // Conversion from an integer index to either a slot or an ic slot. The caller |
93 // should know what kind she expects. | 97 // should know what kind she expects. |
94 FeedbackVectorSlot ToSlot(int index) { | 98 FeedbackVectorSlot ToSlot(int index) const { |
95 DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); | 99 DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); |
96 return FeedbackVectorSlot(index - kReservedIndexCount); | 100 return FeedbackVectorSlot(index - ic_metadata_length() - |
| 101 kReservedIndexCount); |
97 } | 102 } |
98 | 103 |
99 FeedbackVectorICSlot ToICSlot(int index) { | 104 FeedbackVectorICSlot ToICSlot(int index) const { |
100 DCHECK(index >= first_ic_slot_index() && index < length()); | 105 DCHECK(index >= first_ic_slot_index() && index < length()); |
101 return FeedbackVectorICSlot(index - first_ic_slot_index()); | 106 return FeedbackVectorICSlot(index - first_ic_slot_index()); |
102 } | 107 } |
103 | 108 |
104 Object* Get(FeedbackVectorSlot slot) { return get(GetIndex(slot)); } | 109 Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); } |
105 void Set(FeedbackVectorSlot slot, Object* value, | 110 void Set(FeedbackVectorSlot slot, Object* value, |
106 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 111 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
107 set(GetIndex(slot), value, mode); | 112 set(GetIndex(slot), value, mode); |
108 } | 113 } |
109 | 114 |
110 Object* Get(FeedbackVectorICSlot slot) { return get(GetIndex(slot)); } | 115 Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } |
111 void Set(FeedbackVectorICSlot slot, Object* value, | 116 void Set(FeedbackVectorICSlot slot, Object* value, |
112 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 117 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
113 set(GetIndex(slot), value, mode); | 118 set(GetIndex(slot), value, mode); |
114 } | 119 } |
115 | 120 |
| 121 // IC slots need metadata to recognize the type of IC. Set a Kind for every |
| 122 // slot. If GetKind() returns Code::NUMBER_OF_KINDS, then there is |
| 123 // no kind associated with this slot. This may happen in the current design |
| 124 // if a decision is made at compile time not to emit an IC that was planned |
| 125 // for at parse time. This can be eliminated if we encode kind at parse |
| 126 // time. |
| 127 Code::Kind GetKind(FeedbackVectorICSlot slot) const; |
| 128 void SetKind(FeedbackVectorICSlot slot, Code::Kind kind); |
116 | 129 |
117 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, | 130 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, |
118 int ic_slot_count); | 131 int ic_slot_count); |
119 | 132 |
120 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, | 133 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, |
121 Handle<TypeFeedbackVector> vector); | 134 Handle<TypeFeedbackVector> vector); |
122 | 135 |
123 // Clears the vector slots and the vector ic slots. | 136 // Clears the vector slots and the vector ic slots. |
124 void ClearSlots(SharedFunctionInfo* shared); | 137 void ClearSlots(SharedFunctionInfo* shared); |
125 | 138 |
(...skipping 12 matching lines...) Expand all Loading... |
138 // The object that indicates a monomorphic state of Array with | 151 // The object that indicates a monomorphic state of Array with |
139 // ElementsKind | 152 // ElementsKind |
140 static inline Handle<Object> MonomorphicArraySentinel( | 153 static inline Handle<Object> MonomorphicArraySentinel( |
141 Isolate* isolate, ElementsKind elements_kind); | 154 Isolate* isolate, ElementsKind elements_kind); |
142 | 155 |
143 // A raw version of the uninitialized sentinel that's safe to read during | 156 // A raw version of the uninitialized sentinel that's safe to read during |
144 // garbage collection (e.g., for patching the cache). | 157 // garbage collection (e.g., for patching the cache). |
145 static inline Object* RawUninitializedSentinel(Heap* heap); | 158 static inline Object* RawUninitializedSentinel(Heap* heap); |
146 | 159 |
147 private: | 160 private: |
| 161 enum VectorICKind { |
| 162 KindUnused = 0x0, |
| 163 KindCallIC = 0x1, |
| 164 KindLoadIC = 0x2, |
| 165 KindKeyedLoadIC = 0x3 |
| 166 }; |
| 167 |
| 168 static const int kVectorICKindBits = 2; |
| 169 static VectorICKind FromCodeKind(Code::Kind kind); |
| 170 static Code::Kind FromVectorICKind(VectorICKind kind); |
| 171 typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, |
| 172 uint32_t> VectorICComputer; |
| 173 |
148 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 174 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |
149 }; | 175 }; |
150 } | 176 } |
151 } // namespace v8::internal | 177 } // namespace v8::internal |
152 | 178 |
153 #endif // V8_TRANSITIONS_H_ | 179 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |