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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 65 |
66 if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol() || | 66 if (obj->IsJSFunction() || obj->IsAllocationSite() || obj->IsSymbol() || |
67 obj->IsSimd128Value()) { | 67 obj->IsSimd128Value()) { |
68 return Handle<Object>(obj, isolate()); | 68 return Handle<Object>(obj, isolate()); |
69 } | 69 } |
70 | 70 |
71 return undefined; | 71 return undefined; |
72 } | 72 } |
73 | 73 |
74 | 74 |
75 InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(TypeFeedbackId id) { | |
76 Handle<Object> maybe_code = GetInfo(id); | |
77 if (maybe_code->IsCode()) { | |
78 Handle<Code> code = Handle<Code>::cast(maybe_code); | |
79 if (code->is_inline_cache_stub()) return code->ic_state(); | |
80 } | |
81 | |
82 // If we can't find an IC, assume we've seen *something*, but we don't know | |
83 // what. PREMONOMORPHIC roughly encodes this meaning. | |
84 return PREMONOMORPHIC; | |
85 } | |
86 | |
87 | |
88 InlineCacheState TypeFeedbackOracle::LoadInlineCacheState( | 75 InlineCacheState TypeFeedbackOracle::LoadInlineCacheState( |
89 FeedbackVectorSlot slot) { | 76 FeedbackVectorSlot slot) { |
90 if (!slot.IsInvalid()) { | 77 if (!slot.IsInvalid()) { |
91 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); | 78 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); |
92 if (kind == FeedbackVectorSlotKind::LOAD_IC) { | 79 if (kind == FeedbackVectorSlotKind::LOAD_IC) { |
93 LoadICNexus nexus(feedback_vector_, slot); | 80 LoadICNexus nexus(feedback_vector_, slot); |
94 return nexus.StateFromFeedback(); | 81 return nexus.StateFromFeedback(); |
95 } else if (kind == FeedbackVectorSlotKind::KEYED_LOAD_IC) { | 82 } else if (kind == FeedbackVectorSlotKind::KEYED_LOAD_IC) { |
96 KeyedLoadICNexus nexus(feedback_vector_, slot); | 83 KeyedLoadICNexus nexus(feedback_vector_, slot); |
97 return nexus.StateFromFeedback(); | 84 return nexus.StateFromFeedback(); |
98 } | 85 } |
99 } | 86 } |
100 | 87 |
101 // If we can't find an IC, assume we've seen *something*, but we don't know | 88 // If we can't find an IC, assume we've seen *something*, but we don't know |
102 // what. PREMONOMORPHIC roughly encodes this meaning. | 89 // what. PREMONOMORPHIC roughly encodes this meaning. |
103 return PREMONOMORPHIC; | 90 return PREMONOMORPHIC; |
104 } | 91 } |
105 | 92 |
106 | 93 |
107 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) { | |
108 Handle<Object> maybe_code = GetInfo(ast_id); | |
109 if (!maybe_code->IsCode()) return false; | |
110 Handle<Code> code = Handle<Code>::cast(maybe_code); | |
111 return code->ic_state() == UNINITIALIZED; | |
112 } | |
113 | |
114 | |
115 bool TypeFeedbackOracle::StoreIsUninitialized(FeedbackVectorSlot slot) { | 94 bool TypeFeedbackOracle::StoreIsUninitialized(FeedbackVectorSlot slot) { |
116 if (!slot.IsInvalid()) { | 95 if (!slot.IsInvalid()) { |
117 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); | 96 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); |
118 if (kind == FeedbackVectorSlotKind::STORE_IC) { | 97 if (kind == FeedbackVectorSlotKind::STORE_IC) { |
119 StoreICNexus nexus(feedback_vector_, slot); | 98 StoreICNexus nexus(feedback_vector_, slot); |
120 return nexus.StateFromFeedback() == UNINITIALIZED; | 99 return nexus.StateFromFeedback() == UNINITIALIZED; |
121 } else if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) { | 100 } else if (kind == FeedbackVectorSlotKind::KEYED_STORE_IC) { |
122 KeyedStoreICNexus nexus(feedback_vector_, slot); | 101 KeyedStoreICNexus nexus(feedback_vector_, slot); |
123 return nexus.StateFromFeedback() == UNINITIALIZED; | 102 return nexus.StateFromFeedback() == UNINITIALIZED; |
124 } | 103 } |
(...skipping 25 matching lines...) Expand all Loading... |
150 byte TypeFeedbackOracle::ForInType(FeedbackVectorSlot feedback_vector_slot) { | 129 byte TypeFeedbackOracle::ForInType(FeedbackVectorSlot feedback_vector_slot) { |
151 Handle<Object> value = GetInfo(feedback_vector_slot); | 130 Handle<Object> value = GetInfo(feedback_vector_slot); |
152 return value.is_identical_to( | 131 return value.is_identical_to( |
153 TypeFeedbackVector::UninitializedSentinel(isolate())) | 132 TypeFeedbackVector::UninitializedSentinel(isolate())) |
154 ? ForInStatement::FAST_FOR_IN | 133 ? ForInStatement::FAST_FOR_IN |
155 : ForInStatement::SLOW_FOR_IN; | 134 : ForInStatement::SLOW_FOR_IN; |
156 } | 135 } |
157 | 136 |
158 | 137 |
159 void TypeFeedbackOracle::GetStoreModeAndKeyType( | 138 void TypeFeedbackOracle::GetStoreModeAndKeyType( |
160 TypeFeedbackId ast_id, KeyedAccessStoreMode* store_mode, | |
161 IcCheckType* key_type) { | |
162 Handle<Object> maybe_code = GetInfo(ast_id); | |
163 if (maybe_code->IsCode()) { | |
164 Handle<Code> code = Handle<Code>::cast(maybe_code); | |
165 if (code->kind() == Code::KEYED_STORE_IC) { | |
166 ExtraICState extra_ic_state = code->extra_ic_state(); | |
167 *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state); | |
168 *key_type = KeyedStoreIC::GetKeyType(extra_ic_state); | |
169 return; | |
170 } | |
171 } | |
172 *store_mode = STANDARD_STORE; | |
173 *key_type = ELEMENT; | |
174 } | |
175 | |
176 | |
177 void TypeFeedbackOracle::GetStoreModeAndKeyType( | |
178 FeedbackVectorSlot slot, KeyedAccessStoreMode* store_mode, | 139 FeedbackVectorSlot slot, KeyedAccessStoreMode* store_mode, |
179 IcCheckType* key_type) { | 140 IcCheckType* key_type) { |
180 if (!slot.IsInvalid() && | 141 if (!slot.IsInvalid() && |
181 feedback_vector_->GetKind(slot) == | 142 feedback_vector_->GetKind(slot) == |
182 FeedbackVectorSlotKind::KEYED_STORE_IC) { | 143 FeedbackVectorSlotKind::KEYED_STORE_IC) { |
183 KeyedStoreICNexus nexus(feedback_vector_, slot); | 144 KeyedStoreICNexus nexus(feedback_vector_, slot); |
184 *store_mode = nexus.GetKeyedAccessStoreMode(); | 145 *store_mode = nexus.GetKeyedAccessStoreMode(); |
185 *key_type = nexus.GetKeyType(); | 146 *key_type = nexus.GetKeyType(); |
186 } else { | 147 } else { |
187 *store_mode = STANDARD_STORE; | 148 *store_mode = STANDARD_STORE; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( | 186 Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite( |
226 FeedbackVectorSlot slot) { | 187 FeedbackVectorSlot slot) { |
227 Handle<Object> info = GetInfo(slot); | 188 Handle<Object> info = GetInfo(slot); |
228 if (info->IsAllocationSite()) { | 189 if (info->IsAllocationSite()) { |
229 return Handle<AllocationSite>::cast(info); | 190 return Handle<AllocationSite>::cast(info); |
230 } | 191 } |
231 return Handle<AllocationSite>::null(); | 192 return Handle<AllocationSite>::null(); |
232 } | 193 } |
233 | 194 |
234 | 195 |
235 bool TypeFeedbackOracle::LoadIsBuiltin( | |
236 TypeFeedbackId id, Builtins::Name builtin) { | |
237 return *GetInfo(id) == isolate()->builtins()->builtin(builtin); | |
238 } | |
239 | |
240 | |
241 void TypeFeedbackOracle::CompareType(TypeFeedbackId id, | 196 void TypeFeedbackOracle::CompareType(TypeFeedbackId id, |
242 Type** left_type, | 197 Type** left_type, |
243 Type** right_type, | 198 Type** right_type, |
244 Type** combined_type) { | 199 Type** combined_type) { |
245 Handle<Object> info = GetInfo(id); | 200 Handle<Object> info = GetInfo(id); |
246 if (!info->IsCode()) { | 201 if (!info->IsCode()) { |
247 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. | 202 // For some comparisons we don't have ICs, e.g. LiteralCompareTypeof. |
248 *left_type = *right_type = *combined_type = Type::None(zone()); | 203 *left_type = *right_type = *combined_type = Type::None(zone()); |
249 return; | 204 return; |
250 } | 205 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 *key_type = ELEMENT; | 299 *key_type = ELEMENT; |
345 } else { | 300 } else { |
346 KeyedLoadICNexus nexus(feedback_vector_, slot); | 301 KeyedLoadICNexus nexus(feedback_vector_, slot); |
347 CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types); | 302 CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types); |
348 *is_string = HasOnlyStringMaps(receiver_types); | 303 *is_string = HasOnlyStringMaps(receiver_types); |
349 *key_type = nexus.FindFirstName() != NULL ? PROPERTY : ELEMENT; | 304 *key_type = nexus.FindFirstName() != NULL ? PROPERTY : ELEMENT; |
350 } | 305 } |
351 } | 306 } |
352 | 307 |
353 | 308 |
354 void TypeFeedbackOracle::AssignmentReceiverTypes(TypeFeedbackId id, | |
355 Handle<Name> name, | |
356 SmallMapList* receiver_types) { | |
357 receiver_types->Clear(); | |
358 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | |
359 CollectReceiverTypes(id, name, flags, receiver_types); | |
360 } | |
361 | |
362 | |
363 void TypeFeedbackOracle::AssignmentReceiverTypes(FeedbackVectorSlot slot, | 309 void TypeFeedbackOracle::AssignmentReceiverTypes(FeedbackVectorSlot slot, |
364 Handle<Name> name, | 310 Handle<Name> name, |
365 SmallMapList* receiver_types) { | 311 SmallMapList* receiver_types) { |
366 receiver_types->Clear(); | 312 receiver_types->Clear(); |
367 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); | 313 Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC); |
368 CollectReceiverTypes(slot, name, flags, receiver_types); | 314 CollectReceiverTypes(slot, name, flags, receiver_types); |
369 } | 315 } |
370 | 316 |
371 | 317 |
372 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | 318 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( |
373 TypeFeedbackId id, SmallMapList* receiver_types, | |
374 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { | |
375 receiver_types->Clear(); | |
376 CollectReceiverTypes(id, receiver_types); | |
377 GetStoreModeAndKeyType(id, store_mode, key_type); | |
378 } | |
379 | |
380 | |
381 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( | |
382 FeedbackVectorSlot slot, SmallMapList* receiver_types, | 319 FeedbackVectorSlot slot, SmallMapList* receiver_types, |
383 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { | 320 KeyedAccessStoreMode* store_mode, IcCheckType* key_type) { |
384 receiver_types->Clear(); | 321 receiver_types->Clear(); |
385 CollectReceiverTypes(slot, receiver_types); | 322 CollectReceiverTypes(slot, receiver_types); |
386 GetStoreModeAndKeyType(slot, store_mode, key_type); | 323 GetStoreModeAndKeyType(slot, store_mode, key_type); |
387 } | 324 } |
388 | 325 |
389 | 326 |
390 void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id, | |
391 SmallMapList* receiver_types) { | |
392 receiver_types->Clear(); | |
393 CollectReceiverTypes(id, receiver_types); | |
394 } | |
395 | |
396 | |
397 void TypeFeedbackOracle::CountReceiverTypes(FeedbackVectorSlot slot, | 327 void TypeFeedbackOracle::CountReceiverTypes(FeedbackVectorSlot slot, |
398 SmallMapList* receiver_types) { | 328 SmallMapList* receiver_types) { |
399 receiver_types->Clear(); | 329 receiver_types->Clear(); |
400 if (!slot.IsInvalid()) CollectReceiverTypes(slot, receiver_types); | 330 if (!slot.IsInvalid()) CollectReceiverTypes(slot, receiver_types); |
401 } | 331 } |
402 | 332 |
403 | 333 |
404 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot, | 334 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot, |
405 Handle<Name> name, | 335 Handle<Name> name, |
406 Code::Flags flags, | 336 Code::Flags flags, |
407 SmallMapList* types) { | 337 SmallMapList* types) { |
408 StoreICNexus nexus(feedback_vector_, slot); | 338 StoreICNexus nexus(feedback_vector_, slot); |
409 CollectReceiverTypes<FeedbackNexus>(&nexus, name, flags, types); | 339 CollectReceiverTypes<FeedbackNexus>(&nexus, name, flags, types); |
410 } | 340 } |
411 | 341 |
412 | 342 |
413 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | |
414 Handle<Name> name, | |
415 Code::Flags flags, | |
416 SmallMapList* types) { | |
417 Handle<Object> object = GetInfo(ast_id); | |
418 if (object->IsUndefined() || object->IsSmi()) return; | |
419 | |
420 DCHECK(object->IsCode()); | |
421 Handle<Code> code(Handle<Code>::cast(object)); | |
422 CollectReceiverTypes<Code>(*code, name, flags, types); | |
423 } | |
424 | |
425 | |
426 template <class T> | 343 template <class T> |
427 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<Name> name, | 344 void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<Name> name, |
428 Code::Flags flags, | 345 Code::Flags flags, |
429 SmallMapList* types) { | 346 SmallMapList* types) { |
430 if (FLAG_collect_megamorphic_maps_from_stub_cache && | 347 if (FLAG_collect_megamorphic_maps_from_stub_cache && |
431 obj->ic_state() == MEGAMORPHIC) { | 348 obj->ic_state() == MEGAMORPHIC) { |
432 types->Reserve(4, zone()); | 349 types->Reserve(4, zone()); |
433 isolate()->stub_cache()->CollectMatchingMaps( | 350 isolate()->stub_cache()->CollectMatchingMaps( |
434 types, name, flags, native_context_, zone()); | 351 types, name, flags, native_context_, zone()); |
435 } else { | 352 } else { |
436 CollectReceiverTypes<T>(obj, types); | 353 CollectReceiverTypes<T>(obj, types); |
437 } | 354 } |
438 } | 355 } |
439 | 356 |
440 | 357 |
441 void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id, | |
442 SmallMapList* types) { | |
443 Handle<Object> object = GetInfo(ast_id); | |
444 if (!object->IsCode()) return; | |
445 Handle<Code> code = Handle<Code>::cast(object); | |
446 CollectReceiverTypes<Code>(*code, types); | |
447 } | |
448 | |
449 | |
450 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot, | 358 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorSlot slot, |
451 SmallMapList* types) { | 359 SmallMapList* types) { |
452 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); | 360 FeedbackVectorSlotKind kind = feedback_vector_->GetKind(slot); |
453 if (kind == FeedbackVectorSlotKind::STORE_IC) { | 361 if (kind == FeedbackVectorSlotKind::STORE_IC) { |
454 StoreICNexus nexus(feedback_vector_, slot); | 362 StoreICNexus nexus(feedback_vector_, slot); |
455 CollectReceiverTypes<FeedbackNexus>(&nexus, types); | 363 CollectReceiverTypes<FeedbackNexus>(&nexus, types); |
456 } else { | 364 } else { |
457 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, kind); | 365 DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, kind); |
458 KeyedStoreICNexus nexus(feedback_vector_, slot); | 366 KeyedStoreICNexus nexus(feedback_vector_, slot); |
459 CollectReceiverTypes<FeedbackNexus>(&nexus, types); | 367 CollectReceiverTypes<FeedbackNexus>(&nexus, types); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 // Dictionary has been allocated with sufficient size for all elements. | 474 // Dictionary has been allocated with sufficient size for all elements. |
567 DisallowHeapAllocation no_need_to_resize_dictionary; | 475 DisallowHeapAllocation no_need_to_resize_dictionary; |
568 HandleScope scope(isolate()); | 476 HandleScope scope(isolate()); |
569 USE(UnseededNumberDictionary::AtNumberPut( | 477 USE(UnseededNumberDictionary::AtNumberPut( |
570 dictionary_, IdToKey(ast_id), handle(target, isolate()))); | 478 dictionary_, IdToKey(ast_id), handle(target, isolate()))); |
571 } | 479 } |
572 | 480 |
573 | 481 |
574 } // namespace internal | 482 } // namespace internal |
575 } // namespace v8 | 483 } // namespace v8 |
OLD | NEW |