| 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/v8.h" | 5 #include "src/v8.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" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 return Code::KEYED_LOAD_IC; | 43 return Code::KEYED_LOAD_IC; |
| 44 case KindUnused: | 44 case KindUnused: |
| 45 break; | 45 break; |
| 46 } | 46 } |
| 47 // Sentinel for no information. | 47 // Sentinel for no information. |
| 48 return Code::NUMBER_OF_KINDS; | 48 return Code::NUMBER_OF_KINDS; |
| 49 } | 49 } |
| 50 | 50 |
| 51 | 51 |
| 52 Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const { | 52 Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const { |
| 53 if (!FLAG_vector_ics) { | |
| 54 // We only have CALL_ICs | |
| 55 return Code::CALL_IC; | |
| 56 } | |
| 57 | |
| 58 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 53 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 59 int data = Smi::cast(get(index))->value(); | 54 int data = Smi::cast(get(index))->value(); |
| 60 VectorICKind b = VectorICComputer::decode(data, slot.ToInt()); | 55 VectorICKind b = VectorICComputer::decode(data, slot.ToInt()); |
| 61 return FromVectorICKind(b); | 56 return FromVectorICKind(b); |
| 62 } | 57 } |
| 63 | 58 |
| 64 | 59 |
| 65 void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) { | 60 void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) { |
| 66 if (!FLAG_vector_ics) { | |
| 67 // Nothing to do if we only have CALL_ICs | |
| 68 return; | |
| 69 } | |
| 70 | |
| 71 VectorICKind b = FromCodeKind(kind); | 61 VectorICKind b = FromCodeKind(kind); |
| 72 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 62 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 73 int data = Smi::cast(get(index))->value(); | 63 int data = Smi::cast(get(index))->value(); |
| 74 int new_data = VectorICComputer::encode(data, slot.ToInt(), b); | 64 int new_data = VectorICComputer::encode(data, slot.ToInt(), b); |
| 75 set(index, Smi::FromInt(new_data)); | 65 set(index, Smi::FromInt(new_data)); |
| 76 } | 66 } |
| 77 | 67 |
| 78 | 68 |
| 79 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 69 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
| 80 Isolate* isolate, const FeedbackVectorSpec* spec); | 70 Isolate* isolate, const FeedbackVectorSpec* spec); |
| 81 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( | 71 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate( |
| 82 Isolate* isolate, const ZoneFeedbackVectorSpec* spec); | 72 Isolate* isolate, const ZoneFeedbackVectorSpec* spec); |
| 83 | 73 |
| 84 | 74 |
| 85 // static | 75 // static |
| 86 template <typename Spec> | 76 template <typename Spec> |
| 87 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, | 77 Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate, |
| 88 const Spec* spec) { | 78 const Spec* spec) { |
| 89 const int slot_count = spec->slots(); | 79 const int slot_count = spec->slots(); |
| 90 const int ic_slot_count = spec->ic_slots(); | 80 const int ic_slot_count = spec->ic_slots(); |
| 91 const int index_count = | 81 const int index_count = VectorICComputer::word_count(ic_slot_count); |
| 92 FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0; | |
| 93 const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + | 82 const int length = slot_count + (ic_slot_count * elements_per_ic_slot()) + |
| 94 index_count + kReservedIndexCount; | 83 index_count + kReservedIndexCount; |
| 95 if (length == kReservedIndexCount) { | 84 if (length == kReservedIndexCount) { |
| 96 return Handle<TypeFeedbackVector>::cast( | 85 return Handle<TypeFeedbackVector>::cast( |
| 97 isolate->factory()->empty_fixed_array()); | 86 isolate->factory()->empty_fixed_array()); |
| 98 } | 87 } |
| 99 | 88 |
| 100 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 89 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); |
| 101 if (ic_slot_count > 0) { | 90 if (ic_slot_count > 0) { |
| 102 array->set(kFirstICSlotIndex, | 91 array->set(kFirstICSlotIndex, |
| 103 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); | 92 Smi::FromInt(slot_count + index_count + kReservedIndexCount)); |
| 104 } else { | 93 } else { |
| 105 array->set(kFirstICSlotIndex, Smi::FromInt(length)); | 94 array->set(kFirstICSlotIndex, Smi::FromInt(length)); |
| 106 } | 95 } |
| 107 array->set(kWithTypesIndex, Smi::FromInt(0)); | 96 array->set(kWithTypesIndex, Smi::FromInt(0)); |
| 108 array->set(kGenericCountIndex, Smi::FromInt(0)); | 97 array->set(kGenericCountIndex, Smi::FromInt(0)); |
| 109 // Fill the indexes with zeros. | 98 // Fill the indexes with zeros. |
| 110 for (int i = 0; i < index_count; i++) { | 99 for (int i = 0; i < index_count; i++) { |
| 111 array->set(kReservedIndexCount + i, Smi::FromInt(0)); | 100 array->set(kReservedIndexCount + i, Smi::FromInt(0)); |
| 112 } | 101 } |
| 113 | 102 |
| 114 // Ensure we can skip the write barrier | 103 // Ensure we can skip the write barrier |
| 115 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 104 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); |
| 116 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); | 105 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); |
| 117 for (int i = kReservedIndexCount + index_count; i < length; i++) { | 106 for (int i = kReservedIndexCount + index_count; i < length; i++) { |
| 118 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); | 107 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); |
| 119 } | 108 } |
| 120 | 109 |
| 121 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); | 110 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); |
| 122 if (FLAG_vector_ics) { | 111 for (int i = 0; i < ic_slot_count; i++) { |
| 123 for (int i = 0; i < ic_slot_count; i++) { | 112 vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); |
| 124 vector->SetKind(FeedbackVectorICSlot(i), spec->GetKind(i)); | |
| 125 } | |
| 126 } | 113 } |
| 127 return vector; | 114 return vector; |
| 128 } | 115 } |
| 129 | 116 |
| 130 | 117 |
| 131 // static | 118 // static |
| 132 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( | 119 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( |
| 133 Isolate* isolate, Handle<TypeFeedbackVector> vector) { | 120 Isolate* isolate, Handle<TypeFeedbackVector> vector) { |
| 134 Handle<TypeFeedbackVector> result; | 121 Handle<TypeFeedbackVector> result; |
| 135 result = Handle<TypeFeedbackVector>::cast( | 122 result = Handle<TypeFeedbackVector>::cast( |
| 136 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); | 123 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); |
| 137 return result; | 124 return result; |
| 138 } | 125 } |
| 139 | 126 |
| 140 | 127 |
| 141 bool TypeFeedbackVector::SpecDiffersFrom( | 128 bool TypeFeedbackVector::SpecDiffersFrom( |
| 142 const ZoneFeedbackVectorSpec* other_spec) const { | 129 const ZoneFeedbackVectorSpec* other_spec) const { |
| 143 if (!FLAG_vector_ics) return false; | |
| 144 | |
| 145 if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) { | 130 if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) { |
| 146 return true; | 131 return true; |
| 147 } | 132 } |
| 148 | 133 |
| 149 int ic_slots = ICSlots(); | 134 int ic_slots = ICSlots(); |
| 150 for (int i = 0; i < ic_slots; i++) { | 135 for (int i = 0; i < ic_slots; i++) { |
| 151 if (GetKind(FeedbackVectorICSlot(i)) != other_spec->GetKind(i)) { | 136 if (GetKind(FeedbackVectorICSlot(i)) != other_spec->GetKind(i)) { |
| 152 return true; | 137 return true; |
| 153 } | 138 } |
| 154 } | 139 } |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; | 290 return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC; |
| 306 } | 291 } |
| 307 | 292 |
| 308 return UNINITIALIZED; | 293 return UNINITIALIZED; |
| 309 } | 294 } |
| 310 | 295 |
| 311 | 296 |
| 312 InlineCacheState CallICNexus::StateFromFeedback() const { | 297 InlineCacheState CallICNexus::StateFromFeedback() const { |
| 313 Isolate* isolate = GetIsolate(); | 298 Isolate* isolate = GetIsolate(); |
| 314 Object* feedback = GetFeedback(); | 299 Object* feedback = GetFeedback(); |
| 315 DCHECK(!FLAG_vector_ics || | 300 DCHECK(GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate) || |
| 316 GetFeedbackExtra() == *vector()->UninitializedSentinel(isolate) || | |
| 317 GetFeedbackExtra() == Smi::FromInt(kHasReturnedMinusZeroSentinel)); | 301 GetFeedbackExtra() == Smi::FromInt(kHasReturnedMinusZeroSentinel)); |
| 318 | 302 |
| 319 if (feedback == *vector()->MegamorphicSentinel(isolate)) { | 303 if (feedback == *vector()->MegamorphicSentinel(isolate)) { |
| 320 return GENERIC; | 304 return GENERIC; |
| 321 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { | 305 } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) { |
| 322 return MONOMORPHIC; | 306 return MONOMORPHIC; |
| 323 } | 307 } |
| 324 | 308 |
| 325 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); | 309 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); |
| 326 return UNINITIALIZED; | 310 return UNINITIALIZED; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 | 540 |
| 557 Name* KeyedLoadICNexus::FindFirstName() const { | 541 Name* KeyedLoadICNexus::FindFirstName() const { |
| 558 Object* feedback = GetFeedback(); | 542 Object* feedback = GetFeedback(); |
| 559 if (feedback->IsString()) { | 543 if (feedback->IsString()) { |
| 560 return Name::cast(feedback); | 544 return Name::cast(feedback); |
| 561 } | 545 } |
| 562 return NULL; | 546 return NULL; |
| 563 } | 547 } |
| 564 } | 548 } |
| 565 } // namespace v8::internal | 549 } // namespace v8::internal |
| OLD | NEW |