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

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

Issue 2614373002: [FeedbackVector] Infrastructure for literal arrays in the vector. (Closed)
Patch Set: Release compile fix. Created 3 years, 11 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-inl.h" 8 #include "src/ic/ic-inl.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 19 matching lines...) Expand all
30 } 30 }
31 31
32 32
33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind(
34 FeedbackVectorSlot slot) const { 34 FeedbackVectorSlot slot) const {
35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
36 int data = Smi::cast(get(index))->value(); 36 int data = Smi::cast(get(index))->value();
37 return VectorICComputer::decode(data, slot.ToInt()); 37 return VectorICComputer::decode(data, slot.ToInt());
38 } 38 }
39 39
40 int TypeFeedbackMetadata::GetParameter(int parameter_index) const {
41 FixedArray* parameters = FixedArray::cast(get(kParametersTableIndex));
42 return Smi::cast(parameters->get(parameter_index))->value();
43 }
44
40 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, 45 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot,
41 FeedbackVectorSlotKind kind) { 46 FeedbackVectorSlotKind kind) {
42 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); 47 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
43 int data = Smi::cast(get(index))->value(); 48 int data = Smi::cast(get(index))->value();
44 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); 49 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
45 set(index, Smi::FromInt(new_data)); 50 set(index, Smi::FromInt(new_data));
46 } 51 }
47 52
48 53
49 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( 54 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 89 }
85 90
86 Handle<TypeFeedbackMetadata> metadata = 91 Handle<TypeFeedbackMetadata> metadata =
87 Handle<TypeFeedbackMetadata>::cast(array); 92 Handle<TypeFeedbackMetadata>::cast(array);
88 93
89 for (int i = 0; i < slot_count; i++) { 94 for (int i = 0; i < slot_count; i++) {
90 FeedbackVectorSlotKind kind = spec->GetKind(i); 95 FeedbackVectorSlotKind kind = spec->GetKind(i);
91 metadata->SetKind(FeedbackVectorSlot(i), kind); 96 metadata->SetKind(FeedbackVectorSlot(i), kind);
92 } 97 }
93 98
99 if (spec->parameters_count() > 0) {
100 const int parameters_count = spec->parameters_count();
101 Handle<FixedArray> params_array =
102 factory->NewFixedArray(parameters_count, TENURED);
103 for (int i = 0; i < parameters_count; i++) {
104 params_array->set(i, Smi::FromInt(spec->GetParameter(i)));
105 }
106 metadata->set(kParametersTableIndex, *params_array);
107 } else {
108 metadata->set(kParametersTableIndex, *factory->empty_fixed_array());
109 }
110
94 // It's important that the TypeFeedbackMetadata have a COW map, since it's 111 // It's important that the TypeFeedbackMetadata have a COW map, since it's
95 // pointed to by both a SharedFunctionInfo and indirectly by closures through 112 // pointed to by both a SharedFunctionInfo and indirectly by closures through
96 // the TypeFeedbackVector. The serializer uses the COW map type to decide 113 // the TypeFeedbackVector. The serializer uses the COW map type to decide
97 // this object belongs in the startup snapshot and not the partial 114 // this object belongs in the startup snapshot and not the partial
98 // snapshot(s). 115 // snapshot(s).
99 metadata->set_map(isolate->heap()->fixed_cow_array_map()); 116 metadata->set_map(isolate->heap()->fixed_cow_array_map());
100 117
101 return metadata; 118 return metadata;
102 } 119 }
103 120
104 121
105 bool TypeFeedbackMetadata::SpecDiffersFrom( 122 bool TypeFeedbackMetadata::SpecDiffersFrom(
106 const FeedbackVectorSpec* other_spec) const { 123 const FeedbackVectorSpec* other_spec) const {
107 if (other_spec->slots() != slot_count()) { 124 if (other_spec->slots() != slot_count()) {
108 return true; 125 return true;
109 } 126 }
110 127
111 int slots = slot_count(); 128 int slots = slot_count();
129 int parameter_index = 0;
112 for (int i = 0; i < slots;) { 130 for (int i = 0; i < slots;) {
113 FeedbackVectorSlot slot(i); 131 FeedbackVectorSlot slot(i);
114 FeedbackVectorSlotKind kind = GetKind(slot); 132 FeedbackVectorSlotKind kind = GetKind(slot);
115 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 133 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
116 134
117 if (kind != other_spec->GetKind(i)) { 135 if (kind != other_spec->GetKind(i)) {
118 return true; 136 return true;
119 } 137 }
138 if (SlotRequiresParameter(kind)) {
139 int parameter = GetParameter(parameter_index);
140 int other_parameter = other_spec->GetParameter(parameter_index);
141 if (parameter != other_parameter) {
142 return true;
143 }
144 parameter_index++;
145 }
120 i += entry_size; 146 i += entry_size;
121 } 147 }
122 return false; 148 return false;
123 } 149 }
124 150
125 bool TypeFeedbackMetadata::DiffersFrom( 151 bool TypeFeedbackMetadata::DiffersFrom(
126 const TypeFeedbackMetadata* other_metadata) const { 152 const TypeFeedbackMetadata* other_metadata) const {
127 if (other_metadata->slot_count() != slot_count()) { 153 if (other_metadata->slot_count() != slot_count()) {
128 return true; 154 return true;
129 } 155 }
130 156
131 int slots = slot_count(); 157 int slots = slot_count();
158 int parameter_index = 0;
132 for (int i = 0; i < slots;) { 159 for (int i = 0; i < slots;) {
133 FeedbackVectorSlot slot(i); 160 FeedbackVectorSlot slot(i);
134 FeedbackVectorSlotKind kind = GetKind(slot); 161 FeedbackVectorSlotKind kind = GetKind(slot);
135 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 162 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
136 if (GetKind(slot) != other_metadata->GetKind(slot)) { 163 if (GetKind(slot) != other_metadata->GetKind(slot)) {
137 return true; 164 return true;
138 } 165 }
166 if (SlotRequiresParameter(kind)) {
167 if (GetParameter(parameter_index) !=
168 other_metadata->GetParameter(parameter_index)) {
169 return true;
170 }
171 parameter_index++;
172 }
139 i += entry_size; 173 i += entry_size;
140 } 174 }
141 return false; 175 return false;
142 } 176 }
143 177
144 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { 178 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
145 switch (kind) { 179 switch (kind) {
146 case FeedbackVectorSlotKind::INVALID: 180 case FeedbackVectorSlotKind::INVALID:
147 return "INVALID"; 181 return "INVALID";
148 case FeedbackVectorSlotKind::CALL_IC: 182 case FeedbackVectorSlotKind::CALL_IC:
149 return "CALL_IC"; 183 return "CALL_IC";
150 case FeedbackVectorSlotKind::LOAD_IC: 184 case FeedbackVectorSlotKind::LOAD_IC:
151 return "LOAD_IC"; 185 return "LOAD_IC";
152 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: 186 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
153 return "LOAD_GLOBAL_IC"; 187 return "LOAD_GLOBAL_IC";
154 case FeedbackVectorSlotKind::KEYED_LOAD_IC: 188 case FeedbackVectorSlotKind::KEYED_LOAD_IC:
155 return "KEYED_LOAD_IC"; 189 return "KEYED_LOAD_IC";
156 case FeedbackVectorSlotKind::STORE_IC: 190 case FeedbackVectorSlotKind::STORE_IC:
157 return "STORE_IC"; 191 return "STORE_IC";
158 case FeedbackVectorSlotKind::KEYED_STORE_IC: 192 case FeedbackVectorSlotKind::KEYED_STORE_IC:
159 return "KEYED_STORE_IC"; 193 return "KEYED_STORE_IC";
160 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: 194 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
161 return "INTERPRETER_BINARYOP_IC"; 195 return "INTERPRETER_BINARYOP_IC";
162 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: 196 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC:
163 return "INTERPRETER_COMPARE_IC"; 197 return "INTERPRETER_COMPARE_IC";
164 case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC: 198 case FeedbackVectorSlotKind::STORE_DATA_PROPERTY_IN_LITERAL_IC:
165 return "STORE_DATA_PROPERTY_IN_LITERAL_IC"; 199 return "STORE_DATA_PROPERTY_IN_LITERAL_IC";
200 case FeedbackVectorSlotKind::CREATE_CLOSURE:
201 return "CREATE_CLOSURE";
166 case FeedbackVectorSlotKind::GENERAL: 202 case FeedbackVectorSlotKind::GENERAL:
167 return "STUB"; 203 return "STUB";
168 case FeedbackVectorSlotKind::KINDS_NUMBER: 204 case FeedbackVectorSlotKind::KINDS_NUMBER:
169 break; 205 break;
170 } 206 }
171 UNREACHABLE(); 207 UNREACHABLE();
172 return "?"; 208 return "?";
173 } 209 }
174 210
175 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 211 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
176 FeedbackVectorSlot slot) const { 212 FeedbackVectorSlot slot) const {
177 DCHECK(!is_empty()); 213 DCHECK(!is_empty());
178 return metadata()->GetKind(slot); 214 return metadata()->GetKind(slot);
179 } 215 }
180 216
217 int TypeFeedbackVector::GetParameter(FeedbackVectorSlot slot) const {
218 DCHECK(!is_empty());
219 DCHECK(
220 TypeFeedbackMetadata::SlotRequiresParameter(metadata()->GetKind(slot)));
221 return FixedArray::cast(Get(slot))->length();
222 }
223
181 // static 224 // static
182 Handle<TypeFeedbackVector> TypeFeedbackVector::New( 225 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
183 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { 226 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
184 Factory* factory = isolate->factory(); 227 Factory* factory = isolate->factory();
185 228
186 const int slot_count = metadata->slot_count(); 229 const int slot_count = metadata->slot_count();
187 const int length = slot_count + kReservedIndexCount; 230 const int length = slot_count + kReservedIndexCount;
188 if (length == kReservedIndexCount) { 231 if (length == kReservedIndexCount) {
189 return Handle<TypeFeedbackVector>::cast( 232 return Handle<TypeFeedbackVector>::cast(
190 factory->empty_type_feedback_vector()); 233 factory->empty_type_feedback_vector());
191 } 234 }
192 235
193 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); 236 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
194 array->set_map_no_write_barrier(isolate->heap()->type_feedback_vector_map()); 237 array->set_map_no_write_barrier(isolate->heap()->type_feedback_vector_map());
195 array->set(kMetadataIndex, *metadata); 238 array->set(kMetadataIndex, *metadata);
196 array->set(kInvocationCountIndex, Smi::kZero); 239 array->set(kInvocationCountIndex, Smi::kZero);
240 int parameter_index = 0;
241 for (int i = 0; i < slot_count;) {
242 FeedbackVectorSlot slot(i);
243 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
244 int index = TypeFeedbackVector::GetIndex(slot);
245 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
246
247 if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) {
248 // This fixed array is filled with undefined.
249 int length = metadata->GetParameter(parameter_index++);
250 if (length == 0) {
251 // This is a native function literal. We can always point to
252 // the empty literals array here.
253 array->set(index, *factory->empty_literals_array(), SKIP_WRITE_BARRIER);
254 } else {
255 // TODO(mvstanton): Create the array.
256 // Handle<FixedArray> value = factory->NewFixedArray(length);
257 // array->set(index, *value);
258 array->set(index, *factory->empty_literals_array(), SKIP_WRITE_BARRIER);
259 }
260 }
261 i += entry_size;
262 }
197 263
198 DisallowHeapAllocation no_gc; 264 DisallowHeapAllocation no_gc;
199 265
200 // Ensure we can skip the write barrier 266 // Ensure we can skip the write barrier
201 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 267 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
202 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); 268 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
203 for (int i = 0; i < slot_count;) { 269 for (int i = 0; i < slot_count;) {
204 FeedbackVectorSlot slot(i); 270 FeedbackVectorSlot slot(i);
205 FeedbackVectorSlotKind kind = metadata->GetKind(slot); 271 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
206 int index = TypeFeedbackVector::GetIndex(slot); 272 int index = TypeFeedbackVector::GetIndex(slot);
207 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 273 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
208 274
209 Object* value; 275 Object* value;
210 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { 276 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
211 value = isolate->heap()->empty_weak_cell(); 277 value = isolate->heap()->empty_weak_cell();
212 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC || 278 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
213 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) { 279 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) {
214 value = Smi::kZero; 280 value = Smi::kZero;
215 } else { 281 } else {
216 value = *uninitialized_sentinel; 282 value = *uninitialized_sentinel;
217 } 283 }
218 array->set(index, value, SKIP_WRITE_BARRIER);
219 284
220 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero 285 if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) {
221 : *uninitialized_sentinel; 286 array->set(index, value, SKIP_WRITE_BARRIER);
222 for (int j = 1; j < entry_size; j++) { 287 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero
223 array->set(index + j, value, SKIP_WRITE_BARRIER); 288 : *uninitialized_sentinel;
289 for (int j = 1; j < entry_size; j++) {
290 array->set(index + j, value, SKIP_WRITE_BARRIER);
291 }
224 } 292 }
225 i += entry_size; 293 i += entry_size;
226 } 294 }
227 return Handle<TypeFeedbackVector>::cast(array); 295 return Handle<TypeFeedbackVector>::cast(array);
228 } 296 }
229 297
230 298
231 // static 299 // static
232 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, 300 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
233 FeedbackVectorSlot slot) { 301 FeedbackVectorSlot slot) {
(...skipping 14 matching lines...) Expand all
248 // This logic is copied from 316 // This logic is copied from
249 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. 317 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
250 static bool ClearLogic(Isolate* isolate) { 318 static bool ClearLogic(Isolate* isolate) {
251 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); 319 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled();
252 } 320 }
253 321
254 322
255 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, 323 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
256 bool force_clear) { 324 bool force_clear) {
257 Isolate* isolate = GetIsolate(); 325 Isolate* isolate = GetIsolate();
326 if (!force_clear && !ClearLogic(isolate)) return;
258 327
259 if (!force_clear && !ClearLogic(isolate)) return; 328 if (this == isolate->heap()->empty_type_feedback_vector()) return;
260 329
261 Object* uninitialized_sentinel = 330 Object* uninitialized_sentinel =
262 TypeFeedbackVector::RawUninitializedSentinel(isolate); 331 TypeFeedbackVector::RawUninitializedSentinel(isolate);
263 332
264 TypeFeedbackMetadataIterator iter(metadata()); 333 TypeFeedbackMetadataIterator iter(metadata());
265 while (iter.HasNext()) { 334 while (iter.HasNext()) {
266 FeedbackVectorSlot slot = iter.Next(); 335 FeedbackVectorSlot slot = iter.Next();
267 FeedbackVectorSlotKind kind = iter.kind(); 336 FeedbackVectorSlotKind kind = iter.kind();
268 337
269 Object* obj = Get(slot); 338 Object* obj = Get(slot);
(...skipping 29 matching lines...) Expand all
299 nexus.Clear(shared->code()); 368 nexus.Clear(shared->code());
300 break; 369 break;
301 } 370 }
302 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: 371 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
303 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: { 372 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
304 DCHECK(Get(slot)->IsSmi()); 373 DCHECK(Get(slot)->IsSmi());
305 // don't clear these smi slots. 374 // don't clear these smi slots.
306 // Set(slot, Smi::kZero); 375 // Set(slot, Smi::kZero);
307 break; 376 break;
308 } 377 }
378 case FeedbackVectorSlotKind::CREATE_CLOSURE: {
379 // Fill the array with undefined.
380 FixedArray* array = FixedArray::cast(Get(slot));
381 for (int i = 1; i < array->length(); i++) {
382 array->set_undefined(i);
383 }
384 break;
385 }
309 case FeedbackVectorSlotKind::GENERAL: { 386 case FeedbackVectorSlotKind::GENERAL: {
310 if (obj->IsHeapObject()) { 387 if (obj->IsHeapObject()) {
311 InstanceType instance_type = 388 InstanceType instance_type =
312 HeapObject::cast(obj)->map()->instance_type(); 389 HeapObject::cast(obj)->map()->instance_type();
313 // AllocationSites are exempt from clearing. They don't store Maps 390 // AllocationSites are exempt from clearing. They don't store Maps
314 // or Code pointers which can cause memory leaks if not cleared 391 // or Code pointers which can cause memory leaks if not cleared
315 // regularly. 392 // regularly.
316 if (instance_type != ALLOCATION_SITE_TYPE) { 393 if (instance_type != ALLOCATION_SITE_TYPE) {
317 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); 394 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
318 } 395 }
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic( 1089 void StoreDataPropertyInLiteralICNexus::ConfigureMonomorphic(
1013 Handle<Name> name, Handle<Map> receiver_map) { 1090 Handle<Name> name, Handle<Map> receiver_map) {
1014 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); 1091 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
1015 1092
1016 SetFeedback(*cell); 1093 SetFeedback(*cell);
1017 SetFeedbackExtra(*name); 1094 SetFeedbackExtra(*name);
1018 } 1095 }
1019 1096
1020 } // namespace internal 1097 } // namespace internal
1021 } // namespace v8 1098 } // 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