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

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

Issue 2597163002: Revert of [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: 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
« 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
45 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, 40 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot,
46 FeedbackVectorSlotKind kind) { 41 FeedbackVectorSlotKind kind) {
47 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); 42 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
48 int data = Smi::cast(get(index))->value(); 43 int data = Smi::cast(get(index))->value();
49 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); 44 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
50 set(index, Smi::FromInt(new_data)); 45 set(index, Smi::FromInt(new_data));
51 } 46 }
52 47
53 48
54 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( 49 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 } 84 }
90 85
91 Handle<TypeFeedbackMetadata> metadata = 86 Handle<TypeFeedbackMetadata> metadata =
92 Handle<TypeFeedbackMetadata>::cast(array); 87 Handle<TypeFeedbackMetadata>::cast(array);
93 88
94 for (int i = 0; i < slot_count; i++) { 89 for (int i = 0; i < slot_count; i++) {
95 FeedbackVectorSlotKind kind = spec->GetKind(i); 90 FeedbackVectorSlotKind kind = spec->GetKind(i);
96 metadata->SetKind(FeedbackVectorSlot(i), kind); 91 metadata->SetKind(FeedbackVectorSlot(i), kind);
97 } 92 }
98 93
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
111 // It's important that the TypeFeedbackMetadata have a COW map, since it's 94 // It's important that the TypeFeedbackMetadata have a COW map, since it's
112 // pointed to by both a SharedFunctionInfo and indirectly by closures through 95 // pointed to by both a SharedFunctionInfo and indirectly by closures through
113 // the TypeFeedbackVector. The serializer uses the COW map type to decide 96 // the TypeFeedbackVector. The serializer uses the COW map type to decide
114 // this object belongs in the startup snapshot and not the partial 97 // this object belongs in the startup snapshot and not the partial
115 // snapshot(s). 98 // snapshot(s).
116 metadata->set_map(isolate->heap()->fixed_cow_array_map()); 99 metadata->set_map(isolate->heap()->fixed_cow_array_map());
117 100
118 return metadata; 101 return metadata;
119 } 102 }
120 103
121 104
122 bool TypeFeedbackMetadata::SpecDiffersFrom( 105 bool TypeFeedbackMetadata::SpecDiffersFrom(
123 const FeedbackVectorSpec* other_spec) const { 106 const FeedbackVectorSpec* other_spec) const {
124 if (other_spec->slots() != slot_count()) { 107 if (other_spec->slots() != slot_count()) {
125 return true; 108 return true;
126 } 109 }
127 110
128 int slots = slot_count(); 111 int slots = slot_count();
129 int parameter_index = 0;
130 for (int i = 0; i < slots;) { 112 for (int i = 0; i < slots;) {
131 FeedbackVectorSlot slot(i); 113 FeedbackVectorSlot slot(i);
132 FeedbackVectorSlotKind kind = GetKind(slot); 114 FeedbackVectorSlotKind kind = GetKind(slot);
133 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 115 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
134 116
135 if (kind != other_spec->GetKind(i)) { 117 if (kind != other_spec->GetKind(i)) {
136 return true; 118 return true;
137 } 119 }
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 }
146 i += entry_size; 120 i += entry_size;
147 } 121 }
148 return false; 122 return false;
149 } 123 }
150 124
151 bool TypeFeedbackMetadata::DiffersFrom( 125 bool TypeFeedbackMetadata::DiffersFrom(
152 const TypeFeedbackMetadata* other_metadata) const { 126 const TypeFeedbackMetadata* other_metadata) const {
153 if (other_metadata->slot_count() != slot_count()) { 127 if (other_metadata->slot_count() != slot_count()) {
154 return true; 128 return true;
155 } 129 }
156 130
157 int slots = slot_count(); 131 int slots = slot_count();
158 int parameter_index = 0;
159 for (int i = 0; i < slots;) { 132 for (int i = 0; i < slots;) {
160 FeedbackVectorSlot slot(i); 133 FeedbackVectorSlot slot(i);
161 FeedbackVectorSlotKind kind = GetKind(slot); 134 FeedbackVectorSlotKind kind = GetKind(slot);
162 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 135 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
163 if (GetKind(slot) != other_metadata->GetKind(slot)) { 136 if (GetKind(slot) != other_metadata->GetKind(slot)) {
164 return true; 137 return true;
165 } 138 }
166 if (SlotRequiresParameter(kind)) {
167 if (GetParameter(parameter_index) !=
168 other_metadata->GetParameter(parameter_index)) {
169 return true;
170 }
171 parameter_index++;
172 }
173 i += entry_size; 139 i += entry_size;
174 } 140 }
175 return false; 141 return false;
176 } 142 }
177 143
178 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { 144 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
179 switch (kind) { 145 switch (kind) {
180 case FeedbackVectorSlotKind::INVALID: 146 case FeedbackVectorSlotKind::INVALID:
181 return "INVALID"; 147 return "INVALID";
182 case FeedbackVectorSlotKind::CALL_IC: 148 case FeedbackVectorSlotKind::CALL_IC:
183 return "CALL_IC"; 149 return "CALL_IC";
184 case FeedbackVectorSlotKind::LOAD_IC: 150 case FeedbackVectorSlotKind::LOAD_IC:
185 return "LOAD_IC"; 151 return "LOAD_IC";
186 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: 152 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
187 return "LOAD_GLOBAL_IC"; 153 return "LOAD_GLOBAL_IC";
188 case FeedbackVectorSlotKind::KEYED_LOAD_IC: 154 case FeedbackVectorSlotKind::KEYED_LOAD_IC:
189 return "KEYED_LOAD_IC"; 155 return "KEYED_LOAD_IC";
190 case FeedbackVectorSlotKind::STORE_IC: 156 case FeedbackVectorSlotKind::STORE_IC:
191 return "STORE_IC"; 157 return "STORE_IC";
192 case FeedbackVectorSlotKind::KEYED_STORE_IC: 158 case FeedbackVectorSlotKind::KEYED_STORE_IC:
193 return "KEYED_STORE_IC"; 159 return "KEYED_STORE_IC";
194 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: 160 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
195 return "INTERPRETER_BINARYOP_IC"; 161 return "INTERPRETER_BINARYOP_IC";
196 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: 162 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC:
197 return "INTERPRETER_COMPARE_IC"; 163 return "INTERPRETER_COMPARE_IC";
198 case FeedbackVectorSlotKind::CREATE_CLOSURE:
199 return "CREATE_CLOSURE";
200 case FeedbackVectorSlotKind::GENERAL: 164 case FeedbackVectorSlotKind::GENERAL:
201 return "STUB"; 165 return "STUB";
202 case FeedbackVectorSlotKind::KINDS_NUMBER: 166 case FeedbackVectorSlotKind::KINDS_NUMBER:
203 break; 167 break;
204 } 168 }
205 UNREACHABLE(); 169 UNREACHABLE();
206 return "?"; 170 return "?";
207 } 171 }
208 172
209 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( 173 FeedbackVectorSlotKind TypeFeedbackVector::GetKind(
210 FeedbackVectorSlot slot) const { 174 FeedbackVectorSlot slot) const {
211 DCHECK(!is_empty()); 175 DCHECK(!is_empty());
212 return metadata()->GetKind(slot); 176 return metadata()->GetKind(slot);
213 } 177 }
214 178
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
222 // static 179 // static
223 Handle<TypeFeedbackVector> TypeFeedbackVector::New( 180 Handle<TypeFeedbackVector> TypeFeedbackVector::New(
224 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { 181 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
225 Factory* factory = isolate->factory(); 182 Factory* factory = isolate->factory();
226 183
227 const int slot_count = metadata->slot_count(); 184 const int slot_count = metadata->slot_count();
228 const int length = slot_count + kReservedIndexCount; 185 const int length = slot_count + kReservedIndexCount;
229 if (length == kReservedIndexCount) { 186 if (length == kReservedIndexCount) {
230 return Handle<TypeFeedbackVector>::cast( 187 return Handle<TypeFeedbackVector>::cast(
231 factory->empty_type_feedback_vector()); 188 factory->empty_type_feedback_vector());
232 } 189 }
233 190
234 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); 191 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
235 array->set(kMetadataIndex, *metadata); 192 array->set(kMetadataIndex, *metadata);
236 array->set(kInvocationCountIndex, Smi::kZero); 193 array->set(kInvocationCountIndex, Smi::kZero);
237 int parameter_index = 0;
238 for (int i = 0; i < slot_count;) {
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 }
258 194
259 DisallowHeapAllocation no_gc; 195 DisallowHeapAllocation no_gc;
260 196
261 // Ensure we can skip the write barrier 197 // Ensure we can skip the write barrier
262 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); 198 Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
263 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel); 199 DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
264 for (int i = 0; i < slot_count;) { 200 for (int i = 0; i < slot_count;) {
265 FeedbackVectorSlot slot(i); 201 FeedbackVectorSlot slot(i);
266 FeedbackVectorSlotKind kind = metadata->GetKind(slot); 202 FeedbackVectorSlotKind kind = metadata->GetKind(slot);
267 int index = TypeFeedbackVector::GetIndex(slot); 203 int index = TypeFeedbackVector::GetIndex(slot);
268 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); 204 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
269 205
270 Object* value; 206 Object* value;
271 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) { 207 if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
272 value = isolate->heap()->empty_weak_cell(); 208 value = isolate->heap()->empty_weak_cell();
273 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC || 209 } else if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
274 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) { 210 kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) {
275 value = Smi::kZero; 211 value = Smi::kZero;
276 } else { 212 } else {
277 value = *uninitialized_sentinel; 213 value = *uninitialized_sentinel;
278 } 214 }
215 array->set(index, value, SKIP_WRITE_BARRIER);
279 216
280 if (kind != FeedbackVectorSlotKind::CREATE_CLOSURE) { 217 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero
281 array->set(index, value, SKIP_WRITE_BARRIER); 218 : *uninitialized_sentinel;
282 value = kind == FeedbackVectorSlotKind::CALL_IC ? Smi::kZero 219 for (int j = 1; j < entry_size; j++) {
283 : *uninitialized_sentinel; 220 array->set(index + j, value, SKIP_WRITE_BARRIER);
284 for (int j = 1; j < entry_size; j++) {
285 array->set(index + j, value, SKIP_WRITE_BARRIER);
286 }
287 } 221 }
288 i += entry_size; 222 i += entry_size;
289 } 223 }
290 return Handle<TypeFeedbackVector>::cast(array); 224 return Handle<TypeFeedbackVector>::cast(array);
291 } 225 }
292 226
293 227
294 // static 228 // static
295 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec, 229 int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
296 FeedbackVectorSlot slot) { 230 FeedbackVectorSlot slot) {
(...skipping 14 matching lines...) Expand all
311 // This logic is copied from 245 // This logic is copied from
312 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget. 246 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
313 static bool ClearLogic(Isolate* isolate) { 247 static bool ClearLogic(Isolate* isolate) {
314 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled(); 248 return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled();
315 } 249 }
316 250
317 251
318 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared, 252 void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
319 bool force_clear) { 253 bool force_clear) {
320 Isolate* isolate = GetIsolate(); 254 Isolate* isolate = GetIsolate();
255
321 if (!force_clear && !ClearLogic(isolate)) return; 256 if (!force_clear && !ClearLogic(isolate)) return;
322 257
323 if (this == isolate->heap()->empty_type_feedback_vector()) return;
324
325 Object* uninitialized_sentinel = 258 Object* uninitialized_sentinel =
326 TypeFeedbackVector::RawUninitializedSentinel(isolate); 259 TypeFeedbackVector::RawUninitializedSentinel(isolate);
327 260
328 TypeFeedbackMetadataIterator iter(metadata()); 261 TypeFeedbackMetadataIterator iter(metadata());
329 while (iter.HasNext()) { 262 while (iter.HasNext()) {
330 FeedbackVectorSlot slot = iter.Next(); 263 FeedbackVectorSlot slot = iter.Next();
331 FeedbackVectorSlotKind kind = iter.kind(); 264 FeedbackVectorSlotKind kind = iter.kind();
332 265
333 Object* obj = Get(slot); 266 Object* obj = Get(slot);
334 if (obj != uninitialized_sentinel) { 267 if (obj != uninitialized_sentinel) {
(...skipping 28 matching lines...) Expand all
363 nexus.Clear(shared->code()); 296 nexus.Clear(shared->code());
364 break; 297 break;
365 } 298 }
366 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC: 299 case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
367 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: { 300 case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
368 DCHECK(Get(slot)->IsSmi()); 301 DCHECK(Get(slot)->IsSmi());
369 // don't clear these smi slots. 302 // don't clear these smi slots.
370 // Set(slot, Smi::kZero); 303 // Set(slot, Smi::kZero);
371 break; 304 break;
372 } 305 }
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 }
381 case FeedbackVectorSlotKind::GENERAL: { 306 case FeedbackVectorSlotKind::GENERAL: {
382 if (obj->IsHeapObject()) { 307 if (obj->IsHeapObject()) {
383 InstanceType instance_type = 308 InstanceType instance_type =
384 HeapObject::cast(obj)->map()->instance_type(); 309 HeapObject::cast(obj)->map()->instance_type();
385 // AllocationSites are exempt from clearing. They don't store Maps 310 // AllocationSites are exempt from clearing. They don't store Maps
386 // or Code pointers which can cause memory leaks if not cleared 311 // or Code pointers which can cause memory leaks if not cleared
387 // regularly. 312 // regularly.
388 if (instance_type != ALLOCATION_SITE_TYPE) { 313 if (instance_type != ALLOCATION_SITE_TYPE) {
389 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); 314 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
390 } 315 }
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 return BinaryOperationHintFromFeedback(feedback); 982 return BinaryOperationHintFromFeedback(feedback);
1058 } 983 }
1059 984
1060 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { 985 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const {
1061 int feedback = Smi::cast(GetFeedback())->value(); 986 int feedback = Smi::cast(GetFeedback())->value();
1062 return CompareOperationHintFromFeedback(feedback); 987 return CompareOperationHintFromFeedback(feedback);
1063 } 988 }
1064 989
1065 } // namespace internal 990 } // namespace internal
1066 } // namespace v8 991 } // 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