OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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-info.h" | 5 #include "src/type-info.h" |
6 | 6 |
7 #include "src/ast.h" | 7 #include "src/ast.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 | 76 |
77 // Vector-based ICs do not embed direct pointers to maps, functions. | 77 // Vector-based ICs do not embed direct pointers to maps, functions. |
78 // Instead a WeakCell is always used. | 78 // Instead a WeakCell is always used. |
79 if (obj->IsWeakCell()) { | 79 if (obj->IsWeakCell()) { |
80 WeakCell* cell = WeakCell::cast(obj); | 80 WeakCell* cell = WeakCell::cast(obj); |
81 if (cell->cleared()) return undefined; | 81 if (cell->cleared()) return undefined; |
82 obj = cell->value(); | 82 obj = cell->value(); |
83 } | 83 } |
84 | 84 |
85 if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol() || | 85 if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol() || |
86 obj->IsSimd128Value()) { | 86 obj->IsSimd128Value() || (FLAG_vector_stores && obj->IsMap())) { |
mvstanton
2015/08/28 08:25:28
I refactored StoreIsUninitialized(FeedbackVectorIC
| |
87 return Handle<Object>(obj, isolate()); | 87 return Handle<Object>(obj, isolate()); |
88 } | 88 } |
89 | 89 |
90 return undefined; | 90 return undefined; |
91 } | 91 } |
92 | 92 |
93 | 93 |
94 InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(TypeFeedbackId id) { | 94 InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(TypeFeedbackId id) { |
95 Handle<Object> maybe_code = GetInfo(id); | 95 Handle<Object> maybe_code = GetInfo(id); |
96 if (maybe_code->IsCode()) { | 96 if (maybe_code->IsCode()) { |
(...skipping 27 matching lines...) Expand all Loading... | |
124 | 124 |
125 | 125 |
126 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { | 126 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { |
127 Handle<Object> maybe_code = GetInfo(ast_id); | 127 Handle<Object> maybe_code = GetInfo(ast_id); |
128 if (!maybe_code->IsCode()) return false; | 128 if (!maybe_code->IsCode()) return false; |
129 Handle<Code> code = Handle<Code>::cast(maybe_code); | 129 Handle<Code> code = Handle<Code>::cast(maybe_code); |
130 return code->ic_state() == UNINITIALIZED; | 130 return code->ic_state() == UNINITIALIZED; |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 bool TypeFeedbackOracle::StoreIsUninitialized(FeedbackVectorICSlot slot) { | |
135 if (slot.IsInvalid()) return true; | |
136 | |
137 Handle<Object> value = GetInfo(slot); | |
138 return value->IsUndefined() || | |
139 value.is_identical_to( | |
140 TypeFeedbackVector::UninitializedSentinel(isolate())); | |
141 } | |
142 | |
143 | |
134 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { | 144 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { |
135 Handle<Object> value = GetInfo(slot); | 145 Handle<Object> value = GetInfo(slot); |
136 return value->IsUndefined() || | 146 return value->IsUndefined() || |
137 value.is_identical_to( | 147 value.is_identical_to( |
138 TypeFeedbackVector::UninitializedSentinel(isolate())); | 148 TypeFeedbackVector::UninitializedSentinel(isolate())); |
139 } | 149 } |
140 | 150 |
141 | 151 |
142 bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorICSlot slot) { | 152 bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorICSlot slot) { |
143 Handle<Object> value = GetInfo(slot); | 153 Handle<Object> value = GetInfo(slot); |
(...skipping 29 matching lines...) Expand all Loading... | |
173 *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state); | 183 *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state); |
174 *key_type = KeyedStoreIC::GetKeyType(extra_ic_state); | 184 *key_type = KeyedStoreIC::GetKeyType(extra_ic_state); |
175 return; | 185 return; |
176 } | 186 } |
177 } | 187 } |
178 *store_mode = STANDARD_STORE; | 188 *store_mode = STANDARD_STORE; |
179 *key_type = ELEMENT; | 189 *key_type = ELEMENT; |
180 } | 190 } |
181 | 191 |
182 | 192 |
183 void TypeFeedbackOracle::GetLoadKeyType( | 193 void TypeFeedbackOracle::GetStoreModeAndKeyType( |
184 TypeFeedbackId ast_id, IcCheckType* key_type) { | 194 FeedbackVectorICSlot slot, KeyedAccessStoreMode* store_mode, |
185 Handle<Object> maybe_code = GetInfo(ast_id); | 195 IcCheckType* key_type) { |
186 if (maybe_code->IsCode()) { | 196 if (!slot.IsInvalid()) { |
187 Handle<Code> code = Handle<Code>::cast(maybe_code); | 197 KeyedStoreICNexus nexus(feedback_vector_, slot); |
188 if (code->kind() == Code::KEYED_LOAD_IC) { | 198 *store_mode = nexus.GetKeyedAccessStoreMode(); |
189 ExtraICState extra_ic_state = code->extra_ic_state(); | 199 *key_type = nexus.GetKeyType(); |
190 *key_type = KeyedLoadIC::GetKeyType(extra_ic_state); | 200 } else { |
191 return; | 201 *store_mode = STANDARD_STORE; |
192 } | 202 *key_type = ELEMENT; |
193 } | 203 } |
194 *key_type = ELEMENT; | |
195 } | 204 } |
196 | 205 |
197 | 206 |
198 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget( | 207 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget( |
199 FeedbackVectorICSlot slot) { | 208 FeedbackVectorICSlot slot) { |
200 Handle<Object> info = GetInfo(slot); | 209 Handle<Object> info = GetInfo(slot); |
201 if (info->IsAllocationSite()) { | 210 if (info->IsAllocationSite()) { |
202 return Handle<JSFunction>(isolate()->native_context()->array_function()); | 211 return Handle<JSFunction>(isolate()->native_context()->array_function()); |
203 } | 212 } |
204 | 213 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 | 368 |
360 void TypeFeedbackOracle::AssignmentReceiverTypes(TypeFeedbackId id, | 369 void TypeFeedbackOracle::AssignmentReceiverTypes(TypeFeedbackId id, |
361 Handle<Name> name, | 370 Handle<Name> name, |
362 SmallMapList* receiver_types) { | 371 SmallMapList* receiver_types) { |
363 receiver_types->Clear(); | 372 receiver_types->Clear(); |
364 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 373 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
365 CollectReceiverTypes(id, name, flags, receiver_types); | 374 CollectReceiverTypes(id, name, flags, receiver_types); |
366 } | 375 } |
367 | 376 |
368 | 377 |
378 void TypeFeedbackOracle::AssignmentReceiverTypes(FeedbackVectorICSlot slot, | |
379 Handle<Name> name, | |
380 SmallMapList* receiver_types) { | |
381 receiver_types->Clear(); | |
382 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | |
383 CollectReceiverTypes(slot, name, flags, receiver_types); | |
384 } | |
385 | |
386 | |
369 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 387 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( |
370 TypeFeedbackId id, SmallMapList* receiver_types, | 388 TypeFeedbackId id, SmallMapList* receiver_types, |
371 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { | 389 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { |
372 receiver_types->Clear(); | 390 receiver_types->Clear(); |
373 CollectReceiverTypes(id, receiver_types); | 391 CollectReceiverTypes(id, receiver_types); |
374 GetStoreModeAndKeyType(id, store_mode, key_type); | 392 GetStoreModeAndKeyType(id, store_mode, key_type); |
375 } | 393 } |
376 | 394 |
377 | 395 |
396 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | |
397 FeedbackVectorICSlot slot, SmallMapList* receiver_types, | |
398 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { | |
399 receiver_types->Clear(); | |
400 CollectReceiverTypes(slot, receiver_types); | |
401 GetStoreModeAndKeyType(slot, store_mode, key_type); | |
402 } | |
403 | |
404 | |
378 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id, | 405 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id, |
379 SmallMapList* receiver_types) { | 406 SmallMapList* receiver_types) { |
380 receiver_types->Clear(); | 407 receiver_types->Clear(); |
381 CollectReceiverTypes(id, receiver_types); | 408 CollectReceiverTypes(id, receiver_types); |
382 } | 409 } |
383 | 410 |
384 | 411 |
412 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot, | |
413 Handle<Name> name, | |
414 Code::Flags flags, | |
415 SmallMapList* types) { | |
416 StoreICNexus nexus(feedback_vector_, slot); | |
417 CollectReceiverTypes<FeedbackNexus>(&nexus, name, flags, types); | |
418 } | |
419 | |
420 | |
385 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 421 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
386 Handle<Name> name, | 422 Handle<Name> name, |
387 Code::Flags flags, | 423 Code::Flags flags, |
388 SmallMapList* types) { | 424 SmallMapList* types) { |
389 Handle<Object> object = GetInfo(ast_id); | 425 Handle<Object> object = GetInfo(ast_id); |
390 if (object->IsUndefined() || object->IsSmi()) return; | 426 if (object->IsUndefined() || object->IsSmi()) return; |
391 | 427 |
392 DCHECK(object->IsCode()); | 428 DCHECK(object->IsCode()); |
393 Handle<Code> code(Handle<Code>::cast(object)); | 429 Handle<Code> code(Handle<Code>::cast(object)); |
394 CollectReceiverTypes<Code>(*code, name, flags, types); | 430 CollectReceiverTypes<Code>(*code, name, flags, types); |
(...skipping 17 matching lines...) Expand all Loading... | |
412 | 448 |
413 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 449 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
414 SmallMapList* types) { | 450 SmallMapList* types) { |
415 Handle<Object> object = GetInfo(ast_id); | 451 Handle<Object> object = GetInfo(ast_id); |
416 if (!object->IsCode()) return; | 452 if (!object->IsCode()) return; |
417 Handle<Code> code = Handle<Code>::cast(object); | 453 Handle<Code> code = Handle<Code>::cast(object); |
418 CollectReceiverTypes<Code>(*code, types); | 454 CollectReceiverTypes<Code>(*code, types); |
419 } | 455 } |
420 | 456 |
421 | 457 |
458 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot, | |
459 SmallMapList* types) { | |
460 KeyedStoreICNexus nexus(feedback_vector_, slot); | |
461 CollectReceiverTypes<FeedbackNexus>(&nexus, types); | |
462 } | |
463 | |
464 | |
422 template <class T> | 465 template <class T> |
423 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { | 466 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { |
424 MapHandleList maps; | 467 MapHandleList maps; |
425 if (obj->ic_state() == MONOMORPHIC) { | 468 if (obj->ic_state() == MONOMORPHIC) { |
426 Map* map = obj->FindFirstMap(); | 469 Map* map = obj->FindFirstMap(); |
427 if (map != NULL) maps.Add(handle(map)); | 470 if (map != NULL) maps.Add(handle(map)); |
428 } else if (obj->ic_state() == POLYMORPHIC) { | 471 } else if (obj->ic_state() == POLYMORPHIC) { |
429 obj->FindAllMaps(&maps); | 472 obj->FindAllMaps(&maps); |
430 } else { | 473 } else { |
431 return; | 474 return; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
524 // Dictionary has been allocated with sufficient size for all elements. | 567 // Dictionary has been allocated with sufficient size for all elements. |
525 DisallowHeapAllocation no_need_to_resize_dictionary; | 568 DisallowHeapAllocation no_need_to_resize_dictionary; |
526 HandleScope scope(isolate()); | 569 HandleScope scope(isolate()); |
527 USE(UnseededNumberDictionary::AtNumberPut( | 570 USE(UnseededNumberDictionary::AtNumberPut( |
528 dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 571 dictionary_, IdToKey(ast_id), handle(target, isolate()))); |
529 } | 572 } |
530 | 573 |
531 | 574 |
532 } // namespace internal | 575 } // namespace internal |
533 } // namespace v8 | 576 } // namespace v8 |
OLD | NEW |