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

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

Issue 754303003: Flesh out vector ic state query and set mechanisms. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Patch one. Created 6 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/ic/ic.h" 7 #include "src/ic/ic.h"
8 #include "src/ic/ic-state.h" 8 #include "src/ic/ic-state.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/type-feedback-vector-inl.h" 10 #include "src/type-feedback-vector-inl.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // static 114 // static
115 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy( 115 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
116 Isolate* isolate, Handle<TypeFeedbackVector> vector) { 116 Isolate* isolate, Handle<TypeFeedbackVector> vector) {
117 Handle<TypeFeedbackVector> result; 117 Handle<TypeFeedbackVector> result;
118 result = Handle<TypeFeedbackVector>::cast( 118 result = Handle<TypeFeedbackVector>::cast(
119 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); 119 isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector)));
120 return result; 120 return result;
121 } 121 }
122 122
123 123
124 // This logic is copied from
125 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
126 // TODO(mvstanton): with weak handling of all vector ics, this logic should
127 // actually be completely eliminated and we no longer need to clear the
128 // vector ICs.
129 static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind,
130 InlineCacheState state) {
131 if (FLAG_cleanup_code_caches_at_gc &&
132 (kind == Code::CALL_IC || state == MEGAMORPHIC || state == GENERIC ||
133 state == POLYMORPHIC || heap->flush_monomorphic_ics() ||
134 // TODO(mvstanton): is this ic_age granular enough? it comes from
135 // the SharedFunctionInfo which may change on a different schedule
136 // than ic targets.
137 // ic_age != heap->global_ic_age() ||
138 // is_invalidated_weak_stub ||
139 heap->isolate()->serializer_enabled())) {
140 return true;
141 }
142 return false;
143 }
144
145
124 void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) { 146 void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
125 int slots = Slots(); 147 int slots = Slots();
126 Isolate* isolate = GetIsolate(); 148 Isolate* isolate = GetIsolate();
127 Object* uninitialized_sentinel = 149 Object* uninitialized_sentinel =
128 TypeFeedbackVector::RawUninitializedSentinel(isolate->heap()); 150 TypeFeedbackVector::RawUninitializedSentinel(isolate->heap());
129 151
130 for (int i = 0; i < slots; i++) { 152 for (int i = 0; i < slots; i++) {
131 FeedbackVectorSlot slot(i); 153 FeedbackVectorSlot slot(i);
132 Object* obj = Get(slot); 154 Object* obj = Get(slot);
133 if (obj->IsHeapObject()) { 155 if (obj->IsHeapObject()) {
134 InstanceType instance_type = 156 InstanceType instance_type =
135 HeapObject::cast(obj)->map()->instance_type(); 157 HeapObject::cast(obj)->map()->instance_type();
136 // AllocationSites are exempt from clearing. They don't store Maps 158 // AllocationSites are exempt from clearing. They don't store Maps
137 // or Code pointers which can cause memory leaks if not cleared 159 // or Code pointers which can cause memory leaks if not cleared
138 // regularly. 160 // regularly.
139 if (instance_type != ALLOCATION_SITE_TYPE) { 161 if (instance_type != ALLOCATION_SITE_TYPE) {
140 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER); 162 Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
141 } 163 }
142 } 164 }
143 } 165 }
144 166
145 slots = ICSlots(); 167 slots = ICSlots();
146 if (slots == 0) return; 168 if (slots == 0) return;
147 169
148 // Now clear vector-based ICs. They are all CallICs. 170 // Now clear vector-based ICs. They are all CallICs.
Jakob Kummerow 2014/11/26 15:14:15 nit: s/They are all CallICs.//
mvstanton 2014/11/27 13:09:26 Done.
149 // Try and pass the containing code (the "host"). 171 // Try and pass the containing code (the "host").
172 Heap* heap = isolate->heap();
150 Code* host = shared->code(); 173 Code* host = shared->code();
174 // I'm not sure yet if this ic age is the correct one.
175 int ic_age = shared->ic_age();
151 for (int i = 0; i < slots; i++) { 176 for (int i = 0; i < slots; i++) {
152 FeedbackVectorICSlot slot(i); 177 FeedbackVectorICSlot slot(i);
153 Object* obj = Get(slot); 178 Object* obj = Get(slot);
154 if (obj != uninitialized_sentinel) { 179 if (obj != uninitialized_sentinel) {
155 // TODO(mvstanton): To make this code work with --vector-ics, 180 // Discover the correct Code::Kind.
Jakob Kummerow 2014/11/26 15:14:15 nit: this comment doesn't add value
mvstanton 2014/11/27 13:09:26 Done.
156 // additional Nexus types must be created. 181 Code::Kind kind = GetKind(slot);
157 DCHECK(!FLAG_vector_ics); 182 if (kind == Code::CALL_IC) {
158 DCHECK(GetKind(slot) == Code::CALL_IC); 183 CallICNexus nexus(this, slot);
159 CallICNexus nexus(this, slot); 184 // bool is_invalidated = nexus.IsInvalidatedWeakIC();
Jakob Kummerow 2014/11/26 15:14:15 leftover?
mvstanton 2014/11/27 13:09:26 Yes, I think so, removed.
160 ICUtility::Clear(isolate, Code::CALL_IC, host, &nexus); 185 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
186 nexus.Clear(host);
187 }
188 } else if (kind == Code::LOAD_IC) {
189 LoadICNexus nexus(this, slot);
190 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
191 nexus.Clear(host);
192 }
193 } else if (kind == Code::KEYED_LOAD_IC) {
194 KeyedLoadICNexus nexus(this, slot);
195 if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
196 nexus.Clear(host);
197 }
198 }
161 } 199 }
162 } 200 }
163 } 201 }
164 202
165 203
166 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) { 204 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
167 Isolate* isolate = GetIsolate(); 205 Isolate* isolate = GetIsolate();
168 Handle<Object> feedback = handle(GetFeedback(), isolate); 206 Handle<Object> feedback = handle(GetFeedback(), isolate);
169 if (!feedback->IsFixedArray() || 207 if (!feedback->IsFixedArray() ||
170 FixedArray::cast(*feedback)->length() != length) { 208 FixedArray::cast(*feedback)->length() != length) {
(...skipping 12 matching lines...) Expand all
183 int receiver_count = types->length(); 221 int receiver_count = types->length();
184 for (int current = 0; current < receiver_count; ++current) { 222 for (int current = 0; current < receiver_count; ++current) {
185 Handle<HeapType> type = types->at(current); 223 Handle<HeapType> type = types->at(current);
186 Handle<Map> map = IC::TypeToMap(*type, isolate); 224 Handle<Map> map = IC::TypeToMap(*type, isolate);
187 array->set(start_index + (current * 2), *map); 225 array->set(start_index + (current * 2), *map);
188 array->set(start_index + (current * 2 + 1), *handlers->at(current)); 226 array->set(start_index + (current * 2 + 1), *handlers->at(current));
189 } 227 }
190 } 228 }
191 229
192 230
231 InlineCacheState LoadICNexus::StateFromFeedback() const {
232 Isolate* isolate = GetIsolate();
233 InlineCacheState state = UNINITIALIZED;
234 Object* feedback = GetFeedback();
235 if (feedback == *vector()->UninitializedSentinel(isolate)) {
236 state = UNINITIALIZED;
Jakob Kummerow 2014/11/26 15:14:15 consider to directly "return UNINITIALIZED;" (and
mvstanton 2014/11/27 13:09:26 Done.
237 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
238 state = MEGAMORPHIC;
239 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
240 state = PREMONOMORPHIC;
241 } else if (feedback->IsFixedArray()) {
242 FixedArray* array = FixedArray::cast(feedback);
243 int length = array->length();
244 DCHECK(length >= 2);
245 if (length == 2) {
246 state = MONOMORPHIC;
247 } else if (length > 2) {
Jakob Kummerow 2014/11/26 15:14:15 s/if (length > 2)//, it's guaranteed anyway.
mvstanton 2014/11/27 13:09:26 Done.
248 state = POLYMORPHIC;
249 }
250 }
251
252 return state;
253 }
254
255
256 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
257 Isolate* isolate = GetIsolate();
258 InlineCacheState state = UNINITIALIZED;
259 Object* feedback = GetFeedback();
260 if (feedback == *vector()->UninitializedSentinel(isolate)) {
261 state = UNINITIALIZED;
262 } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
263 state = PREMONOMORPHIC;
264 } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
265 state = MEGAMORPHIC;
266 } else if (feedback == *vector()->GenericSentinel(isolate)) {
267 state = GENERIC;
268 } else if (feedback->IsFixedArray()) {
269 FixedArray* array = FixedArray::cast(feedback);
270 int length = array->length();
271 DCHECK(length >= 3);
272
273 if (length == 3) {
274 state = MONOMORPHIC;
275 } else if (length > 3) {
Jakob Kummerow 2014/11/26 15:14:15 s/if (length > 3)//, it's guaranteed anyway.
mvstanton 2014/11/27 13:09:26 Done.
276 state = POLYMORPHIC;
277 }
278 }
279
280 return state;
281 }
282
283
193 InlineCacheState CallICNexus::StateFromFeedback() const { 284 InlineCacheState CallICNexus::StateFromFeedback() const {
194 Isolate* isolate = GetIsolate(); 285 Isolate* isolate = GetIsolate();
195 InlineCacheState state = UNINITIALIZED; 286 InlineCacheState state = UNINITIALIZED;
196 Object* feedback = GetFeedback(); 287 Object* feedback = GetFeedback();
197 288
198 if (feedback == *vector()->MegamorphicSentinel(isolate)) { 289 if (feedback == *vector()->MegamorphicSentinel(isolate)) {
199 state = GENERIC; 290 state = GENERIC;
200 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) { 291 } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
201 state = MONOMORPHIC; 292 state = MONOMORPHIC;
202 } else { 293 } else {
203 CHECK(feedback == *vector()->UninitializedSentinel(isolate)); 294 CHECK(feedback == *vector()->UninitializedSentinel(isolate));
204 } 295 }
205 296
206 return state; 297 return state;
207 } 298 }
208 299
209 300
301 void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
302
303
210 void CallICNexus::ConfigureGeneric() { 304 void CallICNexus::ConfigureGeneric() {
211 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER); 305 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
212 } 306 }
213 307
214 308
215 void CallICNexus::ConfigureMonomorphicArray() { 309 void CallICNexus::ConfigureMonomorphicArray() {
216 Object* feedback = GetFeedback(); 310 Object* feedback = GetFeedback();
217 if (!feedback->IsAllocationSite()) { 311 if (!feedback->IsAllocationSite()) {
218 Handle<AllocationSite> new_site = 312 Handle<AllocationSite> new_site =
219 GetIsolate()->factory()->NewAllocationSite(); 313 GetIsolate()->factory()->NewAllocationSite();
220 SetFeedback(*new_site); 314 SetFeedback(*new_site);
221 } 315 }
222 } 316 }
223 317
224 318
225 void CallICNexus::ConfigureUninitialized() { 319 void CallICNexus::ConfigureUninitialized() {
226 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()), 320 SetFeedback(*vector()->UninitializedSentinel(GetIsolate()),
227 SKIP_WRITE_BARRIER); 321 SKIP_WRITE_BARRIER);
228 } 322 }
229 323
230 324
231 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) { 325 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
232 SetFeedback(*function); 326 SetFeedback(*function);
233 } 327 }
234 328
235 329
330 void KeyedLoadICNexus::ConfigureGeneric() {
331 SetFeedback(*vector()->GenericSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
Jakob Kummerow 2014/11/26 15:14:15 Looks like return raw pointers in the various vect
mvstanton 2014/11/27 13:09:26 Yes, I'll come back for that later. I think I want
332 }
333
334
335 void KeyedLoadICNexus::ConfigureMegamorphic() {
336 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
337 }
338
339
340 void LoadICNexus::ConfigureMegamorphic() {
341 SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
342 }
343
344
345 void LoadICNexus::ConfigurePremonomorphic() {
346 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
347 SKIP_WRITE_BARRIER);
348 }
349
350
351 void KeyedLoadICNexus::ConfigurePremonomorphic() {
352 SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
353 SKIP_WRITE_BARRIER);
354 }
355
356
357 void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
358 Handle<Code> handler) {
359 Handle<FixedArray> array = EnsureArrayOfSize(2);
360 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
361 array->set(0, *receiver_map);
362 array->set(1, *handler);
363 }
364
365
366 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
367 Handle<HeapType> type,
368 Handle<Code> handler) {
369 Handle<FixedArray> array = EnsureArrayOfSize(3);
370 Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
371 if (name.is_null()) {
372 array->set(0, Smi::FromInt(0));
373 } else {
374 array->set(0, *name);
375 }
376 array->set(1, *receiver_map);
377 array->set(2, *handler);
378 }
379
380
381 void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types,
382 CodeHandleList* handlers) {
383 int receiver_count = types->length();
384 EnsureArrayOfSize(receiver_count * 2);
385 InstallHandlers(0, types, handlers);
386 }
387
388
389 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
390 TypeHandleList* types,
391 CodeHandleList* handlers) {
392 int receiver_count = types->length();
393 Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2);
394 if (name.is_null()) {
395 array->set(0, Smi::FromInt(0));
396 } else {
397 array->set(0, *name);
398 }
399 InstallHandlers(1, types, handlers);
400 }
401
402
236 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const { 403 int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
237 Isolate* isolate = GetIsolate(); 404 Isolate* isolate = GetIsolate();
238 Object* feedback = GetFeedback(); 405 Object* feedback = GetFeedback();
239 if (feedback->IsFixedArray()) { 406 if (feedback->IsFixedArray()) {
240 FixedArray* array = FixedArray::cast(feedback); 407 FixedArray* array = FixedArray::cast(feedback);
241 // The array should be of the form [<optional name>], then 408 // The array should be of the form [<optional name>], then
242 // [map, handler, map, handler, ... ] 409 // [map, handler, map, handler, ... ]
243 DCHECK(array->length() >= (2 + start_index)); 410 DCHECK(array->length() >= (2 + start_index));
244 for (int i = start_index; i < array->length(); i += 2) { 411 for (int i = start_index; i < array->length(); i += 2) {
245 Map* map = Map::cast(array->get(i)); 412 Map* map = Map::cast(array->get(i));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 DCHECK(array->length() >= (2 + start_index)); 449 DCHECK(array->length() >= (2 + start_index));
283 for (int i = start_index; i < array->length(); i += 2) { 450 for (int i = start_index; i < array->length(); i += 2) {
284 Code* code = Code::cast(array->get(i + 1)); 451 Code* code = Code::cast(array->get(i + 1));
285 DCHECK(code->kind() == Code::HANDLER); 452 DCHECK(code->kind() == Code::HANDLER);
286 code_list->Add(handle(code)); 453 code_list->Add(handle(code));
287 count++; 454 count++;
288 } 455 }
289 } 456 }
290 return count == length; 457 return count == length;
291 } 458 }
459
460
461 int LoadICNexus::ExtractMaps(MapHandleList* maps) const {
462 return FeedbackNexus::ExtractMaps(0, maps);
463 }
464
465
466 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); }
467
468
469 void KeyedLoadICNexus::Clear(Code* host) {
470 KeyedLoadIC::Clear(GetIsolate(), host, this);
471 }
472
473
474 int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const {
475 return FeedbackNexus::ExtractMaps(1, maps);
476 }
477
478
479 MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const {
480 return FeedbackNexus::FindHandlerForMap(0, map);
481 }
482
483
484 MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const {
485 return FeedbackNexus::FindHandlerForMap(1, map);
486 }
487
488
489 bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const {
490 return FeedbackNexus::FindHandlers(0, code_list, length);
491 }
492
493
494 bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list,
495 int length) const {
496 return FeedbackNexus::FindHandlers(1, code_list, length);
497 }
498
499
500 Name* KeyedLoadICNexus::FindFirstName() const {
501 Object* feedback = GetFeedback();
502 if (feedback->IsFixedArray()) {
503 FixedArray* array = FixedArray::cast(feedback);
504 DCHECK(array->length() >= 3);
505 Object* name = array->get(0);
506 if (name->IsName()) return Name::cast(name);
507 }
508 return NULL;
509 }
292 } 510 }
293 } // namespace v8::internal 511 } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698