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 |