5#ifndef V8_OBJECTS_FEEDBACK_VECTOR_H_
6#define V8_OBJECTS_FEEDBACK_VECTOR_H_
30class FeedbackVectorSpec;
103 case HeapObjectReferenceType::STRONG:
106 case HeapObjectReferenceType::WEAK:
131 return index_ == other.index_;
134 return index_ != other.index_;
270#include "torque-generated/src/objects/feedback-vector-tq.inc"
277 RootIndex::kClosureFeedbackCellArrayMap;
287 ClosureFeedbackCellArrayShape> {
310 :
public TorqueGeneratedFeedbackVector<FeedbackVector, HeapObject> {
313 DEFINE_TORQUE_GENERATED_OSR_STATE()
314 DEFINE_TORQUE_GENERATED_FEEDBACK_VECTOR_FLAGS()
316#ifndef V8_ENABLE_LEAPTIERING
320 FeedbackVector::MaybeHasTurbofanCodeBit::kMask;
322 FeedbackVector::MaybeHasMaglevCodeBit::kMask;
324 FeedbackVector::MaybeHasMaglevCodeBit::kMask |
325 FeedbackVector::MaybeHasTurbofanCodeBit::kMask;
329 FeedbackVector::LogNextExecutionBit::kMask;
341 using TorqueGeneratedFeedbackVector::invocation_count;
342 using TorqueGeneratedFeedbackVector::set_invocation_count;
345 using TorqueGeneratedFeedbackVector::invocation_count_before_stable;
346 using TorqueGeneratedFeedbackVector::set_invocation_count_before_stable;
375#ifndef V8_ENABLE_LEAPTIERING
404#ifdef V8_ENABLE_LEAPTIERING
405 inline bool tiering_in_progress()
const;
406 void set_tiering_in_progress(
bool);
469#define DEFINE_SLOT_KIND_PREDICATE(Name) \
470 bool Name(FeedbackSlot slot) const { return Name##Kind(GetKind(slot)); }
481#undef DEFINE_SLOT_KIND_PREDICATE
497#ifdef V8_TRACE_FEEDBACK_UPDATES
498 static void TraceFeedbackChange(
Isolate* isolate,
527 "Header must be padded for alignment");
529 class BodyDescriptor;
532 return kRawFeedbackSlotsOffset + index *
kTaggedSize;
557 using TorqueGeneratedFeedbackVector::raw_feedback_slots;
563 : slot_kinds_(zone), create_closure_parameter_counts_(zone) {
564 slot_kinds_.reserve(16);
567 int slot_count()
const {
return static_cast<int>(slot_kinds_.size()); }
569 return static_cast<int>(create_closure_parameter_counts_.size());
574 return create_closure_slot_count() - 1;
578 return create_closure_parameter_counts_.at(index);
582 return slot_kinds_.at(slot.
ToInt());
588 return AddSlot(FeedbackSlotKind::kLoadProperty);
592 return AddSlot(typeof_mode == TypeofMode::kInside
593 ? FeedbackSlotKind::kLoadGlobalInsideTypeof
594 : FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
598 return AddSlot(FeedbackSlotKind::kLoadKeyed);
602 return AddSlot(FeedbackSlotKind::kHasKeyed);
606 static_assert(LanguageModeSize == 2);
607 return is_strict(language_mode) ? FeedbackSlotKind::kSetNamedStrict
608 : FeedbackSlotKind::kSetNamedSloppy;
612 return AddSlot(GetStoreICSlot(language_mode));
616 return AddSlot(FeedbackSlotKind::kDefineNamedOwn);
622 return AddSlot(FeedbackSlotKind::kDefineKeyedOwn);
626 static_assert(LanguageModeSize == 2);
628 ? FeedbackSlotKind::kStoreGlobalStrict
629 : FeedbackSlotKind::kStoreGlobalSloppy);
633 static_assert(LanguageModeSize == 2);
634 return is_strict(language_mode) ? FeedbackSlotKind::kSetKeyedStrict
635 : FeedbackSlotKind::kSetKeyedSloppy;
639 return AddSlot(GetKeyedStoreICSlotKind(language_mode));
643 return AddSlot(FeedbackSlotKind::kStoreInArrayLiteral);
647 return AddSlot(FeedbackSlotKind::kBinaryOp);
651 return AddSlot(FeedbackSlotKind::kCompareOp);
657 return AddSlot(FeedbackSlotKind::kInstanceOf);
665 return AddSlot(FeedbackSlotKind::kDefineKeyedOwnPropertyInLiteral);
669 return AddSlot(FeedbackSlotKind::kCloneObject);
673 return AddSlot(FeedbackSlotKind::kJumpLoop);
758 template <typename IsolateT>
779 V(kSlotCountOffset, kInt32Size) \
780 V(kCreateClosureSlotCountOffset, kInt32Size) \
786 class BodyDescriptor;
792 inline int32_t
get(
int index)
const;
793 inline void set(
int index, int32_t value);
888 enum Mode { MainThread, BackgroundThread };
891 return local_heap_ ==
nullptr ? MainThread : BackgroundThread;
897 template <
typename T>
917 :
isolate_(isolate), local_heap_(nullptr) {}
919 :
isolate_(isolate), local_heap_(local_heap) {}
941 return vector_handle_;
944 return vector_handle_.is_null() ?
vector_ : *vector_handle_;
951 return vector()->GetLanguageMode(slot());
956 return ic_state() == InlineCacheState::UNINITIALIZED;
959 return ic_state() == InlineCacheState::MEGAMORPHIC;
961 bool IsGeneric()
const {
return ic_state() == InlineCacheState::GENERIC; }
972 int ExtractMapsAndHandlers(
978 template <
typename F>
979 void IterateMapsWithUnclearedHandler(
F)
const;
983 return !
v8_flags.use_ic || state == InlineCacheState::UNINITIALIZED;
988 void ConfigureUninitialized();
991 bool ConfigureMegamorphic();
992 bool ConfigureMegamorphic(
IcCheckType property_type);
1032 float ComputeCallFrequency();
1044 bool ConfigureLexicalVarMode(
int script_context_index,
int context_slot_index,
1049 static constexpr int kCloneObjectPolymorphicEntrySize = 2;
1054#define LEXICAL_MODE_BIT_FIELDS(V, _) \
1055 V(ContextIndexBits, unsigned, 12, _) \
1056 V(SlotIndexBits, unsigned, 18, _) \
1057 V(ImmutabilityBit, bool, 1, _)
1060#undef LEXICAL_MODE_BIT_FIELDS
1063 static_assert(LEXICAL_MODE_BIT_FIELDS_Ranges::kBitsCount <= kSmiValueSize);
1066 template <
typename FeedbackType>
1067 inline void SetFeedback(Tagged<FeedbackType> feedback,
1068 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
1069 template <
typename FeedbackType,
typename FeedbackExtraType>
1070 inline void SetFeedback(Tagged<FeedbackType> feedback, WriteBarrierMode mode,
1071 Tagged<FeedbackExtraType> feedback_extra,
1072 WriteBarrierMode mode_extra = UPDATE_WRITE_BARRIER);
1074 inline Tagged<MaybeObject> UninitializedSentinel()
const;
1075 inline Tagged<MaybeObject> MegamorphicSentinel()
const;
1076 inline Tagged<MaybeObject> MegaDOMSentinel()
const;
1079 DirectHandle<WeakFixedArray> CreateArrayOfSize(
int length);
1082 inline Tagged<MaybeObject> FromHandle(MaybeObjectDirectHandle slot)
const;
1083 inline MaybeObjectHandle ToHandle(Tagged<MaybeObject> value)
const;
1095 mutable std::optional<std::pair<MaybeObjectHandle, MaybeObjectHandle>>
1111 return number_of_entries * kEntrySize;
1116 return entry * kEntrySize;
1121 return (entry * kEntrySize) + kHandlerOffset;
1124 static constexpr int kEntrySize = 2;
1125 static constexpr int kHandlerOffset = 1;
1128 void AdvancePolymorphic();
#define DEFINE_BIT_FIELDS(LIST_MACRO)
static int word_count(int items)
static constexpr bool kLengthEqualsCapacity
static constexpr RootIndex kMapRootIndex
static V8_EXPORT_PRIVATE DirectHandle< ClosureFeedbackCellArray > New(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared, AllocationType allocation=AllocationType::kYoung)
void push_back(const_reference x)
size_t size() const noexcept
bool empty() const noexcept
static int HandlerIndexForEntry(int entry)
Tagged< MaybeObject > handler_
DirectHandle< WeakFixedArray > polymorphic_feedback_
static int MapIndexForEntry(int entry)
static int SizeFor(int number_of_entries)
Tagged< MaybeObject > handler()
std::function< MaybeHandle< Map >(Handle< Map >)> TryUpdateHandler
const NexusConfig * config() const
Tagged< FeedbackVector > vector() const
DirectHandle< FeedbackVector > vector_handle() const
FeedbackSlotKind kind() const
bool IsMegamorphic() const
Handle< FeedbackVector > vector_handle_
bool IsUninitialized() const
LanguageMode GetLanguageMode() const
Tagged< FeedbackVector > vector_
void Print(std::ostream &os)
FeedbackSlot slot() const
std::optional< std::pair< MaybeObjectHandle, MaybeObjectHandle > > feedback_cache_
FeedbackVectorSpec(Zone *zone)
FeedbackSlot AddDefineKeyedOwnPropertyInLiteralICSlot()
FeedbackSlot AddStoreInArrayLiteralICSlot()
FeedbackSlot AddCloneObjectSlot()
FeedbackSlotKind GetKind(FeedbackSlot slot) const
FeedbackSlot AddCallICSlot()
FeedbackSlot AddForInSlot()
FeedbackSlot AddInstanceOfSlot()
int create_closure_slot_count() const
FeedbackSlot AddLoadICSlot()
void append(FeedbackSlotKind kind)
FeedbackSlot AddKeyedStoreICSlot(LanguageMode language_mode)
FeedbackSlot AddCompareICSlot()
FeedbackSlot AddJumpLoopSlot()
FeedbackSlot AddLiteralSlot()
FeedbackSlotKind GetKeyedStoreICSlotKind(LanguageMode language_mode)
FeedbackSlot AddSlot(FeedbackSlotKind kind)
FeedbackSlot AddStoreICSlot(LanguageMode language_mode)
ZoneVector< uint16_t > create_closure_parameter_counts_
FeedbackSlot AddBinaryOpICSlot()
uint16_t GetCreateClosureParameterCount(int index) const
FeedbackSlot AddLoadGlobalICSlot(TypeofMode typeof_mode)
int AddCreateClosureParameterCount(uint16_t parameter_count)
FeedbackSlot AddTypeOfSlot()
ZoneVector< FeedbackSlotKind > slot_kinds_
FeedbackSlotKind GetStoreICSlot(LanguageMode language_mode)
FeedbackSlot AddStoreGlobalICSlot(LanguageMode language_mode)
FeedbackSlot AddKeyedHasICSlot()
FeedbackSlot AddDefineKeyedOwnICSlot()
FeedbackSlot AddDefineNamedOwnICSlot()
FeedbackSlot AddKeyedLoadICSlot()
V8_EXPORT_PRIVATE void set_tiering_state(TieringState state)
LanguageMode GetLanguageMode(FeedbackSlot slot) const
bool was_once_deoptimized() const
static DirectHandle< Symbol > MegaDOMSentinel(Isolate *isolate)
Tagged< MaybeObject > Get(FeedbackSlot slot) const
static FeedbackSlot ToSlot(intptr_t index)
static DirectHandle< Symbol > UninitializedSentinel(Isolate *isolate)
Tagged< Code > optimized_code(IsolateForSandbox isolate) const
void set_maybe_has_turbofan_code(bool value)
TypeofMode GetTypeofMode(FeedbackSlot slot) const
static V8_EXPORT_PRIVATE Handle< FeedbackVector > NewWithOneBinarySlotForTesting(Zone *zone, Isolate *isolate)
static V8_EXPORT_PRIVATE Handle< FeedbackVector > NewForTesting(Isolate *isolate, const FeedbackVectorSpec *spec)
void set_maybe_has_optimized_osr_code(bool value, CodeKind code_kind)
bool maybe_has_optimized_osr_code() const
bool has_optimized_code() const
void RequestOsrAtNextOpportunity()
void SetOptimizedOsrCode(Isolate *isolate, FeedbackSlot slot, Tagged< Code > code)
Tagged< FeedbackCell > closure_feedback_cell(int index) const
void Set(FeedbackSlot slot, Tagged< MaybeObject > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
static Tagged< Symbol > RawUninitializedSentinel(Isolate *isolate)
static V8_EXPORT_PRIVATE Handle< FeedbackVector > New(Isolate *isolate, DirectHandle< SharedFunctionInfo > shared, DirectHandle< ClosureFeedbackCellArray > closure_feedback_cell_array, DirectHandle< FeedbackCell > parent_feedback_cell, IsCompiledScope *is_compiled_scope)
static constexpr uint32_t kFlagsHasAnyOptimizedCode
static constexpr uint8_t kInvocationCountBeforeStableDeoptSentinel
bool maybe_has_maglev_osr_code() const
static constexpr uint32_t kFlagsMaybeHasMaglevCode
MaybeObjectSlot slots_start()
bool maybe_has_turbofan_code() const
bool maybe_has_maglev_code() const
bool log_next_execution() const
std::optional< Tagged< Code > > GetOptimizedOsrCode(Isolate *isolate, FeedbackSlot slot)
bool osr_tiering_in_progress()
void set_log_next_execution(bool value=true)
Tagged< MaybeObject > SynchronizedGet(FeedbackSlot slot) const
DirectHandle< FeedbackCell > GetClosureFeedbackCell(Isolate *isolate, int index) const
static int GetIndex(FeedbackSlot slot)
void reset_tiering_state()
bool ClearSlots(Isolate *isolate)
static void AddToVectorsForProfilingTools(Isolate *isolate, DirectHandle< FeedbackVector > vector)
void FeedbackSlotPrint(std::ostream &os, FeedbackSlot slot)
void set_maybe_has_maglev_code(bool value)
void SynchronizedSet(FeedbackSlot slot, Tagged< MaybeObject > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
TieringState tiering_state() const
static constexpr uint32_t kFlagsTieringStateIsAnyRequested
bool ClearAllSlotsForTesting(Isolate *isolate)
void EvictOptimizedCodeMarkedForDeoptimization(Isolate *isolate, Tagged< SharedFunctionInfo > shared, const char *reason)
bool interrupt_budget_reset_by_ic_change() const
void clear_invocation_count(RelaxedStoreTag tag)
void SetOptimizedCode(IsolateForSandbox isolate, Tagged< Code > code)
static constexpr uint32_t kFlagsLogNextExecution
void set_was_once_deoptimized()
static Handle< Symbol > MegamorphicSentinel(Isolate *isolate)
bool maybe_has_turbofan_osr_code() const
void ClearOptimizedCode()
void set_interrupt_budget_reset_by_ic_change(bool value)
void set_osr_urgency(int urgency)
static constexpr uint32_t kFlagsMaybeHasTurbofanCode
static constexpr int kMaxOsrUrgency
static constexpr uint32_t FlagMaskForNeedsProcessingCheckFrom(CodeKind code_kind)
static V8_EXPORT_PRIVATE Handle< FeedbackVector > NewWithOneCompareSlotForTesting(Zone *zone, Isolate *isolate)
void set_osr_tiering_in_progress(bool osr_in_progress)
V8_EXPORT_PRIVATE FeedbackSlotKind GetKind(FeedbackSlot slot) const
static constexpr int OffsetOfElementAt(int index)
static constexpr int kHeaderSize
constexpr Iterator(const MapsAndHandlers *container, size_t i)
constexpr Iterator()=default
value_type operator*() const
constexpr Iterator operator++(int)
constexpr bool operator==(const Iterator &other)
constexpr Iterator & operator++()
constexpr bool operator!=(const Iterator &other)
const MapsAndHandlers * container_
DirectHandleSmallVector< Object, DEFAULT_MAX_POLYMORPHIC_MAP_COUNT > handlers_
void emplace_back(DirectHandle< Map > map, MaybeObjectDirectHandle handler)
MapsAndHandlers(Isolate *isolate)
DirectHandleSmallVector< Map, DEFAULT_MAX_POLYMORPHIC_MAP_COUNT > maps_
base::SmallVector< HeapObjectReferenceType, DEFAULT_MAX_POLYMORPHIC_MAP_COUNT > handlers_reference_types_
MapAndHandler operator[](size_t i) const
base::Vector< DirectHandle< Map > > maps()
void set_handler(size_t i, MaybeObjectDirectHandle handler)
void reserve(size_t capacity)
void set_map(size_t i, DirectHandle< Map > map)
static MaybeObjectDirectHandle Weak(Tagged< Object > object, Isolate *isolate)
static constexpr int kEmptyHashField
static constexpr int kHashNotComputedMask
Isolate * isolate() const
NexusConfig(Isolate *isolate, LocalHeap *local_heap)
NexusConfig(Isolate *isolate)
LocalHeap *const local_heap_
static NexusConfig FromMainThread(Isolate *isolate)
static NexusConfig FromBackgroundThread(Isolate *isolate, LocalHeap *local_heap)
FeedbackVectorSpec * spec_
SharedFeedbackSlot(FeedbackVectorSpec *spec, FeedbackSlotKind kind)
#define OBJECT_POINTER_ALIGN(value)
#define DEFINE_SLOT_KIND_PREDICATE(Name)
#define LEXICAL_MODE_BIT_FIELDS(V, _)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
constexpr Vector< T > VectorOf(T *start, size_t size)
bool IsStoreGlobalICKind(FeedbackSlotKind kind)
bool IsKeyedHasICKind(FeedbackSlotKind kind)
constexpr int kTaggedSize
bool IsDefineNamedOwnICKind(FeedbackSlotKind kind)
constexpr int kBitsPerByte
ForInHint ForInHintFromFeedback(ForInFeedback type_feedback)
constexpr intptr_t kObjectAlignment
CompareOperationHint CompareOperationHintFromFeedback(int type_feedback)
bool IsSetNamedICKind(FeedbackSlotKind kind)
static constexpr int kFeedbackSlotKindCount
@ kLoadGlobalNotInsideTypeof
@ kLoadGlobalInsideTypeof
@ kDefineKeyedOwnPropertyInLiteral
LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind)
bool IsLoadICKind(FeedbackSlotKind kind)
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
bool IsCallICKind(FeedbackSlotKind kind)
bool IsStoreInArrayLiteralICKind(FeedbackSlotKind kind)
bool is_strict(LanguageMode language_mode)
TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind)
V8_EXPORT_PRIVATE FlagValues v8_flags
bool IsKeyedLoadICKind(FeedbackSlotKind kind)
bool IsCloneObjectKind(FeedbackSlotKind kind)
bool IsDefineKeyedOwnICKind(FeedbackSlotKind kind)
constexpr int kUInt16Size
bool IsLoadGlobalICKind(FeedbackSlotKind kind)
static constexpr uint32_t kNoneOrInProgressMask
bool IsDefineKeyedOwnPropertyInLiteralKind(FeedbackSlotKind kind)
BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback)
std::vector< MaybeObjectHandle > MaybeObjectHandles
V8HeapCompressionSchemeImpl< MainCage > V8HeapCompressionScheme
bool IsGlobalICKind(FeedbackSlotKind kind)
bool IsKeyedStoreICKind(FeedbackSlotKind kind)
std::pair< DirectHandle< Map >, MaybeObjectDirectHandle > MapAndHandler
#define DECL_GETTER(name,...)
#define DECL_ACQUIRE_GETTER(name,...)
#define DECL_VERIFIER(Name)
#define NEVER_READ_ONLY_SPACE
#define DECL_PRINTER(Name)
#define DECL_RELAXED_INT32_ACCESSORS(name)
#define TQ_OBJECT_CONSTRUCTORS(Type)
#define DECL_INT32_ACCESSORS(name)
#define DECL_RELAXED_UINT8_ACCESSORS(name)
#define CHECK_GE(lhs, rhs)
#define CHECK_GT(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define V8_EXPORT_PRIVATE
EmbedderRootsHandler * handler_
#define DEFINE_FIELD_OFFSET_CONSTANTS(StartOffset, LIST_MACRO)