5#ifndef V8_OBJECTS_INSTANCE_TYPE_INL_H_
6#define V8_OBJECTS_INSTANCE_TYPE_INL_H_
23namespace InstanceTypeChecker {
31namespace InstanceTypeTraits {
33#define DECL_TYPE(type, ...) class type;
35TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(
DECL_TYPE)
36TORQUE_INSTANCE_CHECKERS_MULTIPLE_ONLY_DECLARED(
DECL_TYPE)
49#define INSTANCE_TYPE_MAP(V, rootIndexName, rootAccessorName, class_name) \
51 V8_INLINE consteval std::optional<RootIndex> \
52 UniqueMapOfInstanceTypeCheck<InstanceTypeTraits::class_name>() { \
53 return {RootIndex::k##rootIndexName}; \
56#undef INSTANCE_TYPE_MAP
60#define INSTANCE_TYPE_CHECK(it, forinstancetype) \
61 if (type == forinstancetype) { \
62 return InstanceTypeChecker::UniqueMapOfInstanceTypeCheck< \
63 InstanceTypeChecker::InstanceTypeTraits::it>(); \
66#undef INSTANCE_TYPE_CHECK
78#if V8_STATIC_ROOTS_BOOL
79constexpr std::array<std::pair<InstanceTypeRange, TaggedAddressRange>, 9>
80 kUniqueMapRangeOfInstanceTypeRangeList = {
81 {{{ALLOCATION_SITE_TYPE, ALLOCATION_SITE_TYPE},
82 {StaticReadOnlyRoot::kAllocationSiteWithWeakNextMap,
83 StaticReadOnlyRoot::kAllocationSiteWithoutWeakNextMap}},
85 {InstanceTypeChecker::kStringMapLowerBound,
86 InstanceTypeChecker::kStringMapUpperBound}},
87 {{FIRST_NAME_TYPE, LAST_NAME_TYPE},
88 {StaticReadOnlyRoot::kSeqTwoByteStringMap,
89 StaticReadOnlyRoot::kSymbolMap}},
90 {{ODDBALL_TYPE, ODDBALL_TYPE},
91 {StaticReadOnlyRoot::kUndefinedMap, StaticReadOnlyRoot::kBooleanMap}},
92 {{HEAP_NUMBER_TYPE, ODDBALL_TYPE},
93 {StaticReadOnlyRoot::kUndefinedMap,
94 StaticReadOnlyRoot::kHeapNumberMap}},
96 {StaticReadOnlyRoot::kHeapNumberMap, StaticReadOnlyRoot::kBigIntMap}},
97 {{FIRST_SMALL_ORDERED_HASH_TABLE_TYPE,
98 LAST_SMALL_ORDERED_HASH_TABLE_TYPE},
99 {StaticReadOnlyRoot::kSmallOrderedHashMapMap,
100 StaticReadOnlyRoot::kSmallOrderedNameDictionaryMap}},
101 {{FIRST_ABSTRACT_INTERNAL_CLASS_TYPE,
102 LAST_ABSTRACT_INTERNAL_CLASS_TYPE},
103 {StaticReadOnlyRoot::kAbstractInternalClassSubclass1Map,
104 StaticReadOnlyRoot::kAbstractInternalClassSubclass2Map}},
105 {{FIRST_TURBOFAN_TYPE_TYPE, LAST_TURBOFAN_TYPE_TYPE},
106 {StaticReadOnlyRoot::kTurbofanBitsetTypeMap,
107 StaticReadOnlyRoot::kTurbofanOtherNumberConstantTypeMap}}}};
109struct kUniqueMapRangeOfStringType {
110 static constexpr TaggedAddressRange kSeqString = {
111 InstanceTypeChecker::kStringMapLowerBound,
112 StaticReadOnlyRoot::kInternalizedOneByteStringMap};
113 static constexpr TaggedAddressRange kInternalizedString = {
114 StaticReadOnlyRoot::kInternalizedTwoByteStringMap,
115 StaticReadOnlyRoot::kUncachedExternalInternalizedOneByteStringMap};
116 static constexpr TaggedAddressRange kExternalString = {
117 StaticReadOnlyRoot::kExternalInternalizedTwoByteStringMap,
118 StaticReadOnlyRoot::kSharedExternalOneByteStringMap};
120 StaticReadOnlyRoot::kUncachedExternalInternalizedTwoByteStringMap,
121 StaticReadOnlyRoot::kSharedUncachedExternalOneByteStringMap};
123 StaticReadOnlyRoot::kConsTwoByteStringMap,
124 StaticReadOnlyRoot::kConsOneByteStringMap};
126 StaticReadOnlyRoot::kSlicedTwoByteStringMap,
127 StaticReadOnlyRoot::kSlicedOneByteStringMap};
129 StaticReadOnlyRoot::kThinTwoByteStringMap,
130 StaticReadOnlyRoot::kThinOneByteStringMap};
140static constexpr int kStringMapEncodingMask =
142static constexpr int kOneByteStringMapBit =
143 StaticReadOnlyRoot::kSeqOneByteStringMap & kStringMapEncodingMask;
144static constexpr int kTwoByteStringMapBit =
145 StaticReadOnlyRoot::kSeqTwoByteStringMap & kStringMapEncodingMask;
147inline constexpr std::optional<TaggedAddressRange>
151 for (
size_t i = 0;
i < kUniqueMapRangeOfInstanceTypeRangeList.size(); ++
i) {
152 if (kUniqueMapRangeOfInstanceTypeRangeList[
i].first.first == first &&
153 kUniqueMapRangeOfInstanceTypeRangeList[
i].first.second == last) {
154 return {kUniqueMapRangeOfInstanceTypeRangeList[
i].second};
160inline constexpr std::optional<TaggedAddressRange> UniqueMapRangeOfInstanceType(
162 return UniqueMapRangeOfInstanceTypeRange(type, type);
167 for (
auto& el : kUniqueMapRangeOfInstanceTypeRangeList) {
168 if (el.first.first <= type && type <= el.first.second) {
175inline bool CheckInstanceMap(
RootIndex expected, Tagged<Map> map) {
177 StaticReadOnlyRootsPointerTable[
static_cast<size_t>(expected)];
198#define INSTANCE_TYPE_CHECKER1(type, forinstancetype) \
199 V8_INLINE constexpr bool Is##type(InstanceType instance_type) { \
200 return instance_type == forinstancetype; \
203#if V8_STATIC_ROOTS_BOOL
205#define INSTANCE_TYPE_CHECKER2(type, forinstancetype_) \
206 V8_INLINE bool Is##type(Tagged<Map> map_object) { \
207 constexpr InstanceType forinstancetype = \
208 static_cast<InstanceType>(forinstancetype_); \
209 if constexpr (constexpr std::optional<RootIndex> index = \
210 UniqueMapOfInstanceType(forinstancetype)) { \
211 return CheckInstanceMap(*index, map_object); \
213 if constexpr (constexpr std::optional<TaggedAddressRange> map_range = \
214 UniqueMapRangeOfInstanceType(forinstancetype)) { \
215 return CheckInstanceMapRange(*map_range, map_object); \
217 return Is##type(map_object->instance_type()); \
222#define INSTANCE_TYPE_CHECKER2(type, forinstancetype) \
223 V8_INLINE bool Is##type(Tagged<Map> map_object) { \
224 return Is##type(map_object->instance_type()); \
231#undef INSTANCE_TYPE_CHECKER1
232#undef INSTANCE_TYPE_CHECKER2
236template <InstanceType lower_limit, InstanceType upper_limit>
242template <InstanceType upper_limit>
246 return value <= upper_limit;
249template <InstanceType lower_limit>
253 return value >= lower_limit;
263#define INSTANCE_TYPE_CHECKER_RANGE1(type, first_instance_type, \
264 last_instance_type) \
265 V8_INLINE constexpr bool Is##type(InstanceType instance_type) { \
266 return InstanceRangeChecker<first_instance_type, \
267 last_instance_type>::Check(instance_type); \
270#if V8_STATIC_ROOTS_BOOL
272#define INSTANCE_TYPE_CHECKER_RANGE2(type, first_instance_type, \
273 last_instance_type) \
274 V8_INLINE bool Is##type(Tagged<Map> map_object) { \
275 if constexpr (constexpr std::optional<TaggedAddressRange> maybe_range = \
276 UniqueMapRangeOfInstanceTypeRange(first_instance_type, \
277 last_instance_type)) { \
278 return CheckInstanceMapRange(*maybe_range, map_object); \
280 return Is##type(map_object->instance_type()); \
285#define INSTANCE_TYPE_CHECKER_RANGE2(type, first_instance_type, \
286 last_instance_type) \
287 V8_INLINE bool Is##type(Tagged<Map> map_object) { \
288 return Is##type(map_object->instance_type()); \
295#undef INSTANCE_TYPE_CHECKER_RANGE1
296#undef INSTANCE_TYPE_CHECKER_RANGE2
309#if V8_STATIC_ROOTS_BOOL
310 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kInternalizedString,
323#if V8_STATIC_ROOTS_BOOL
324 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kSeqString,
337#if V8_STATIC_ROOTS_BOOL
338 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kExternalString,
352#if V8_STATIC_ROOTS_BOOL
353 return CheckInstanceMapRange(
354 kUniqueMapRangeOfStringType::kUncachedExternalString, map_object);
365#if V8_STATIC_ROOTS_BOOL
366 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kConsString,
378#if V8_STATIC_ROOTS_BOOL
379 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kSlicedString,
391#if V8_STATIC_ROOTS_BOOL
392 return CheckInstanceMapRange(kUniqueMapRangeOfStringType::kThinString,
400 DCHECK(IsString(instance_type));
405#if V8_STATIC_ROOTS_BOOL
406 DCHECK(IsStringMap(map_object));
409 return (ptr & kStringMapEncodingMask) == kOneByteStringMapBit;
416 DCHECK(IsString(instance_type));
421#if V8_STATIC_ROOTS_BOOL
422 DCHECK(IsStringMap(map_object));
425 return (ptr & kStringMapEncodingMask) == kTwoByteStringMapBit;
432 return !IsString(instance_type) && !IsBigInt(instance_type) &&
433 instance_type != HEAP_NUMBER_TYPE;
437 return IsCode(instance_type);
441 return IsCode(map_object);
445 return IsBytecodeArray(instance_type) || IsCode(instance_type);
453 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
465 return IsJSExternalObject(instance_type) || IsJSMessageObject(instance_type);
484 if (IsContext(instance_type))
return true;
486 if (!IsJSReceiver(instance_type))
return false;
490 if (instance_type == JS_MESSAGE_OBJECT_TYPE ||
491 instance_type == JS_EXTERNAL_OBJECT_TYPE) {
497 }
else if (InstanceTypeChecker::IsAlwaysSharedSpaceJSObject(instance_type)) {
501#if V8_ENABLE_WEBASSEMBLY
502 }
else if (InstanceTypeChecker::IsWasmObject(instance_type)) {
516#define TYPE_CHECKER(type, ...) \
517 bool Is##type##Map(Tagged<Map> map) { \
518 return InstanceTypeChecker::Is##type(map); \
static constexpr std::optional< RootIndex > TryGetMapRootIdxFor(InstanceType type)
V8_INLINE constexpr StorageType ptr() const
static V8_INLINE Tagged_t CompressObject(Address tagged)
#define TYPE_CHECKER(type,...)
#define INSTANCE_TYPE_CHECKERS_SINGLE(V)
#define INSTANCE_TYPE_CHECKERS_RANGE(V)
#define INSTANCE_TYPE_CHECKERS(V)
#define DECL_TYPE(type,...)
#define INSTANCE_TYPE_CHECKER2(type, forinstancetype)
#define INSTANCE_TYPE_MAP(V, rootIndexName, rootAccessorName, class_name)
#define INSTANCE_TYPE_CHECK(it, forinstancetype)
#define INSTANCE_TYPE_CHECKER_RANGE1(type, first_instance_type, last_instance_type)
#define INSTANCE_TYPE_CHECKER1(type, forinstancetype)
#define INSTANCE_TYPE_CHECKER_RANGE2(type, first_instance_type, last_instance_type)
#define UNIQUE_INSTANCE_TYPE_MAP_LIST_GENERATOR(V, _)
constexpr unsigned CountTrailingZerosNonZero(T value)
constexpr bool IsInRange(T value, U lower_limit, U higher_limit)
V8_INLINE constexpr bool IsSeqString(InstanceType instance_type)
V8_INLINE constexpr bool IsThinString(InstanceType instance_type)
std::pair< InstanceType, InstanceType > InstanceTypeRange
V8_INLINE constexpr bool IsGcSafeCode(InstanceType instance_type)
V8_INLINE constexpr bool IsConsString(InstanceType instance_type)
bool MayHaveMapCheckFastCase(InstanceType type)
V8_INLINE constexpr bool IsExternalString(InstanceType instance_type)
V8_INLINE constexpr bool IsOneByteString(InstanceType instance_type)
V8_INLINE constexpr bool IsInternalizedString(InstanceType instance_type)
V8_INLINE consteval std::optional< RootIndex > UniqueMapOfInstanceTypeCheck()
V8_INLINE bool IsNativeContextSpecificMap(Tagged< Map > map_object)
V8_INLINE constexpr std::optional< RootIndex > UniqueMapOfInstanceType(InstanceType type)
V8_INLINE constexpr bool IsPropertyDictionary(InstanceType instance_type)
V8_INLINE constexpr bool IsNativeContextSpecific(InstanceType instance_type)
V8_INLINE constexpr bool IsAbstractCode(InstanceType instance_type)
V8_INLINE constexpr bool IsFreeSpaceOrFiller(InstanceType instance_type)
V8_INLINE constexpr bool IsMaybeReadOnlyJSObject(InstanceType instance_type)
V8_INLINE constexpr bool IsReferenceComparable(InstanceType instance_type)
std::pair< Tagged_t, Tagged_t > TaggedAddressRange
V8_INLINE constexpr bool IsSlicedString(InstanceType instance_type)
V8_INLINE constexpr bool IsUncachedExternalString(InstanceType instance_type)
V8_INLINE constexpr bool IsTwoByteString(InstanceType instance_type)
V8_INLINE constexpr bool IsHeapObject(InstanceType instance_type)
const uint32_t kStringEncodingMask
const uint32_t kTwoByteStringTag
constexpr InstanceType LAST_STRING_TYPE
const uint32_t kUncachedExternalStringTag
static constexpr InstanceType PROPERTY_DICTIONARY_TYPE
const uint32_t kUncachedExternalStringMask
const uint32_t kNotInternalizedTag
const uint32_t kStringTag
const uint32_t kOneByteStringTag
const uint32_t kStringRepresentationMask
const uint32_t kInternalizedTag
const uint32_t kIsNotInternalizedMask
const uint32_t kIsNotStringMask
#define HEAP_OBJECT_TYPE_LIST(V)
#define DCHECK_LE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
static constexpr bool Check(InstanceType value)
static constexpr bool Check(InstanceType value)
static constexpr bool Check(InstanceType value)