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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after 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()) { |
| 136 Code::Kind kind = feedback_vector_->GetKind(slot); |
| 137 if (kind == Code::STORE_IC) { |
| 138 StoreICNexus nexus(feedback_vector_, slot); |
| 139 return nexus.StateFromFeedback(); |
| 140 } else if (kind == Code::KEYED_STORE_IC) { |
| 141 KeyedStoreICNexus nexus(feedback_vector_, slot); |
| 142 return nexus.StateFromFeedback(); |
| 143 } |
| 144 } |
| 145 return true; |
| 146 } |
| 147 |
| 148 |
134 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { | 149 bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) { |
135 Handle<Object> value = GetInfo(slot); | 150 Handle<Object> value = GetInfo(slot); |
136 return value->IsUndefined() || | 151 return value->IsUndefined() || |
137 value.is_identical_to( | 152 value.is_identical_to( |
138 TypeFeedbackVector::UninitializedSentinel(isolate())); | 153 TypeFeedbackVector::UninitializedSentinel(isolate())); |
139 } | 154 } |
140 | 155 |
141 | 156 |
142 bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorICSlot slot) { | 157 bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorICSlot slot) { |
143 Handle<Object> value = GetInfo(slot); | 158 Handle<Object> value = GetInfo(slot); |
(...skipping 29 matching lines...) Expand all Loading... |
173 *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state); | 188 *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state); |
174 *key_type = KeyedStoreIC::GetKeyType(extra_ic_state); | 189 *key_type = KeyedStoreIC::GetKeyType(extra_ic_state); |
175 return; | 190 return; |
176 } | 191 } |
177 } | 192 } |
178 *store_mode = STANDARD_STORE; | 193 *store_mode = STANDARD_STORE; |
179 *key_type = ELEMENT; | 194 *key_type = ELEMENT; |
180 } | 195 } |
181 | 196 |
182 | 197 |
183 void TypeFeedbackOracle::GetLoadKeyType( | 198 void TypeFeedbackOracle::GetStoreModeAndKeyType( |
184 TypeFeedbackId ast_id, IcCheckType* key_type) { | 199 FeedbackVectorICSlot slot, KeyedAccessStoreMode* store_mode, |
185 Handle<Object> maybe_code = GetInfo(ast_id); | 200 IcCheckType* key_type) { |
186 if (maybe_code->IsCode()) { | 201 if (!slot.IsInvalid()) { |
187 Handle<Code> code = Handle<Code>::cast(maybe_code); | 202 KeyedStoreICNexus nexus(feedback_vector_, slot); |
188 if (code->kind() == Code::KEYED_LOAD_IC) { | 203 *store_mode = nexus.GetKeyedAccessStoreMode(); |
189 ExtraICState extra_ic_state = code->extra_ic_state(); | 204 *key_type = nexus.GetKeyType(); |
190 *key_type = KeyedLoadIC::GetKeyType(extra_ic_state); | 205 } else { |
191 return; | 206 *store_mode = STANDARD_STORE; |
192 } | 207 *key_type = ELEMENT; |
193 } | 208 } |
194 *key_type = ELEMENT; | |
195 } | 209 } |
196 | 210 |
197 | 211 |
198 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget( | 212 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget( |
199 FeedbackVectorICSlot slot) { | 213 FeedbackVectorICSlot slot) { |
200 Handle<Object> info = GetInfo(slot); | 214 Handle<Object> info = GetInfo(slot); |
201 if (info->IsAllocationSite()) { | 215 if (info->IsAllocationSite()) { |
202 return Handle<JSFunction>(isolate()->native_context()->array_function()); | 216 return Handle<JSFunction>(isolate()->native_context()->array_function()); |
203 } | 217 } |
204 | 218 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 | 373 |
360 void TypeFeedbackOracle::AssignmentReceiverTypes(TypeFeedbackId id, | 374 void TypeFeedbackOracle::AssignmentReceiverTypes(TypeFeedbackId id, |
361 Handle<Name> name, | 375 Handle<Name> name, |
362 SmallMapList* receiver_types) { | 376 SmallMapList* receiver_types) { |
363 receiver_types->Clear(); | 377 receiver_types->Clear(); |
364 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 378 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
365 CollectReceiverTypes(id, name, flags, receiver_types); | 379 CollectReceiverTypes(id, name, flags, receiver_types); |
366 } | 380 } |
367 | 381 |
368 | 382 |
| 383 void TypeFeedbackOracle::AssignmentReceiverTypes(FeedbackVectorICSlot slot, |
| 384 Handle<Name> name, |
| 385 SmallMapList* receiver_types) { |
| 386 receiver_types->Clear(); |
| 387 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
| 388 CollectReceiverTypes(slot, name, flags, receiver_types); |
| 389 } |
| 390 |
| 391 |
369 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 392 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( |
370 TypeFeedbackId id, SmallMapList* receiver_types, | 393 TypeFeedbackId id, SmallMapList* receiver_types, |
371 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { | 394 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { |
372 receiver_types->Clear(); | 395 receiver_types->Clear(); |
373 CollectReceiverTypes(id, receiver_types); | 396 CollectReceiverTypes(id, receiver_types); |
374 GetStoreModeAndKeyType(id, store_mode, key_type); | 397 GetStoreModeAndKeyType(id, store_mode, key_type); |
375 } | 398 } |
376 | 399 |
377 | 400 |
| 401 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( |
| 402 FeedbackVectorICSlot slot, SmallMapList* receiver_types, |
| 403 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { |
| 404 receiver_types->Clear(); |
| 405 CollectReceiverTypes(slot, receiver_types); |
| 406 GetStoreModeAndKeyType(slot, store_mode, key_type); |
| 407 } |
| 408 |
| 409 |
378 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id, | 410 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id, |
379 SmallMapList* receiver_types) { | 411 SmallMapList* receiver_types) { |
380 receiver_types->Clear(); | 412 receiver_types->Clear(); |
381 CollectReceiverTypes(id, receiver_types); | 413 CollectReceiverTypes(id, receiver_types); |
382 } | 414 } |
383 | 415 |
384 | 416 |
| 417 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot, |
| 418 Handle<Name> name, |
| 419 Code::Flags flags, |
| 420 SmallMapList* types) { |
| 421 StoreICNexus nexus(feedback_vector_, slot); |
| 422 CollectReceiverTypes<FeedbackNexus>(&nexus, name, flags, types); |
| 423 } |
| 424 |
| 425 |
385 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 426 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
386 Handle<Name> name, | 427 Handle<Name> name, |
387 Code::Flags flags, | 428 Code::Flags flags, |
388 SmallMapList* types) { | 429 SmallMapList* types) { |
389 Handle<Object> object = GetInfo(ast_id); | 430 Handle<Object> object = GetInfo(ast_id); |
390 if (object->IsUndefined() || object->IsSmi()) return; | 431 if (object->IsUndefined() || object->IsSmi()) return; |
391 | 432 |
392 DCHECK(object->IsCode()); | 433 DCHECK(object->IsCode()); |
393 Handle<Code> code(Handle<Code>::cast(object)); | 434 Handle<Code> code(Handle<Code>::cast(object)); |
394 CollectReceiverTypes<Code>(*code, name, flags, types); | 435 CollectReceiverTypes<Code>(*code, name, flags, types); |
(...skipping 17 matching lines...) Expand all Loading... |
412 | 453 |
413 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | 454 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, |
414 SmallMapList* types) { | 455 SmallMapList* types) { |
415 Handle<Object> object = GetInfo(ast_id); | 456 Handle<Object> object = GetInfo(ast_id); |
416 if (!object->IsCode()) return; | 457 if (!object->IsCode()) return; |
417 Handle<Code> code = Handle<Code>::cast(object); | 458 Handle<Code> code = Handle<Code>::cast(object); |
418 CollectReceiverTypes<Code>(*code, types); | 459 CollectReceiverTypes<Code>(*code, types); |
419 } | 460 } |
420 | 461 |
421 | 462 |
| 463 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot, |
| 464 SmallMapList* types) { |
| 465 KeyedStoreICNexus nexus(feedback_vector_, slot); |
| 466 CollectReceiverTypes<FeedbackNexus>(&nexus, types); |
| 467 } |
| 468 |
| 469 |
422 template <class T> | 470 template <class T> |
423 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { | 471 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) { |
424 MapHandleList maps; | 472 MapHandleList maps; |
425 if (obj->ic_state() == MONOMORPHIC) { | 473 if (obj->ic_state() == MONOMORPHIC) { |
426 Map* map = obj->FindFirstMap(); | 474 Map* map = obj->FindFirstMap(); |
427 if (map != NULL) maps.Add(handle(map)); | 475 if (map != NULL) maps.Add(handle(map)); |
428 } else if (obj->ic_state() == POLYMORPHIC) { | 476 } else if (obj->ic_state() == POLYMORPHIC) { |
429 obj->FindAllMaps(&maps); | 477 obj->FindAllMaps(&maps); |
430 } else { | 478 } else { |
431 return; | 479 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. | 572 // Dictionary has been allocated with sufficient size for all elements. |
525 DisallowHeapAllocation no_need_to_resize_dictionary; | 573 DisallowHeapAllocation no_need_to_resize_dictionary; |
526 HandleScope scope(isolate()); | 574 HandleScope scope(isolate()); |
527 USE(UnseededNumberDictionary::AtNumberPut( | 575 USE(UnseededNumberDictionary::AtNumberPut( |
528 dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 576 dictionary_, IdToKey(ast_id), handle(target, isolate()))); |
529 } | 577 } |
530 | 578 |
531 | 579 |
532 } // namespace internal | 580 } // namespace internal |
533 } // namespace v8 | 581 } // namespace v8 |
OLD | NEW |