5 #ifndef V8_FEEDBACK_VECTOR_H_ 6 #define V8_FEEDBACK_VECTOR_H_ 10 #include "src/base/logging.h" 11 #include "src/base/macros.h" 12 #include "src/elements-kind.h" 13 #include "src/globals.h" 14 #include "src/objects/map.h" 15 #include "src/objects/name.h" 16 #include "src/objects/object-macros.h" 17 #include "src/type-hints.h" 18 #include "src/zone/zone-containers.h" 23 enum class FeedbackSlotKind {
33 kLastSloppyKind = kStoreKeyedSloppy,
38 kLoadGlobalNotInsideTypeof,
39 kLoadGlobalInsideTypeof,
48 kStoreDataPropertyInLiteral,
59 inline bool IsCallICKind(FeedbackSlotKind kind) {
60 return kind == FeedbackSlotKind::kCall;
63 inline bool IsLoadICKind(FeedbackSlotKind kind) {
64 return kind == FeedbackSlotKind::kLoadProperty;
67 inline bool IsLoadGlobalICKind(FeedbackSlotKind kind) {
68 return kind == FeedbackSlotKind::kLoadGlobalNotInsideTypeof ||
69 kind == FeedbackSlotKind::kLoadGlobalInsideTypeof;
72 inline bool IsKeyedLoadICKind(FeedbackSlotKind kind) {
73 return kind == FeedbackSlotKind::kLoadKeyed;
76 inline bool IsStoreGlobalICKind(FeedbackSlotKind kind) {
77 return kind == FeedbackSlotKind::kStoreGlobalSloppy ||
78 kind == FeedbackSlotKind::kStoreGlobalStrict;
81 inline bool IsStoreICKind(FeedbackSlotKind kind) {
82 return kind == FeedbackSlotKind::kStoreNamedSloppy ||
83 kind == FeedbackSlotKind::kStoreNamedStrict;
86 inline bool IsStoreOwnICKind(FeedbackSlotKind kind) {
87 return kind == FeedbackSlotKind::kStoreOwnNamed;
90 inline bool IsStoreDataPropertyInLiteralKind(FeedbackSlotKind kind) {
91 return kind == FeedbackSlotKind::kStoreDataPropertyInLiteral;
94 inline bool IsKeyedStoreICKind(FeedbackSlotKind kind) {
95 return kind == FeedbackSlotKind::kStoreKeyedSloppy ||
96 kind == FeedbackSlotKind::kStoreKeyedStrict;
99 inline bool IsStoreInArrayLiteralICKind(FeedbackSlotKind kind) {
100 return kind == FeedbackSlotKind::kStoreInArrayLiteral;
103 inline bool IsGlobalICKind(FeedbackSlotKind kind) {
104 return IsLoadGlobalICKind(kind) || IsStoreGlobalICKind(kind);
107 inline bool IsTypeProfileKind(FeedbackSlotKind kind) {
108 return kind == FeedbackSlotKind::kTypeProfile;
111 inline bool IsCloneObjectKind(FeedbackSlotKind kind) {
112 return kind == FeedbackSlotKind::kCloneObject;
115 inline TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind) {
116 DCHECK(IsLoadGlobalICKind(kind));
117 return (kind == FeedbackSlotKind::kLoadGlobalInsideTypeof)
122 inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
123 DCHECK(IsStoreICKind(kind) || IsStoreOwnICKind(kind) ||
124 IsStoreGlobalICKind(kind) || IsKeyedStoreICKind(kind));
125 STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <=
126 FeedbackSlotKind::kLastSloppyKind);
127 STATIC_ASSERT(FeedbackSlotKind::kStoreKeyedSloppy <=
128 FeedbackSlotKind::kLastSloppyKind);
129 STATIC_ASSERT(FeedbackSlotKind::kStoreNamedSloppy <=
130 FeedbackSlotKind::kLastSloppyKind);
131 return (kind <= FeedbackSlotKind::kLastSloppyKind) ? LanguageMode::kSloppy
132 : LanguageMode::kStrict;
135 std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind);
137 typedef std::vector<MaybeObjectHandle> MaybeObjectHandles;
139 class FeedbackMetadata;
153 inline void ComputeCounts(
int* with_type_info,
int*
generic,
154 int* vector_ic_count);
156 inline bool is_empty()
const;
166 DECL_ACCESSORS2(optimized_code_weak_or_smi,
MaybeObject)
170 DECL_INT32_ACCESSORS(length)
173 DECL_INT32_ACCESSORS(invocation_count)
177 DECL_INT32_ACCESSORS(profiler_ticks)
180 DECL_INT32_ACCESSORS(deopt_count)
182 inline void clear_invocation_count();
183 inline void increment_deopt_count();
185 inline Code optimized_code()
const;
186 inline OptimizationMarker optimization_marker()
const;
187 inline bool has_optimized_code()
const;
188 inline bool has_optimization_marker()
const;
189 void ClearOptimizedCode();
194 void SetOptimizationMarker(OptimizationMarker marker);
197 void ClearOptimizationMarker();
200 static int GetIndex(
FeedbackSlot slot) {
return slot.ToInt(); }
207 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
209 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
211 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
212 inline void set(
int index,
Object* value,
213 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
226 #define DEFINE_SLOT_KIND_PREDICATE(Name) \ 227 bool Name(FeedbackSlot slot) const { return Name##Kind(GetKind(slot)); } 229 DEFINE_SLOT_KIND_PREDICATE(IsCallIC)
230 DEFINE_SLOT_KIND_PREDICATE(IsGlobalIC)
231 DEFINE_SLOT_KIND_PREDICATE(IsLoadIC)
232 DEFINE_SLOT_KIND_PREDICATE(IsLoadGlobalIC)
233 DEFINE_SLOT_KIND_PREDICATE(IsKeyedLoadIC)
234 DEFINE_SLOT_KIND_PREDICATE(IsStoreIC)
235 DEFINE_SLOT_KIND_PREDICATE(IsStoreOwnIC)
236 DEFINE_SLOT_KIND_PREDICATE(IsStoreGlobalIC)
237 DEFINE_SLOT_KIND_PREDICATE(IsKeyedStoreIC)
238 DEFINE_SLOT_KIND_PREDICATE(IsTypeProfile)
239 #undef DEFINE_SLOT_KIND_PREDICATE 242 inline TypeofMode GetTypeofMode(
FeedbackSlot slot)
const {
243 return GetTypeofModeFromSlotKind(GetKind(slot));
247 inline LanguageMode GetLanguageMode(
FeedbackSlot slot)
const {
248 return GetLanguageModeFromSlotKind(GetKind(slot));
251 static void AssertNoLegacyTypes(
MaybeObject object);
256 void FeedbackSlotPrint(std::ostream& os,
FeedbackSlot slot);
259 bool ClearSlots(
Isolate* isolate);
275 static inline Symbol RawUninitializedSentinel(
Isolate* isolate);
278 #define FEEDBACK_VECTOR_FIELDS(V) \ 280 V(kSharedFunctionInfoOffset, kPointerSize) \ 281 V(kOptimizedCodeOffset, kPointerSize) \ 282 V(kLengthOffset, kInt32Size) \ 283 V(kInvocationCountOffset, kInt32Size) \ 284 V(kProfilerTicksOffset, kInt32Size) \ 285 V(kDeoptCountOffset, kInt32Size) \ 286 V(kUnalignedHeaderSize, 0) 288 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, FEEDBACK_VECTOR_FIELDS)
289 #undef FEEDBACK_VECTOR_FIELDS 291 static const int kHeaderSize =
292 RoundUp<kObjectAlignment>(
int{kUnalignedHeaderSize});
293 static const int kFeedbackSlotsOffset = kHeaderSize;
298 static constexpr
int SizeFor(
int length) {
299 return kFeedbackSlotsOffset + length * kPointerSize;
303 static void AddToVectorsForProfilingTools(
Isolate* isolate,
312 slot_kinds_.reserve(16);
315 int slots()
const {
return static_cast<int>(slot_kinds_.size()); }
318 return static_cast<FeedbackSlotKind
>(slot_kinds_.at(slot.ToInt()));
321 bool HasTypeProfileSlot()
const;
326 static const int kTypeProfileSlotIndex = 0;
328 FeedbackSlot AddCallICSlot() {
return AddSlot(FeedbackSlotKind::kCall); }
331 return AddSlot(FeedbackSlotKind::kLoadProperty);
334 FeedbackSlot AddLoadGlobalICSlot(TypeofMode typeof_mode) {
335 return AddSlot(typeof_mode == INSIDE_TYPEOF
336 ? FeedbackSlotKind::kLoadGlobalInsideTypeof
337 : FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
341 return AddSlot(FeedbackSlotKind::kCreateClosure);
345 return AddSlot(FeedbackSlotKind::kLoadKeyed);
348 FeedbackSlotKind GetStoreICSlot(LanguageMode language_mode) {
349 STATIC_ASSERT(LanguageModeSize == 2);
350 return is_strict(language_mode) ? FeedbackSlotKind::kStoreNamedStrict
351 : FeedbackSlotKind::kStoreNamedSloppy;
354 FeedbackSlot AddStoreICSlot(LanguageMode language_mode) {
355 return AddSlot(GetStoreICSlot(language_mode));
359 return AddSlot(FeedbackSlotKind::kStoreOwnNamed);
362 FeedbackSlot AddStoreGlobalICSlot(LanguageMode language_mode) {
363 STATIC_ASSERT(LanguageModeSize == 2);
364 return AddSlot(is_strict(language_mode)
365 ? FeedbackSlotKind::kStoreGlobalStrict
366 : FeedbackSlotKind::kStoreGlobalSloppy);
369 FeedbackSlotKind GetKeyedStoreICSlotKind(LanguageMode language_mode) {
370 STATIC_ASSERT(LanguageModeSize == 2);
371 return is_strict(language_mode) ? FeedbackSlotKind::kStoreKeyedStrict
372 : FeedbackSlotKind::kStoreKeyedSloppy;
375 FeedbackSlot AddKeyedStoreICSlot(LanguageMode language_mode) {
376 return AddSlot(GetKeyedStoreICSlotKind(language_mode));
380 return AddSlot(FeedbackSlotKind::kStoreInArrayLiteral);
384 return AddSlot(FeedbackSlotKind::kBinaryOp);
388 return AddSlot(FeedbackSlotKind::kCompareOp);
391 FeedbackSlot AddForInSlot() {
return AddSlot(FeedbackSlotKind::kForIn); }
394 return AddSlot(FeedbackSlotKind::kInstanceOf);
397 FeedbackSlot AddLiteralSlot() {
return AddSlot(FeedbackSlotKind::kLiteral); }
400 return AddSlot(FeedbackSlotKind::kStoreDataPropertyInLiteral);
406 return AddSlot(FeedbackSlotKind::kCloneObject);
412 #endif // OBJECT_PRINT 419 void append(FeedbackSlotKind kind) {
420 slot_kinds_.push_back(static_cast<unsigned char>(kind));
433 : kind_(kind), spec_(spec) {}
436 if (slot_.IsInvalid()) slot_ = spec_->AddSlot(kind_);
441 FeedbackSlotKind kind_;
457 DECL_INT32_ACCESSORS(slot_count)
460 inline int32_t synchronized_slot_count()
const;
463 static inline int GetSlotSize(FeedbackSlotKind kind);
467 inline bool is_empty()
const;
479 static const char* Kind2String(FeedbackSlotKind kind);
480 bool HasTypeProfileSlot()
const;
485 static int SizeFor(
int slot_count) {
486 return OBJECT_POINTER_ALIGN(kHeaderSize + length(slot_count) * kInt32Size);
489 static const int kSlotCountOffset = HeapObject::kHeaderSize;
490 static const int kHeaderSize = kSlotCountOffset + kInt32Size;
498 inline int32_t
get(
int index)
const;
499 inline void set(
int index, int32_t value);
503 static int length(
int slot_count) {
504 return VectorICComputer::word_count(slot_count);
506 inline int length()
const;
508 static const int kFeedbackSlotKindBits = 5;
509 STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) <
510 (1 << kFeedbackSlotKindBits));
515 kInt32Size * kBitsPerByte,
uint32_t>
523 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
524 STATIC_ASSERT(Name::kEmptyHashField == 0x3);
526 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
531 : metadata_handle_(metadata),
533 slot_kind_(FeedbackSlotKind::kInvalid) {}
536 : metadata_(metadata),
538 slot_kind_(FeedbackSlotKind::kInvalid) {}
540 inline bool HasNext()
const;
545 FeedbackSlotKind kind()
const {
546 DCHECK_NE(FeedbackSlotKind::kInvalid, slot_kind_);
547 DCHECK_NE(FeedbackSlotKind::kKindsNumber, slot_kind_);
552 inline int entry_size()
const;
556 return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
566 FeedbackSlotKind slot_kind_;
573 : vector_handle_(vector),
576 kind_(vector->GetKind(slot)) {}
578 : vector_(vector), slot_(slot), kind_(vector->GetKind(slot)) {}
581 DCHECK_NULL(vector_);
582 return vector_handle_;
585 return vector_handle_.is_null() ? vector_ : *vector_handle_;
588 FeedbackSlotKind kind()
const {
return kind_; }
590 inline LanguageMode GetLanguageMode()
const {
591 return vector()->GetLanguageMode(slot());
594 InlineCacheState ic_state()
const {
return StateFromFeedback(); }
595 bool IsUninitialized()
const {
return StateFromFeedback() == UNINITIALIZED; }
596 bool IsMegamorphic()
const {
return StateFromFeedback() == MEGAMORPHIC; }
597 bool IsGeneric()
const {
return StateFromFeedback() == GENERIC; }
599 void Print(std::ostream& os);
602 Map FindFirstMap()
const;
604 InlineCacheState StateFromFeedback()
const;
605 int ExtractMaps(MapHandles* maps)
const;
607 bool FindHandlers(MaybeObjectHandles* code_list,
int length = -1)
const;
609 bool IsCleared()
const {
610 InlineCacheState state = StateFromFeedback();
611 return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC;
616 void ConfigureUninitialized();
617 void ConfigurePremonomorphic(
Handle<Map> receiver_map);
620 bool ConfigureMegamorphic();
621 bool ConfigureMegamorphic(IcCheckType property_type);
626 inline Isolate* GetIsolate()
const;
631 void ConfigurePolymorphic(
Handle<Name> name, MapHandles
const& maps,
632 MaybeObjectHandles* handlers);
634 BinaryOperationHint GetBinaryOperationFeedback()
const;
635 CompareOperationHint GetCompareOperationFeedback()
const;
636 ForInHint GetForInFeedback()
const;
639 KeyedAccessLoadMode GetKeyedAccessLoadMode()
const;
642 KeyedAccessStoreMode GetKeyedAccessStoreMode()
const;
645 IcCheckType GetKeyType()
const;
646 Name FindFirstName()
const;
650 void SetSpeculationMode(SpeculationMode mode);
651 SpeculationMode GetSpeculationMode();
655 float ComputeCallFrequency();
669 bool ConfigureLexicalVarMode(
int script_context_index,
670 int context_slot_index);
674 static constexpr
int kCloneObjectPolymorphicEntrySize = 2;
678 #define LEXICAL_MODE_BIT_FIELDS(V, _) \ 679 V(ContextIndexBits, unsigned, 12, _) \ 680 V(SlotIndexBits, unsigned, 19, _) 682 DEFINE_BIT_FIELDS(LEXICAL_MODE_BIT_FIELDS)
683 #undef LEXICAL_MODE_BIT_FIELDS 686 STATIC_ASSERT(LEXICAL_MODE_BIT_FIELDS_Ranges::kBitsCount <= kSmiValueSize);
690 void ResetTypeProfile();
696 std::vector<int> GetSourcePositions()
const;
697 std::vector<Handle<String>> GetTypesForSourcePositions(
uint32_t pos)
const;
699 inline void SetFeedback(
Object* feedback,
700 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
702 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
703 inline void SetFeedbackExtra(
Object* feedback_extra,
704 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
705 inline void SetFeedbackExtra(
MaybeObject feedback_extra,
706 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
719 FeedbackSlotKind kind_;
722 inline BinaryOperationHint BinaryOperationHintFromFeedback(
int type_feedback);
723 inline CompareOperationHint CompareOperationHintFromFeedback(
int type_feedback);
724 inline ForInHint ForInHintFromFeedback(
int type_feedback);
729 #endif // V8_FEEDBACK_VECTOR_H_