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

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

Issue 2504153002: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: REBASE. Created 4 years 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
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";
198 case FeedbackVectorSlotKind::CREATE_CLOSURE:
199 return "CREATE_CLOSURE";
164 case FeedbackVectorSlotKind::GENERAL: 200 case FeedbackVectorSlotKind::GENERAL:
165 return "STUB"; 201 return "STUB";
166 case FeedbackVectorSlotKind::KINDS_NUMBER: 202 case FeedbackVectorSlotKind::KINDS_NUMBER:
167 break; 203 break;
168 } 204 }
169 UNREACHABLE(); 205 UNREACHABLE();
170 return "?"; 206 return "?";
171 } 207 }
172 208
173 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 209 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
174 FeedbackVectorSlot slot) const { 210 FeedbackVectorSlot slot) const {
175 DCHECK(!is_empty()); 211 DCHECK(!is_empty());
176 return metadata()->GetKind(slot); 212 return metadata()->GetKind(slot);
177 } 213 }
178 214
215 int TypeFeedbackVector::GetParameter(FeedbackVectorSlot slot) const {
216 DCHECK(!is_empty());
217 DCHECK(
218 TypeFeedbackMetadata::SlotRequiresParameter(metadata()->GetKind(slot)));
219 return FixedArray::cast(Get(slot))->length();
220 }
221
179 // static 222 // static
180 Handle<TypeFeedbackVector> TypeFeedbackVector::New( 223 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
181 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { 224 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
182 Factory* factory = isolate->factory(); 225 Factory* factory = isolate->factory();
183 226
184 const int slot_count = metadata->slot_count(); 227 const int slot_count = metadata->slot_count();
185 const int length = slot_count + kReservedIndexCount; 228 const int length = slot_count + kReservedIndexCount;
186 if (length == kReservedIndexCount) { 229 if (length == kReservedIndexCount) {
187 return Handle<TypeFeedbackVector>::cast( 230 return Handle<TypeFeedbackVector>::cast(
188 factory->empty_type_feedback_vector()); 231 factory->empty_type_feedback_vector());
189 } 232 }
190 233
191 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); 234 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
192 array->set(kMetadataIndex, *metadata); 235 array->set(kMetadataIndex, *metadata);
193 array->set(kInvocationCountIndex, Smi::kZero); 236 array->set(kInvocationCountIndex, Smi::kZero);
237 int parameter_index = 0;
238 for (int i = 0; i < slot_count;) {
Benedikt Meurer 2016/12/11 17:58:09 Hm, this looks expensive. Did you measure the perf
mvstanton 2016/12/21 13:09:13 The performance does seem to be okay.
239 FeedbackVectorSlot slot(i);
240 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
241 int index = TypeFeedbackVector::GetIndex(slot);
242 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
243
244 if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) {
245 // This fixed array is filled with undefined.
246 int length = metadata->GetParameter(parameter_index++);
247 if (length == 0) {
248 // This is a native function literal. We can always point to
249 // the empty literals array here.
250 array->set(index, *factory->empty_literals_array(), SKIP_WRITE_BARRIER);
251 } else {
252 Handle<FixedArray> value = factory->NewFixedArray(length);
253 array->set(index, *value);
254 }
255 }
256 i += entry_size;
257 }
194 258
195 DisallowHeapAllocation no_gc; 259 DisallowHeapAllocation no_gc;
196 260
197 // Ensure we can skip the write barrier 261 // Ensure we can skip the write barrier
198 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 262 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
199 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); 263 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
200 for (int i = 0; i < slot_count;) { 264 for (int i = 0; i < slot_count;) {
201 FeedbackVectorSlot slot(i); 265 FeedbackVectorSlot slot(i);
202 FeedbackVectorSlotKind kind = metadata->GetKind(slot); 266 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
203 int index = TypeFeedbackVector::GetIndex(slot); 267 int index = TypeFeedbackVector::GetIndex(slot);
204 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 268 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
205 269
206 Object* value; 270 Object* value;
207 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { 271 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
208 value = isolate->heap()->empty_weak_cell(); 272 value = isolate->heap()->empty_weak_cell();
209 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC || 273 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
210 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) { 274 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) {
211 value = Smi::kZero; 275 value = Smi::kZero;
212 } else { 276 } else {
213 value = *uninitialized_sentinel; 277 value = *uninitialized_sentinel;
214 } 278 }
215 array->set(index, value, SKIP_WRITE_BARRIER);
216 279
217 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero 280 if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) {
218 : *uninitialized_sentinel; 281 array->set(index, value, SKIP_WRITE_BARRIER);
219 for (int j = 1; j < entry_size; j++) { 282 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero
220 array->set(index + j, value, SKIP_WRITE_BARRIER); 283 : *uninitialized_sentinel;
284 for (int j = 1; j < entry_size; j++) {
285 array->set(index + j, value, SKIP_WRITE_BARRIER);
286 }
221 } 287 }
222 i += entry_size; 288 i += entry_size;
223 } 289 }
224 return Handle<TypeFeedbackVector>::cast(array); 290 return Handle<TypeFeedbackVector>::cast(array);
225 } 291 }
226 292
227 293
228 // static 294 // static
229 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, 295 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
230 FeedbackVectorSlot slot) { 296 FeedbackVectorSlot slot) {
(...skipping 14 matching lines...) Expand all
245 // This logic is copied from 311 // This logic is copied from
246 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. 312 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
247 static bool ClearLogic(Isolate* isolate) { 313 static bool ClearLogic(Isolate* isolate) {
248 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); 314 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled();
249 } 315 }
250 316
251 317
252 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, 318 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
253 bool force_clear) { 319 bool force_clear) {
254 Isolate* isolate = GetIsolate(); 320 Isolate* isolate = GetIsolate();
321 if (!force_clear && !ClearLogic(isolate)) return;
255 322
256 if (!force_clear && !ClearLogic(isolate)) return; 323 if (this == isolate->heap()->empty_type_feedback_vector()) return;
257 324
258 Object* uninitialized_sentinel = 325 Object* uninitialized_sentinel =
259 TypeFeedbackVector::RawUninitializedSentinel(isolate); 326 TypeFeedbackVector::RawUninitializedSentinel(isolate);
260 327
261 TypeFeedbackMetadataIterator iter(metadata()); 328 TypeFeedbackMetadataIterator iter(metadata());
262 while (iter.HasNext()) { 329 while (iter.HasNext()) {
263 FeedbackVectorSlot slot = iter.Next(); 330 FeedbackVectorSlot slot = iter.Next();
264 FeedbackVectorSlotKind kind = iter.kind(); 331 FeedbackVectorSlotKind kind = iter.kind();
265 332
266 Object* obj = Get(slot); 333 Object* obj = Get(slot);
(...skipping 29 matching lines...) Expand all
296 nexus.Clear(shared->code()); 363 nexus.Clear(shared->code());
297 break; 364 break;
298 } 365 }
299 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: 366 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
300 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: { 367 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
301 DCHECK(Get(slot)->IsSmi()); 368 DCHECK(Get(slot)->IsSmi());
302 // don't clear these smi slots. 369 // don't clear these smi slots.
303 // Set(slot, Smi::kZero); 370 // Set(slot, Smi::kZero);
304 break; 371 break;
305 } 372 }
373 case FeedbackVectorSlotKind::CREATE_CLOSURE: {
374 // Fill the array with undefined.
375 FixedArray* array = FixedArray::cast(Get(slot));
376 for (int i = 0; i < array->length(); i++) {
377 array->set_undefined(i);
378 }
379 break;
380 }
306 case FeedbackVectorSlotKind::GENERAL: { 381 case FeedbackVectorSlotKind::GENERAL: {
307 if (obj->IsHeapObject()) { 382 if (obj->IsHeapObject()) {
308 InstanceType instance_type = 383 InstanceType instance_type =
309 HeapObject::cast(obj)->map()->instance_type(); 384 HeapObject::cast(obj)->map()->instance_type();
310 // AllocationSites are exempt from clearing. They don't store Maps 385 // AllocationSites are exempt from clearing. They don't store Maps
311 // or Code pointers which can cause memory leaks if not cleared 386 // or Code pointers which can cause memory leaks if not cleared
312 // regularly. 387 // regularly.
313 if (instance_type != ALLOCATION_SITE_TYPE) { 388 if (instance_type != ALLOCATION_SITE_TYPE) {
314 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); 389 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
315 } 390 }
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 return BinaryOperationHintFromFeedback(feedback); 1057 return BinaryOperationHintFromFeedback(feedback);
983 } 1058 }
984 1059
985 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { 1060 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const {
986 int feedback = Smi::cast(GetFeedback())->value(); 1061 int feedback = Smi::cast(GetFeedback())->value();
987 return CompareOperationHintFromFeedback(feedback); 1062 return CompareOperationHintFromFeedback(feedback);
988 } 1063 }
989 1064
990 } // namespace internal 1065 } // namespace internal
991 } // namespace v8 1066 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698