| 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 #include "src/type-feedback-vector.h" | 5 #include "src/type-feedback-vector.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
| 9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| 11 #include "src/type-feedback-vector-inl.h" | 11 #include "src/type-feedback-vector-inl.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { | 16 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { |
| 17 return os << TypeFeedbackVector::Kind2String(kind); | 17 return os << TypeFeedbackVector::Kind2String(kind); |
| 18 } | 18 } |
| 19 | 19 |
| 20 | 20 |
| 21 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( | 21 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
| 22 FeedbackVectorICSlot slot) const { | 22 FeedbackVectorSlot slot) const { |
| 23 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 23 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 24 int data = Smi::cast(get(index))->value(); | 24 int data = Smi::cast(get(index))->value(); |
| 25 return VectorICComputer::decode(data, slot.ToInt()); | 25 return VectorICComputer::decode(data, slot.ToInt()); |
| 26 } | 26 } |
| 27 | 27 |
| 28 | 28 |
| 29 void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, | 29 void TypeFeedbackVector::SetKind(FeedbackVectorSlot slot, |
| 30 FeedbackVectorSlotKind kind) { | 30 FeedbackVectorSlotKind kind) { |
| 31 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 31 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 32 int data = Smi::cast(get(index))->value(); | 32 int data = Smi::cast(get(index))->value(); |
| 33 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); | 33 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); |
| 34 set(index, Smi::FromInt(new_data)); | 34 set(index, Smi::FromInt(new_data)); |
| 35 } | 35 } |
| 36 | 36 |
| 37 | 37 |
| 38 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 38 template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
| 39 Isolate* isolate, const StaticFeedbackVectorSpec* spec); | 39 Isolate* isolate, const StaticFeedbackVectorSpec* spec); |
| 40 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 40 template Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
| 41 Isolate* isolate, const FeedbackVectorSpec* spec); | 41 Isolate* isolate, const FeedbackVectorSpec* spec); |
| 42 | 42 |
| 43 | 43 |
| 44 // static | 44 // static |
| 45 template <typename Spec> | 45 template <typename Spec> |
| 46 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, | 46 Handle<TypeFeedbackVector> TypeFeedbackVector::New(Isolate* isolate, |
| 47 const Spec* spec) { | 47 const Spec* spec) { |
| 48 const int slot_count = spec->slots(); | 48 const int slot_count = spec->slots(); |
| 49 const int ic_slot_count = spec->ic_slots(); | 49 const int index_count = VectorICComputer::word_count(slot_count); |
| 50 const int index_count = VectorICComputer::word_count(ic_slot_count); | 50 const int length = slot_count + index_count + kReservedIndexCount; |
| 51 const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + | |
| 52 index_count + kReservedIndexCount; | |
| 53 if (length == kReservedIndexCount) { | 51 if (length == kReservedIndexCount) { |
| 54 return Handle<TypeFeedbackVector>::cast( | 52 return Handle<TypeFeedbackVector>::cast( |
| 55 isolate->factory()->empty_fixed_array()); | 53 isolate->factory()->empty_fixed_array()); |
| 56 } | 54 } |
| 55 #ifdef DEBUG |
| 56 for (int i = 0; i < slot_count;) { |
| 57 FeedbackVectorSlotKind kind = spec->GetKind(i); |
| 58 int entry_size = TypeFeedbackVector::GetSlotSize(kind); |
| 59 for (int j = 1; j < entry_size; j++) { |
| 60 FeedbackVectorSlotKind kind = spec->GetKind(i + j); |
| 61 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); |
| 62 } |
| 63 i += entry_size; |
| 64 } |
| 65 #endif |
| 57 | 66 |
| 58 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 67 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
| 59 if (ic_slot_count > 0) { | 68 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); |
| 60 array->set(kFirstICSlotIndex, | |
| 61 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); | |
| 62 } else { | |
| 63 array->set(kFirstICSlotIndex, Smi::FromInt(length)); | |
| 64 } | |
| 65 array->set(kWithTypesIndex, Smi::FromInt(0)); | 69 array->set(kWithTypesIndex, Smi::FromInt(0)); |
| 66 array->set(kGenericCountIndex, Smi::FromInt(0)); | 70 array->set(kGenericCountIndex, Smi::FromInt(0)); |
| 67 // Fill the indexes with zeros. | 71 // Fill the indexes with zeros. |
| 68 for (int i = 0; i < index_count; i++) { | 72 for (int i = 0; i < index_count; i++) { |
| 69 array->set(kReservedIndexCount + i, Smi::FromInt(0)); | 73 array->set(kReservedIndexCount + i, Smi::FromInt(0)); |
| 70 } | 74 } |
| 71 | 75 |
| 72 // Ensure we can skip the write barrier | 76 // Ensure we can skip the write barrier |
| 73 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 77 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
| 74 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | 78 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
| 75 for (int i = kReservedIndexCount + index_count; i < length; i++) { | 79 for (int i = kReservedIndexCount + index_count; i < length; i++) { |
| 76 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); | 80 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 77 } | 81 } |
| 78 | 82 |
| 79 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); | 83 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
| 80 for (int i = 0; i < ic_slot_count; i++) { | 84 for (int i = 0; i < slot_count; i++) { |
| 81 vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); | 85 vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
| 82 } | 86 } |
| 83 return vector; | 87 return vector; |
| 84 } | 88 } |
| 85 | 89 |
| 86 | 90 |
| 87 template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, | |
| 88 FeedbackVectorICSlot); | |
| 89 template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*, | |
| 90 FeedbackVectorSlot); | |
| 91 | |
| 92 | |
| 93 // static | 91 // static |
| 94 template <typename Spec> | 92 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, |
| 95 int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, | |
| 96 FeedbackVectorSlot slot) { | 93 FeedbackVectorSlot slot) { |
| 97 const int ic_slot_count = spec->ic_slots(); | 94 const int slot_count = spec->slots(); |
| 98 const int index_count = VectorICComputer::word_count(ic_slot_count); | 95 const int index_count = VectorICComputer::word_count(slot_count); |
| 99 return kReservedIndexCount + index_count + slot.ToInt(); | 96 return kReservedIndexCount + index_count + slot.ToInt(); |
| 100 } | 97 } |
| 101 | 98 |
| 102 | 99 |
| 103 // static | |
| 104 template <typename Spec> | |
| 105 int TypeFeedbackVector::GetIndexFromSpec(const Spec* spec, | |
| 106 FeedbackVectorICSlot slot) { | |
| 107 const int slot_count = spec->slots(); | |
| 108 const int ic_slot_count = spec->ic_slots(); | |
| 109 const int index_count = VectorICComputer::word_count(ic_slot_count); | |
| 110 return kReservedIndexCount + index_count + slot_count + | |
| 111 slot.ToInt() * elements_per_ic_slot(); | |
| 112 } | |
| 113 | |
| 114 | |
| 115 // static | 100 // static |
| 116 int TypeFeedbackVector::PushAppliedArgumentsIndex() { | 101 int TypeFeedbackVector::PushAppliedArgumentsIndex() { |
| 117 const int index_count = VectorICComputer::word_count(1); | 102 const int index_count = VectorICComputer::word_count(1); |
| 118 return kReservedIndexCount + index_count; | 103 return kReservedIndexCount + index_count; |
| 119 } | 104 } |
| 120 | 105 |
| 121 | 106 |
| 122 // static | 107 // static |
| 123 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( | 108 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( |
| 124 Isolate* isolate) { | 109 Isolate* isolate) { |
| 125 FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::KEYED_LOAD_IC}; | 110 StaticFeedbackVectorSpec spec; |
| 126 StaticFeedbackVectorSpec spec(0, 1, kinds); | 111 FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot(); |
| 127 Handle<TypeFeedbackVector> feedback_vector = | 112 Handle<TypeFeedbackVector> feedback_vector = |
| 128 isolate->factory()->NewTypeFeedbackVector(&spec); | 113 TypeFeedbackVector::New(isolate, &spec); |
| 129 DCHECK(PushAppliedArgumentsIndex() == | 114 DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot)); |
| 130 feedback_vector->GetIndex(FeedbackVectorICSlot(0))); | 115 USE(slot); |
| 131 return feedback_vector; | 116 return feedback_vector; |
| 132 } | 117 } |
| 133 | 118 |
| 134 | 119 |
| 135 // static | 120 // static |
| 136 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( | 121 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
| 137 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 122 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
| 138 Handle<TypeFeedbackVector> result; | 123 Handle<TypeFeedbackVector> result; |
| 139 result = Handle<TypeFeedbackVector>::cast( | 124 result = Handle<TypeFeedbackVector>::cast( |
| 140 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 125 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
| 141 return result; | 126 return result; |
| 142 } | 127 } |
| 143 | 128 |
| 144 | 129 |
| 145 bool TypeFeedbackVector::SpecDiffersFrom( | 130 bool TypeFeedbackVector::SpecDiffersFrom( |
| 146 const FeedbackVectorSpec* other_spec) const { | 131 const FeedbackVectorSpec* other_spec) const { |
| 147 if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) { | 132 if (other_spec->slots() != Slots()) { |
| 148 return true; | 133 return true; |
| 149 } | 134 } |
| 150 | 135 |
| 151 int ic_slots = ICSlots(); | 136 int slots = Slots(); |
| 152 for (int i = 0; i < ic_slots; i++) { | 137 for (int i = 0; i < slots; i++) { |
| 153 if (GetKind(FeedbackVectorICSlot(i)) != other_spec->GetKind(i)) { | 138 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
| 154 return true; | 139 return true; |
| 155 } | 140 } |
| 156 } | 141 } |
| 157 return false; | 142 return false; |
| 158 } | 143 } |
| 159 | 144 |
| 160 | 145 |
| 161 // This logic is copied from | 146 // This logic is copied from |
| 162 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. | 147 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. |
| 163 static bool ClearLogic(Heap* heap) { | 148 static bool ClearLogic(Isolate* isolate) { |
| 164 return FLAG_cleanup_code_caches_at_gc && | 149 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); |
| 165 heap->isolate()->serializer_enabled(); | |
| 166 } | 150 } |
| 167 | 151 |
| 168 | 152 |
| 169 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, | 153 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, |
| 170 bool force_clear) { | 154 bool force_clear) { |
| 171 int slots = Slots(); | 155 Isolate* isolate = GetIsolate(); |
| 172 Heap* heap = GetIsolate()->heap(); | |
| 173 | 156 |
| 174 if (!force_clear && !ClearLogic(heap)) return; | 157 if (!force_clear && !ClearLogic(isolate)) return; |
| 175 | 158 |
| 176 Object* uninitialized_sentinel = | 159 Object* uninitialized_sentinel = |
| 177 TypeFeedbackVector::RawUninitializedSentinel(heap); | 160 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
| 178 for (int i = 0; i < slots; i++) { | |
| 179 FeedbackVectorSlot slot(i); | |
| 180 Object* obj = Get(slot); | |
| 181 if (obj->IsHeapObject()) { | |
| 182 InstanceType instance_type = | |
| 183 HeapObject::cast(obj)->map()->instance_type(); | |
| 184 // AllocationSites are exempt from clearing. They don't store Maps | |
| 185 // or Code pointers which can cause memory leaks if not cleared | |
| 186 // regularly. | |
| 187 if (instance_type != ALLOCATION_SITE_TYPE) { | |
| 188 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); | |
| 189 } | |
| 190 } | |
| 191 } | |
| 192 } | |
| 193 | 161 |
| 162 TypeFeedbackMetadataIterator iter(this); |
| 163 while (iter.HasNext()) { |
| 164 FeedbackVectorSlot slot = iter.Next(); |
| 165 FeedbackVectorSlotKind kind = iter.kind(); |
| 194 | 166 |
| 195 void TypeFeedbackVector::ClearICSlotsImpl(SharedFunctionInfo* shared, | |
| 196 bool force_clear) { | |
| 197 Heap* heap = GetIsolate()->heap(); | |
| 198 | |
| 199 if (!force_clear && !ClearLogic(heap)) return; | |
| 200 | |
| 201 int slots = ICSlots(); | |
| 202 Code* host = shared->code(); | |
| 203 Object* uninitialized_sentinel = | |
| 204 TypeFeedbackVector::RawUninitializedSentinel(heap); | |
| 205 for (int i = 0; i < slots; i++) { | |
| 206 FeedbackVectorICSlot slot(i); | |
| 207 Object* obj = Get(slot); | 167 Object* obj = Get(slot); |
| 208 if (obj != uninitialized_sentinel) { | 168 if (obj != uninitialized_sentinel) { |
| 209 FeedbackVectorSlotKind kind = GetKind(slot); | |
| 210 switch (kind) { | 169 switch (kind) { |
| 211 case FeedbackVectorSlotKind::CALL_IC: { | 170 case FeedbackVectorSlotKind::CALL_IC: { |
| 212 CallICNexus nexus(this, slot); | 171 CallICNexus nexus(this, slot); |
| 213 nexus.Clear(host); | 172 nexus.Clear(shared->code()); |
| 214 break; | 173 break; |
| 215 } | 174 } |
| 216 case FeedbackVectorSlotKind::LOAD_IC: { | 175 case FeedbackVectorSlotKind::LOAD_IC: { |
| 217 LoadICNexus nexus(this, slot); | 176 LoadICNexus nexus(this, slot); |
| 218 nexus.Clear(host); | 177 nexus.Clear(shared->code()); |
| 219 break; | 178 break; |
| 220 } | 179 } |
| 221 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { | 180 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { |
| 222 KeyedLoadICNexus nexus(this, slot); | 181 KeyedLoadICNexus nexus(this, slot); |
| 223 nexus.Clear(host); | 182 nexus.Clear(shared->code()); |
| 224 break; | 183 break; |
| 225 } | 184 } |
| 226 case FeedbackVectorSlotKind::STORE_IC: { | 185 case FeedbackVectorSlotKind::STORE_IC: { |
| 227 DCHECK(FLAG_vector_stores); | 186 DCHECK(FLAG_vector_stores); |
| 228 StoreICNexus nexus(this, slot); | 187 StoreICNexus nexus(this, slot); |
| 229 nexus.Clear(host); | 188 nexus.Clear(shared->code()); |
| 230 break; | 189 break; |
| 231 } | 190 } |
| 232 case FeedbackVectorSlotKind::KEYED_STORE_IC: { | 191 case FeedbackVectorSlotKind::KEYED_STORE_IC: { |
| 233 DCHECK(FLAG_vector_stores); | 192 DCHECK(FLAG_vector_stores); |
| 234 KeyedStoreICNexus nexus(this, slot); | 193 KeyedStoreICNexus nexus(this, slot); |
| 235 nexus.Clear(host); | 194 nexus.Clear(shared->code()); |
| 236 break; | 195 break; |
| 237 } | 196 } |
| 238 case FeedbackVectorSlotKind::UNUSED: | 197 case FeedbackVectorSlotKind::GENERAL: { |
| 198 if (obj->IsHeapObject()) { |
| 199 InstanceType instance_type = |
| 200 HeapObject::cast(obj)->map()->instance_type(); |
| 201 // AllocationSites are exempt from clearing. They don't store Maps |
| 202 // or Code pointers which can cause memory leaks if not cleared |
| 203 // regularly. |
| 204 if (instance_type != ALLOCATION_SITE_TYPE) { |
| 205 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 206 } |
| 207 } |
| 208 break; |
| 209 } |
| 210 case FeedbackVectorSlotKind::INVALID: |
| 239 case FeedbackVectorSlotKind::KINDS_NUMBER: | 211 case FeedbackVectorSlotKind::KINDS_NUMBER: |
| 240 UNREACHABLE(); | 212 UNREACHABLE(); |
| 241 break; | 213 break; |
| 242 } | 214 } |
| 243 } | 215 } |
| 244 } | 216 } |
| 245 } | 217 } |
| 246 | 218 |
| 247 | 219 |
| 248 // static | 220 // static |
| 249 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { | 221 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { |
| 250 DCHECK(FLAG_vector_stores); | 222 DCHECK(FLAG_vector_stores); |
| 251 SharedFunctionInfo::Iterator iterator(isolate); | 223 SharedFunctionInfo::Iterator iterator(isolate); |
| 252 SharedFunctionInfo* shared; | 224 SharedFunctionInfo* shared; |
| 253 while ((shared = iterator.Next())) { | 225 while ((shared = iterator.Next())) { |
| 254 TypeFeedbackVector* vector = shared->feedback_vector(); | 226 TypeFeedbackVector* vector = shared->feedback_vector(); |
| 255 vector->ClearKeyedStoreICs(shared); | 227 vector->ClearKeyedStoreICs(shared); |
| 256 } | 228 } |
| 257 } | 229 } |
| 258 | 230 |
| 259 | 231 |
| 260 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { | 232 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
| 261 Heap* heap = GetIsolate()->heap(); | 233 Isolate* isolate = GetIsolate(); |
| 262 | 234 |
| 263 int slots = ICSlots(); | |
| 264 Code* host = shared->code(); | 235 Code* host = shared->code(); |
| 265 Object* uninitialized_sentinel = | 236 Object* uninitialized_sentinel = |
| 266 TypeFeedbackVector::RawUninitializedSentinel(heap); | 237 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
| 267 for (int i = 0; i < slots; i++) { | 238 |
| 268 FeedbackVectorICSlot slot(i); | 239 TypeFeedbackMetadataIterator iter(this); |
| 240 while (iter.HasNext()) { |
| 241 FeedbackVectorSlot slot = iter.Next(); |
| 242 FeedbackVectorSlotKind kind = iter.kind(); |
| 243 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; |
| 269 Object* obj = Get(slot); | 244 Object* obj = Get(slot); |
| 270 if (obj != uninitialized_sentinel) { | 245 if (obj != uninitialized_sentinel) { |
| 271 FeedbackVectorSlotKind kind = GetKind(slot); | 246 DCHECK(FLAG_vector_stores); |
| 272 if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) { | 247 KeyedStoreICNexus nexus(this, slot); |
| 273 DCHECK(FLAG_vector_stores); | 248 nexus.Clear(host); |
| 274 KeyedStoreICNexus nexus(this, slot); | |
| 275 nexus.Clear(host); | |
| 276 } | |
| 277 } | 249 } |
| 278 } | 250 } |
| 279 } | 251 } |
| 280 | 252 |
| 281 | 253 |
| 282 // static | 254 // static |
| 283 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { | 255 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { |
| 284 return Handle<TypeFeedbackVector>::cast(isolate->factory()->dummy_vector()); | 256 return isolate->factory()->dummy_vector(); |
| 285 } | 257 } |
| 286 | 258 |
| 287 | 259 |
| 288 const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { | 260 const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) { |
| 289 switch (kind) { | 261 switch (kind) { |
| 290 case FeedbackVectorSlotKind::UNUSED: | 262 case FeedbackVectorSlotKind::INVALID: |
| 291 return "UNUSED"; | 263 return "INVALID"; |
| 292 case FeedbackVectorSlotKind::CALL_IC: | 264 case FeedbackVectorSlotKind::CALL_IC: |
| 293 return "CALL_IC"; | 265 return "CALL_IC"; |
| 294 case FeedbackVectorSlotKind::LOAD_IC: | 266 case FeedbackVectorSlotKind::LOAD_IC: |
| 295 return "LOAD_IC"; | 267 return "LOAD_IC"; |
| 296 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 268 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
| 297 return "KEYED_LOAD_IC"; | 269 return "KEYED_LOAD_IC"; |
| 298 case FeedbackVectorSlotKind::STORE_IC: | 270 case FeedbackVectorSlotKind::STORE_IC: |
| 299 return "STORE_IC"; | 271 return "STORE_IC"; |
| 300 case FeedbackVectorSlotKind::KEYED_STORE_IC: | 272 case FeedbackVectorSlotKind::KEYED_STORE_IC: |
| 301 return "KEYED_STORE_IC"; | 273 return "KEYED_STORE_IC"; |
| 274 case FeedbackVectorSlotKind::GENERAL: |
| 275 return "STUB"; |
| 302 case FeedbackVectorSlotKind::KINDS_NUMBER: | 276 case FeedbackVectorSlotKind::KINDS_NUMBER: |
| 303 break; | 277 break; |
| 304 } | 278 } |
| 305 UNREACHABLE(); | 279 UNREACHABLE(); |
| 306 return "?"; | 280 return "?"; |
| 307 } | 281 } |
| 308 | 282 |
| 309 | 283 |
| 310 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { | 284 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { |
| 311 Isolate* isolate = GetIsolate(); | 285 Isolate* isolate = GetIsolate(); |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 return mode; | 805 return mode; |
| 832 } | 806 } |
| 833 | 807 |
| 834 | 808 |
| 835 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 809 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
| 836 // The structure of the vector slots tells us the type. | 810 // The structure of the vector slots tells us the type. |
| 837 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; | 811 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; |
| 838 } | 812 } |
| 839 } // namespace internal | 813 } // namespace internal |
| 840 } // namespace v8 | 814 } // namespace v8 |
| OLD | NEW |