Chromium Code Reviews| 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 |