| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // 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 | 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_INL_H_ | 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_INL_H_ | 
| 6 #define V8_TYPE_FEEDBACK_VECTOR_INL_H_ | 6 #define V8_TYPE_FEEDBACK_VECTOR_INL_H_ | 
| 7 | 7 | 
| 8 #include "src/type-feedback-vector.h" | 8 #include "src/type-feedback-vector.h" | 
| 9 | 9 | 
| 10 namespace v8 { | 10 namespace v8 { | 
| 11 namespace internal { | 11 namespace internal { | 
| 12 | 12 | 
|  | 13 | 
|  | 14 FeedbackVectorSlot FeedbackVectorSpec::AddSlot(FeedbackVectorSlotKind kind) { | 
|  | 15   int slot = slots(); | 
|  | 16   int entries_per_slot = TypeFeedbackVector::GetSlotSize(kind); | 
|  | 17   slot_kinds_.resize( | 
|  | 18       slot + entries_per_slot, | 
|  | 19       static_cast<unsigned char>(FeedbackVectorSlotKind::INVALID)); | 
|  | 20   slot_kinds_[slot] = static_cast<unsigned char>(kind); | 
|  | 21   return FeedbackVectorSlot(slot); | 
|  | 22 } | 
|  | 23 | 
|  | 24 | 
| 13 // static | 25 // static | 
| 14 TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) { | 26 TypeFeedbackVector* TypeFeedbackVector::cast(Object* obj) { | 
| 15   DCHECK(obj->IsTypeFeedbackVector()); | 27   DCHECK(obj->IsTypeFeedbackVector()); | 
| 16   return reinterpret_cast<TypeFeedbackVector*>(obj); | 28   return reinterpret_cast<TypeFeedbackVector*>(obj); | 
| 17 } | 29 } | 
| 18 | 30 | 
| 19 | 31 | 
| 20 int TypeFeedbackVector::first_ic_slot_index() const { | 32 int TypeFeedbackVector::GetSlotSize(FeedbackVectorSlotKind kind) { | 
| 21   DCHECK(length() >= kReservedIndexCount); | 33   DCHECK_NE(FeedbackVectorSlotKind::INVALID, kind); | 
| 22   return Smi::cast(get(kFirstICSlotIndex))->value(); | 34   DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, kind); | 
|  | 35   return kind == FeedbackVectorSlotKind::STUB ? 1 : 2; | 
| 23 } | 36 } | 
| 24 | 37 | 
| 25 | 38 | 
|  | 39 bool TypeFeedbackVector::is_empty() const { | 
|  | 40   if (length() == 0) return true; | 
|  | 41   DCHECK(length() >= kReservedIndexCount); | 
|  | 42   return false; | 
|  | 43 } | 
|  | 44 | 
|  | 45 | 
|  | 46 int TypeFeedbackVector::Slots() const { | 
|  | 47   if (length() == 0) return 0; | 
|  | 48   DCHECK(length() >= kReservedIndexCount); | 
|  | 49   return Smi::cast(get(kSlotsCountIndex))->value(); | 
|  | 50 } | 
|  | 51 | 
|  | 52 | 
| 26 int TypeFeedbackVector::ic_with_type_info_count() { | 53 int TypeFeedbackVector::ic_with_type_info_count() { | 
| 27   return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 54   return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 
| 28 } | 55 } | 
| 29 | 56 | 
| 30 | 57 | 
| 31 void TypeFeedbackVector::change_ic_with_type_info_count(int delta) { | 58 void TypeFeedbackVector::change_ic_with_type_info_count(int delta) { | 
| 32   if (delta == 0) return; | 59   if (delta == 0) return; | 
| 33   int value = ic_with_type_info_count() + delta; | 60   int value = ic_with_type_info_count() + delta; | 
| 34   // Could go negative because of the debugger. | 61   // Could go negative because of the debugger. | 
| 35   if (value >= 0) { | 62   if (value >= 0) { | 
| 36     set(kWithTypesIndex, Smi::FromInt(value)); | 63     set(kWithTypesIndex, Smi::FromInt(value)); | 
| 37   } | 64   } | 
| 38 } | 65 } | 
| 39 | 66 | 
| 40 | 67 | 
| 41 int TypeFeedbackVector::ic_generic_count() { | 68 int TypeFeedbackVector::ic_generic_count() { | 
| 42   return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; | 69   return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; | 
| 43 } | 70 } | 
| 44 | 71 | 
| 45 | 72 | 
| 46 void TypeFeedbackVector::change_ic_generic_count(int delta) { | 73 void TypeFeedbackVector::change_ic_generic_count(int delta) { | 
| 47   if (delta == 0) return; | 74   if (delta == 0) return; | 
| 48   int value = ic_generic_count() + delta; | 75   int value = ic_generic_count() + delta; | 
| 49   if (value >= 0) { | 76   if (value >= 0) { | 
| 50     set(kGenericCountIndex, Smi::FromInt(value)); | 77     set(kGenericCountIndex, Smi::FromInt(value)); | 
| 51   } | 78   } | 
| 52 } | 79 } | 
| 53 | 80 | 
| 54 | 81 | 
| 55 int TypeFeedbackVector::Slots() const { |  | 
| 56   if (length() == 0) return 0; |  | 
| 57   return Max( |  | 
| 58       0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount); |  | 
| 59 } |  | 
| 60 |  | 
| 61 |  | 
| 62 int TypeFeedbackVector::ICSlots() const { |  | 
| 63   if (length() == 0) return 0; |  | 
| 64   return (length() - first_ic_slot_index()) / elements_per_ic_slot(); |  | 
| 65 } |  | 
| 66 |  | 
| 67 |  | 
| 68 int TypeFeedbackVector::ic_metadata_length() const { | 82 int TypeFeedbackVector::ic_metadata_length() const { | 
| 69   return VectorICComputer::word_count(ICSlots()); | 83   return VectorICComputer::word_count(Slots()); | 
| 70 } | 84 } | 
| 71 | 85 | 
| 72 | 86 | 
| 73 // Conversion from a slot or ic slot to an integer index to the underlying |  | 
| 74 // array. |  | 
| 75 int TypeFeedbackVector::GetIndex(FeedbackVectorSlot slot) const { | 87 int TypeFeedbackVector::GetIndex(FeedbackVectorSlot slot) const { | 
| 76   DCHECK(slot.ToInt() < first_ic_slot_index()); | 88   DCHECK(slot.ToInt() < Slots()); | 
| 77   return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); | 89   return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); | 
| 78 } | 90 } | 
| 79 | 91 | 
| 80 | 92 | 
| 81 int TypeFeedbackVector::GetIndex(FeedbackVectorICSlot slot) const { |  | 
| 82   int first_ic_slot = first_ic_slot_index(); |  | 
| 83   DCHECK(slot.ToInt() < ICSlots()); |  | 
| 84   return first_ic_slot + slot.ToInt() * elements_per_ic_slot(); |  | 
| 85 } |  | 
| 86 |  | 
| 87 |  | 
| 88 // Conversion from an integer index to either a slot or an ic slot. The caller | 93 // Conversion from an integer index to either a slot or an ic slot. The caller | 
| 89 // should know what kind she expects. | 94 // should know what kind she expects. | 
| 90 FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const { | 95 FeedbackVectorSlot TypeFeedbackVector::ToSlot(int index) const { | 
| 91   DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); | 96   DCHECK(index >= kReservedIndexCount + ic_metadata_length() && | 
|  | 97          index < length()); | 
| 92   return FeedbackVectorSlot(index - ic_metadata_length() - kReservedIndexCount); | 98   return FeedbackVectorSlot(index - ic_metadata_length() - kReservedIndexCount); | 
| 93 } | 99 } | 
| 94 | 100 | 
| 95 | 101 | 
| 96 FeedbackVectorICSlot TypeFeedbackVector::ToICSlot(int index) const { |  | 
| 97   DCHECK(index >= first_ic_slot_index() && index < length()); |  | 
| 98   int ic_slot = (index - first_ic_slot_index()) / elements_per_ic_slot(); |  | 
| 99   return FeedbackVectorICSlot(ic_slot); |  | 
| 100 } |  | 
| 101 |  | 
| 102 |  | 
| 103 Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const { | 102 Object* TypeFeedbackVector::Get(FeedbackVectorSlot slot) const { | 
| 104   return get(GetIndex(slot)); | 103   return get(GetIndex(slot)); | 
| 105 } | 104 } | 
| 106 | 105 | 
| 107 | 106 | 
| 108 void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value, | 107 void TypeFeedbackVector::Set(FeedbackVectorSlot slot, Object* value, | 
| 109                              WriteBarrierMode mode) { | 108                              WriteBarrierMode mode) { | 
| 110   set(GetIndex(slot), value, mode); | 109   set(GetIndex(slot), value, mode); | 
| 111 } | 110 } | 
| 112 | 111 | 
| 113 | 112 | 
| 114 Object* TypeFeedbackVector::Get(FeedbackVectorICSlot slot) const { |  | 
| 115   return get(GetIndex(slot)); |  | 
| 116 } |  | 
| 117 |  | 
| 118 |  | 
| 119 void TypeFeedbackVector::Set(FeedbackVectorICSlot slot, Object* value, |  | 
| 120                              WriteBarrierMode mode) { |  | 
| 121   set(GetIndex(slot), value, mode); |  | 
| 122 } |  | 
| 123 |  | 
| 124 |  | 
| 125 Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) { | 113 Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) { | 
| 126   return isolate->factory()->uninitialized_symbol(); | 114   return isolate->factory()->uninitialized_symbol(); | 
| 127 } | 115 } | 
| 128 | 116 | 
| 129 | 117 | 
| 130 Handle<Object> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) { | 118 Handle<Object> TypeFeedbackVector::MegamorphicSentinel(Isolate* isolate) { | 
| 131   return isolate->factory()->megamorphic_symbol(); | 119   return isolate->factory()->megamorphic_symbol(); | 
| 132 } | 120 } | 
| 133 | 121 | 
| 134 | 122 | 
| 135 Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) { | 123 Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) { | 
| 136   return isolate->factory()->premonomorphic_symbol(); | 124   return isolate->factory()->premonomorphic_symbol(); | 
| 137 } | 125 } | 
| 138 | 126 | 
| 139 | 127 | 
| 140 Object* TypeFeedbackVector::RawUninitializedSentinel(Heap* heap) { | 128 Object* TypeFeedbackVector::RawUninitializedSentinel(Isolate* isolate) { | 
| 141   return heap->uninitialized_symbol(); | 129   return isolate->heap()->uninitialized_symbol(); | 
| 142 } | 130 } | 
| 143 | 131 | 
| 144 | 132 | 
| 145 Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); } | 133 Object* FeedbackNexus::GetFeedback() const { return vector()->Get(slot()); } | 
| 146 | 134 | 
| 147 | 135 | 
| 148 Object* FeedbackNexus::GetFeedbackExtra() const { | 136 Object* FeedbackNexus::GetFeedbackExtra() const { | 
| 149   DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1); | 137 #ifdef DEBUG | 
|  | 138   FeedbackVectorSlotKind kind = vector()->GetKind(slot()); | 
|  | 139   DCHECK_LT(1, TypeFeedbackVector::GetSlotSize(kind)); | 
|  | 140 #endif | 
| 150   int extra_index = vector()->GetIndex(slot()) + 1; | 141   int extra_index = vector()->GetIndex(slot()) + 1; | 
| 151   return vector()->get(extra_index); | 142   return vector()->get(extra_index); | 
| 152 } | 143 } | 
| 153 | 144 | 
| 154 | 145 | 
| 155 void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) { | 146 void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) { | 
| 156   vector()->Set(slot(), feedback, mode); | 147   vector()->Set(slot(), feedback, mode); | 
| 157 } | 148 } | 
| 158 | 149 | 
| 159 | 150 | 
| 160 void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra, | 151 void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra, | 
| 161                                      WriteBarrierMode mode) { | 152                                      WriteBarrierMode mode) { | 
| 162   DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1); | 153 #ifdef DEBUG | 
|  | 154   FeedbackVectorSlotKind kind = vector()->GetKind(slot()); | 
|  | 155   DCHECK_LT(1, TypeFeedbackVector::GetSlotSize(kind)); | 
|  | 156 #endif | 
| 163   int index = vector()->GetIndex(slot()) + 1; | 157   int index = vector()->GetIndex(slot()) + 1; | 
| 164   vector()->set(index, feedback_extra, mode); | 158   vector()->set(index, feedback_extra, mode); | 
| 165 } | 159 } | 
| 166 | 160 | 
| 167 | 161 | 
| 168 Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); } | 162 Isolate* FeedbackNexus::GetIsolate() const { return vector()->GetIsolate(); } | 
| 169 }  // namespace internal | 163 }  // namespace internal | 
| 170 }  // namespace v8 | 164 }  // namespace v8 | 
| 171 | 165 | 
| 172 #endif  // V8_TYPE_FEEDBACK_VECTOR_INL_H_ | 166 #endif  // V8_TYPE_FEEDBACK_VECTOR_INL_H_ | 
| OLD | NEW | 
|---|