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: |
| 18 // 0: first_ic_slot_index (== length() if no ic slots are present) |
| 19 // 1: ics_with_types |
| 20 // 2: ics_with_generic_info |
| 21 // 3: first feedback slot |
| 22 // ... |
| 23 // [<first_ic_slot_index>: feedback slot] |
| 24 // ...to length() - 1 |
| 25 // |
17 class TypeFeedbackVector : public FixedArray { | 26 class TypeFeedbackVector : public FixedArray { |
18 public: | 27 public: |
19 // Casting. | 28 // Casting. |
20 static TypeFeedbackVector* cast(Object* obj) { | 29 static TypeFeedbackVector* cast(Object* obj) { |
21 DCHECK(obj->IsTypeFeedbackVector()); | 30 DCHECK(obj->IsTypeFeedbackVector()); |
22 return reinterpret_cast<TypeFeedbackVector*>(obj); | 31 return reinterpret_cast<TypeFeedbackVector*>(obj); |
23 } | 32 } |
24 | 33 |
| 34 static const int kReservedIndexCount = 3; |
| 35 static const int kFirstICSlotIndex = 0; |
| 36 static const int kWithTypesIndex = 1; |
| 37 static const int kGenericCountIndex = 2; |
| 38 |
| 39 int first_ic_slot_index() { |
| 40 DCHECK(length() >= kReservedIndexCount); |
| 41 return Smi::cast(get(kFirstICSlotIndex))->value(); |
| 42 } |
| 43 |
| 44 int ic_with_type_info_count() { |
| 45 return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; |
| 46 } |
| 47 |
| 48 void change_ic_with_type_info_count(int delta) { |
| 49 if (delta == 0) return; |
| 50 int value = ic_with_type_info_count() + delta; |
| 51 // Could go negative because of the debugger. |
| 52 if (value >= 0) { |
| 53 set(kWithTypesIndex, Smi::FromInt(value)); |
| 54 } |
| 55 } |
| 56 |
| 57 int ic_generic_count() { |
| 58 return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; |
| 59 } |
| 60 |
| 61 void change_ic_generic_count(int delta) { |
| 62 if (delta == 0) return; |
| 63 int value = ic_generic_count() + delta; |
| 64 if (value >= 0) { |
| 65 set(kGenericCountIndex, Smi::FromInt(value)); |
| 66 } |
| 67 } |
| 68 |
| 69 int Slots() { |
| 70 if (length() == 0) return 0; |
| 71 return Max(0, first_ic_slot_index() - kReservedIndexCount); |
| 72 } |
| 73 |
| 74 int ICSlots() { |
| 75 if (length() == 0) return 0; |
| 76 return length() - first_ic_slot_index(); |
| 77 } |
| 78 |
| 79 // Conversion from a slot or ic slot to an integer index to the underlying |
| 80 // array. |
| 81 int GetIndex(FeedbackVectorSlot slot) { |
| 82 return kReservedIndexCount + slot.ToInt(); |
| 83 } |
| 84 |
| 85 int GetIndex(FeedbackVectorICSlot slot) { |
| 86 int first_ic_slot = first_ic_slot_index(); |
| 87 DCHECK(slot.ToInt() < ICSlots()); |
| 88 return first_ic_slot + slot.ToInt(); |
| 89 } |
| 90 |
| 91 |
| 92 // Conversion from an integer index to either a slot or an ic slot. The caller |
| 93 // should know what kind she expects. |
| 94 FeedbackVectorSlot ToSlot(int index) { |
| 95 DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); |
| 96 return FeedbackVectorSlot(index - kReservedIndexCount); |
| 97 } |
| 98 |
| 99 FeedbackVectorICSlot ToICSlot(int index) { |
| 100 DCHECK(index >= first_ic_slot_index() && index < length()); |
| 101 return FeedbackVectorICSlot(index - first_ic_slot_index()); |
| 102 } |
| 103 |
| 104 Object* Get(FeedbackVectorSlot slot) { return get(GetIndex(slot)); } |
| 105 void Set(FeedbackVectorSlot slot, Object* value, |
| 106 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
| 107 set(GetIndex(slot), value, mode); |
| 108 } |
| 109 |
| 110 Object* Get(FeedbackVectorICSlot slot) { return get(GetIndex(slot)); } |
| 111 void Set(FeedbackVectorICSlot slot, Object* value, |
| 112 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
| 113 set(GetIndex(slot), value, mode); |
| 114 } |
| 115 |
| 116 |
| 117 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, |
| 118 int ic_slot_count); |
| 119 |
25 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, | 120 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, |
26 Handle<TypeFeedbackVector> vector); | 121 Handle<TypeFeedbackVector> vector); |
27 | 122 |
| 123 // Clears the vector slots and the vector ic slots. |
| 124 void ClearSlots(SharedFunctionInfo* shared); |
| 125 |
28 // The object that indicates an uninitialized cache. | 126 // The object that indicates an uninitialized cache. |
29 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); | 127 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); |
30 | 128 |
31 // The object that indicates a megamorphic state. | 129 // The object that indicates a megamorphic state. |
32 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate); | 130 static inline Handle<Object> MegamorphicSentinel(Isolate* isolate); |
33 | 131 |
34 // The object that indicates a premonomorphic state. | 132 // The object that indicates a premonomorphic state. |
35 static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate); | 133 static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate); |
36 | 134 |
37 // The object that indicates a generic state. | 135 // The object that indicates a generic state. |
38 static inline Handle<Object> GenericSentinel(Isolate* isolate); | 136 static inline Handle<Object> GenericSentinel(Isolate* isolate); |
39 | 137 |
40 // The object that indicates a monomorphic state of Array with | 138 // The object that indicates a monomorphic state of Array with |
41 // ElementsKind | 139 // ElementsKind |
42 static inline Handle<Object> MonomorphicArraySentinel( | 140 static inline Handle<Object> MonomorphicArraySentinel( |
43 Isolate* isolate, ElementsKind elements_kind); | 141 Isolate* isolate, ElementsKind elements_kind); |
44 | 142 |
45 // A raw version of the uninitialized sentinel that's safe to read during | 143 // A raw version of the uninitialized sentinel that's safe to read during |
46 // garbage collection (e.g., for patching the cache). | 144 // garbage collection (e.g., for patching the cache). |
47 static inline Object* RawUninitializedSentinel(Heap* heap); | 145 static inline Object* RawUninitializedSentinel(Heap* heap); |
48 | 146 |
49 private: | 147 private: |
50 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 148 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |
51 }; | 149 }; |
52 } | 150 } |
53 } // namespace v8::internal | 151 } // namespace v8::internal |
54 | 152 |
55 #endif // V8_TRANSITIONS_H_ | 153 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |