Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/type-feedback-vector.cc

Issue 1384673002: The metadata part of TypeFeedbackVector is extracted to TypeFeedbackMetadata array. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Cleanup Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-feedback-vector-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 << TypeFeedbackMetadata::Kind2String(kind);
18 } 18 }
19 19
20 20
21 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 21 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind(
22 FeedbackVectorSlot 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(FeedbackVectorSlot slot, 29 void TypeFeedbackMetadata::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::New( 38 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
39 Isolate* isolate, const StaticFeedbackVectorSpec* spec); 39 Isolate* isolate, const StaticFeedbackVectorSpec* spec);
40 template Handle<TypeFeedbackVector> TypeFeedbackVector::New( 40 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::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::New(Isolate* isolate, 46 Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::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 index_count = VectorICComputer::word_count(slot_count); 49 const int slot_kinds_length = VectorICComputer::word_count(slot_count);
50 const int length = slot_count + index_count + kReservedIndexCount; 50 const int length = slot_kinds_length + kReservedIndexCount;
51 if (length == kReservedIndexCount) { 51 if (length == kReservedIndexCount) {
52 return Handle<TypeFeedbackVector>::cast( 52 return Handle<TypeFeedbackMetadata>::cast(
53 isolate->factory()->empty_fixed_array()); 53 isolate->factory()->empty_fixed_array());
54 } 54 }
55 #ifdef DEBUG 55 #ifdef DEBUG
56 for (int i = 0; i < slot_count;) { 56 for (int i = 0; i < slot_count;) {
57 FeedbackVectorSlotKind kind = spec->GetKind(i); 57 FeedbackVectorSlotKind kind = spec->GetKind(i);
58 int entry_size = TypeFeedbackVector::GetSlotSize(kind); 58 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
59 for (int j = 1; j < entry_size; j++) { 59 for (int j = 1; j < entry_size; j++) {
60 FeedbackVectorSlotKind kind = spec->GetKind(i + j); 60 FeedbackVectorSlotKind kind = spec->GetKind(i + j);
61 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind); 61 DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind);
62 } 62 }
63 i += entry_size; 63 i += entry_size;
64 } 64 }
65 #endif 65 #endif
66 66
67 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); 67 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
68 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); 68 array->set(kSlotsCountIndex, Smi::FromInt(slot_count));
69 array->set(kWithTypesIndex, Smi::FromInt(0)); 69 // Fill the bit-vector part with zeros.
70 array->set(kGenericCountIndex, Smi::FromInt(0)); 70 for (int i = 0; i < slot_kinds_length; i++) {
71 // Fill the indexes with zeros.
72 for (int i = 0; i < index_count; i++) {
73 array->set(kReservedIndexCount + i, Smi::FromInt(0)); 71 array->set(kReservedIndexCount + i, Smi::FromInt(0));
74 } 72 }
75 73
74 Handle<TypeFeedbackMetadata> metadata =
75 Handle<TypeFeedbackMetadata>::cast(array);
76 for (int i = 0; i < slot_count; i++) {
77 metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i));
78 }
79 return metadata;
80 }
81
82
83 bool TypeFeedbackMetadata::SpecDiffersFrom(
84 const FeedbackVectorSpec* other_spec) const {
85 if (other_spec->slots() != slot_count()) {
86 return true;
87 }
88
89 int slots = slot_count();
90 for (int i = 0; i < slots; i++) {
91 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) {
92 return true;
93 }
94 }
95 return false;
96 }
97
98
99 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
100 switch (kind) {
101 case FeedbackVectorSlotKind::INVALID:
102 return "INVALID";
103 case FeedbackVectorSlotKind::CALL_IC:
104 return "CALL_IC";
105 case FeedbackVectorSlotKind::LOAD_IC:
106 return "LOAD_IC";
107 case FeedbackVectorSlotKind::KEYED_LOAD_IC:
108 return "KEYED_LOAD_IC";
109 case FeedbackVectorSlotKind::STORE_IC:
110 return "STORE_IC";
111 case FeedbackVectorSlotKind::KEYED_STORE_IC:
112 return "KEYED_STORE_IC";
113 case FeedbackVectorSlotKind::GENERAL:
114 return "STUB";
115 case FeedbackVectorSlotKind::KINDS_NUMBER:
116 break;
117 }
118 UNREACHABLE();
119 return "?";
120 }
121
122
123 // static
124 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
125 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
126 Factory* factory = isolate->factory();
127
128 const int slot_count = metadata->slot_count();
129 const int length = slot_count + kReservedIndexCount;
130 if (length == kReservedIndexCount) {
131 return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array());
132 }
133
134 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
135 array->set(kMetadataIndex, *metadata);
136 array->set(kWithTypesIndex, Smi::FromInt(0));
137 array->set(kGenericCountIndex, Smi::FromInt(0));
138
76 // Ensure we can skip the write barrier 139 // Ensure we can skip the write barrier
77 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 140 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
78 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); 141 DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel);
79 for (int i = kReservedIndexCount + index_count; i < length; i++) { 142 for (int i = kReservedIndexCount; i < length; i++) {
80 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER); 143 array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
81 } 144 }
82 145
83 Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array); 146 return Handle<TypeFeedbackVector>::cast(array);
84 for (int i = 0; i < slot_count; i++) {
85 vector->SetKind(FeedbackVectorSlot(i), spec->GetKind(i));
86 }
87 return vector;
88 } 147 }
89 148
90 149
91 // static 150 // static
92 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, 151 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
93 FeedbackVectorSlot slot) { 152 FeedbackVectorSlot slot) {
94 const int slot_count = spec->slots(); 153 return kReservedIndexCount + slot.ToInt();
95 const int index_count = VectorICComputer::word_count(slot_count);
96 return kReservedIndexCount + index_count + slot.ToInt();
97 } 154 }
98 155
99 156
100 // static 157 // static
101 int TypeFeedbackVector::PushAppliedArgumentsIndex() { 158 int TypeFeedbackVector::PushAppliedArgumentsIndex() {
102 const int index_count = VectorICComputer::word_count(1); 159 return kReservedIndexCount;
103 return kReservedIndexCount + index_count;
104 } 160 }
105 161
106 162
107 // static 163 // static
108 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector( 164 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
109 Isolate* isolate) { 165 Isolate* isolate) {
110 StaticFeedbackVectorSpec spec; 166 StaticFeedbackVectorSpec spec;
111 FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot(); 167 FeedbackVectorSlot slot = spec.AddKeyedLoadICSlot();
168 // TODO(ishell): allocate this metadata only once.
169 Handle<TypeFeedbackMetadata> feedback_metadata =
170 TypeFeedbackMetadata::New(isolate, &spec);
112 Handle<TypeFeedbackVector> feedback_vector = 171 Handle<TypeFeedbackVector> feedback_vector =
113 TypeFeedbackVector::New(isolate, &spec); 172 TypeFeedbackVector::New(isolate, feedback_metadata);
114 DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot)); 173 DCHECK_EQ(PushAppliedArgumentsIndex(), feedback_vector->GetIndex(slot));
115 USE(slot); 174 USE(slot);
116 return feedback_vector; 175 return feedback_vector;
117 } 176 }
118 177
119 178
120 // static 179 // static
121 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( 180 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
122 Isolate* isolate, Handle<TypeFeedbackVector> vector) { 181 Isolate* isolate, Handle<TypeFeedbackVector> vector) {
123 Handle<TypeFeedbackVector> result; 182 Handle<TypeFeedbackVector> result;
124 result = Handle<TypeFeedbackVector>::cast( 183 result = Handle<TypeFeedbackVector>::cast(
125 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); 184 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector)));
126 return result; 185 return result;
127 } 186 }
128 187
129 188
130 bool TypeFeedbackVector::SpecDiffersFrom(
131 const FeedbackVectorSpec* other_spec) const {
132 if (other_spec->slots() != Slots()) {
133 return true;
134 }
135
136 int slots = Slots();
137 for (int i = 0; i < slots; i++) {
138 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) {
139 return true;
140 }
141 }
142 return false;
143 }
144
145
146 // This logic is copied from 189 // This logic is copied from
147 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. 190 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
148 static bool ClearLogic(Isolate* isolate) { 191 static bool ClearLogic(Isolate* isolate) {
149 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); 192 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled();
150 } 193 }
151 194
152 195
153 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, 196 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
154 bool force_clear) { 197 bool force_clear) {
155 Isolate* isolate = GetIsolate(); 198 Isolate* isolate = GetIsolate();
156 199
157 if (!force_clear && !ClearLogic(isolate)) return; 200 if (!force_clear && !ClearLogic(isolate)) return;
158 201
159 Object* uninitialized_sentinel = 202 Object* uninitialized_sentinel =
160 TypeFeedbackVector::RawUninitializedSentinel(isolate); 203 TypeFeedbackVector::RawUninitializedSentinel(isolate);
161 204
162 TypeFeedbackMetadataIterator iter(this); 205 TypeFeedbackMetadataIterator iter(metadata());
163 while (iter.HasNext()) { 206 while (iter.HasNext()) {
164 FeedbackVectorSlot slot = iter.Next(); 207 FeedbackVectorSlot slot = iter.Next();
165 FeedbackVectorSlotKind kind = iter.kind(); 208 FeedbackVectorSlotKind kind = iter.kind();
166 209
167 Object* obj = Get(slot); 210 Object* obj = Get(slot);
168 if (obj != uninitialized_sentinel) { 211 if (obj != uninitialized_sentinel) {
169 switch (kind) { 212 switch (kind) {
170 case FeedbackVectorSlotKind::CALL_IC: { 213 case FeedbackVectorSlotKind::CALL_IC: {
171 CallICNexus nexus(this, slot); 214 CallICNexus nexus(this, slot);
172 nexus.Clear(shared->code()); 215 nexus.Clear(shared->code());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 272 }
230 273
231 274
232 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { 275 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
233 Isolate* isolate = GetIsolate(); 276 Isolate* isolate = GetIsolate();
234 277
235 Code* host = shared->code(); 278 Code* host = shared->code();
236 Object* uninitialized_sentinel = 279 Object* uninitialized_sentinel =
237 TypeFeedbackVector::RawUninitializedSentinel(isolate); 280 TypeFeedbackVector::RawUninitializedSentinel(isolate);
238 281
239 TypeFeedbackMetadataIterator iter(this); 282 TypeFeedbackMetadataIterator iter(metadata());
240 while (iter.HasNext()) { 283 while (iter.HasNext()) {
241 FeedbackVectorSlot slot = iter.Next(); 284 FeedbackVectorSlot slot = iter.Next();
242 FeedbackVectorSlotKind kind = iter.kind(); 285 FeedbackVectorSlotKind kind = iter.kind();
243 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; 286 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue;
244 Object* obj = Get(slot); 287 Object* obj = Get(slot);
245 if (obj != uninitialized_sentinel) { 288 if (obj != uninitialized_sentinel) {
246 DCHECK(FLAG_vector_stores); 289 DCHECK(FLAG_vector_stores);
247 KeyedStoreICNexus nexus(this, slot); 290 KeyedStoreICNexus nexus(this, slot);
248 nexus.Clear(host); 291 nexus.Clear(host);
249 } 292 }
250 } 293 }
251 } 294 }
252 295
253 296
254 // static 297 // static
255 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) { 298 Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
256 return isolate->factory()->dummy_vector(); 299 return isolate->factory()->dummy_vector();
257 } 300 }
258 301
259 302
260 const char* TypeFeedbackVector::Kind2String(FeedbackVectorSlotKind kind) {
261 switch (kind) {
262 case FeedbackVectorSlotKind::INVALID:
263 return "INVALID";
264 case FeedbackVectorSlotKind::CALL_IC:
265 return "CALL_IC";
266 case FeedbackVectorSlotKind::LOAD_IC:
267 return "LOAD_IC";
268 case FeedbackVectorSlotKind::KEYED_LOAD_IC:
269 return "KEYED_LOAD_IC";
270 case FeedbackVectorSlotKind::STORE_IC:
271 return "STORE_IC";
272 case FeedbackVectorSlotKind::KEYED_STORE_IC:
273 return "KEYED_STORE_IC";
274 case FeedbackVectorSlotKind::GENERAL:
275 return "STUB";
276 case FeedbackVectorSlotKind::KINDS_NUMBER:
277 break;
278 }
279 UNREACHABLE();
280 return "?";
281 }
282
283
284 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { 303 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
285 Isolate* isolate = GetIsolate(); 304 Isolate* isolate = GetIsolate();
286 Handle<Object> feedback = handle(GetFeedback(), isolate); 305 Handle<Object> feedback = handle(GetFeedback(), isolate);
287 if (!feedback->IsFixedArray() || 306 if (!feedback->IsFixedArray() ||
288 FixedArray::cast(*feedback)->length() != length) { 307 FixedArray::cast(*feedback)->length() != length) {
289 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); 308 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
290 SetFeedback(*array); 309 SetFeedback(*array);
291 return array; 310 return array;
292 } 311 }
293 return Handle<FixedArray>::cast(feedback); 312 return Handle<FixedArray>::cast(feedback);
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 return mode; 824 return mode;
806 } 825 }
807 826
808 827
809 IcCheckType KeyedStoreICNexus::GetKeyType() const { 828 IcCheckType KeyedStoreICNexus::GetKeyType() const {
810 // The structure of the vector slots tells us the type. 829 // The structure of the vector slots tells us the type.
811 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; 830 return GetFeedback()->IsName() ? PROPERTY : ELEMENT;
812 } 831 }
813 } // namespace internal 832 } // namespace internal
814 } // namespace v8 833 } // namespace v8
OLDNEW
« no previous file with comments | « src/type-feedback-vector.h ('k') | src/type-feedback-vector-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698