5#ifndef RUNTIME_VM_TAGGED_POINTER_H_
6#define RUNTIME_VM_TAGGED_POINTER_H_
20#define OBJECT_POINTER_CORE_FUNCTIONS(type, ptr) \
21 type* operator->() { \
24 const type* operator->() const { \
27 bool IsWellFormed() const { \
28 const uword value = ptr; \
29 return (value & kSmiTagMask) == 0 || \
30 Utils::IsAligned(value - kHeapObjectTag, kWordSize); \
32 bool IsImmediateObject() const { \
33 ASSERT(IsWellFormed()); \
34 const uword value = ptr; \
35 return (value & kSmiTagMask) != kHeapObjectTag; \
37 bool IsHeapObject() const { \
38 ASSERT(IsWellFormed()); \
39 const uword value = ptr; \
40 return (value & kSmiTagMask) == kHeapObjectTag; \
43 bool IsNewObject() const { \
44 ASSERT(IsHeapObject()); \
45 const uword addr = ptr; \
46 return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset; \
48 bool IsNewObjectMayBeSmi() const { \
49 const uword kNewObjectBits = (kNewObjectAlignmentOffset | kHeapObjectTag); \
50 const uword addr = ptr; \
51 return (addr & kObjectAlignmentMask) == kNewObjectBits; \
54 bool IsOldObject() const { \
55 ASSERT(IsHeapObject()); \
56 const uword addr = ptr; \
57 return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset; \
61 bool IsImmediateOrOldObject() const { \
62 ASSERT(IsWellFormed()); \
63 const uword kNewObjectBits = (kNewObjectAlignmentOffset | kHeapObjectTag); \
64 const uword addr = ptr; \
65 return (addr & kObjectAlignmentMask) != kNewObjectBits; \
69 bool IsImmediateOrNewObject() const { \
70 ASSERT(IsWellFormed()); \
71 const uword kOldObjectBits = (kOldObjectAlignmentOffset | kHeapObjectTag); \
72 const uword addr = ptr; \
73 return (addr & kObjectAlignmentMask) != kOldObjectBits; \
76 bool operator==(const type& other) { \
77 return (ptr & kSmiTagMask) == kHeapObjectTag \
79 : static_cast<compressed_uword>(ptr) == \
80 static_cast<compressed_uword>(other.ptr); \
82 bool operator!=(const type& other) { \
83 return (ptr & kSmiTagMask) == kHeapObjectTag \
85 : static_cast<compressed_uword>(ptr) != \
86 static_cast<compressed_uword>(other.ptr); \
88 constexpr bool operator==(const type& other) const { \
89 return (ptr & kSmiTagMask) == kHeapObjectTag \
91 : static_cast<compressed_uword>(ptr) == \
92 static_cast<compressed_uword>(other.ptr); \
94 constexpr bool operator!=(const type& other) const { \
95 return (ptr & kSmiTagMask) == kHeapObjectTag \
97 : static_cast<compressed_uword>(ptr) != \
98 static_cast<compressed_uword>(other.ptr); \
109#define DEFINE_IS_CID(clazz) \
110 bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
114#define DEFINE_IS_CID(clazz) \
115 bool IsTypedData##clazz() const { \
116 return ((GetClassId() == kTypedData##clazz##Cid)); \
118 bool IsTypedDataView##clazz() const { \
119 return ((GetClassId() == kTypedData##clazz##ViewCid)); \
121 bool IsUnmodifiableTypedDataView##clazz() const { \
122 return ((GetClassId() == kUnmodifiableTypedData##clazz##ViewCid)); \
124 bool IsExternalTypedData##clazz() const { \
125 return ((GetClassId() == kExternalTypedData##clazz##Cid)); \
130#define DEFINE_IS_CID(clazz) \
131 bool IsFfi##clazz() const { return ((GetClassId() == kFfi##clazz##Cid)); }
152 return IsHeapObject() ?
GetClassId() :
static_cast<intptr_t
>(kSmiCid);
159 constexpr bool operator==(
const std::nullptr_t& other)
const {
162 constexpr bool operator!=(
const std::nullptr_t& other)
const {
167 operator bool()
const =
delete;
175#if INT_MAX == INTPTR_MAX
176 explicit operator int()
const {
180#if LONG_MAX == INTPTR_MAX
181 explicit operator long()
const {
185#if LLONG_MAX == INTPTR_MAX
186 explicit operator long long()
const {
190#if UINT_MAX == UINTPTR_MAX
191 explicit operator unsigned int()
const {
195#if ULONG_MAX == UINTPTR_MAX
196 explicit operator unsigned long()
const {
200#if ULLONG_MAX == UINTPTR_MAX
201 explicit operator unsigned long long()
const {
223#if !defined(DART_HOST_OS_WINDOWS)
225 ASSERT(!IsInstructions());
226 ASSERT(!IsInstructionsSection());
241#if defined(DEBUG) || defined(TESTING)
243 os << reinterpret_cast<void*>(
static_cast<uword>(obj));
248template <
typename T,
typename Enable =
void>
253 typename
std::enable_if<std::is_base_of<ObjectPtr, T>::value, void>
::type>
255template <
typename T,
typename Enable =
void>
258template <
typename T,
typename Enable =
void>
264#if !defined(DART_COMPRESSED_POINTERS)
266#define DEFINE_COMPRESSED_POINTER(klass, base) \
267 typedef klass##Ptr Compressed##klass##Ptr;
274 : compressed_pointer_(
275 static_cast<uint32_t
>(
static_cast<uword>(uncompressed))) {}
277 : compressed_pointer_(
static_cast<uint32_t
>(tagged)) {}
280 return static_cast<ObjectPtr>(
static_cast<uword>(compressed_pointer_) +
286 return static_cast<ObjectPtr>(
static_cast<uword>(compressed_pointer_));
290 compressed_pointer_ =
static_cast<uint32_t
>(
static_cast<uword>(other));
295 uint32_t compressed_pointer_;
299struct is_compressed_ptr<
301 typename
std::enable_if<std::is_base_of<CompressedObjectPtr, T>::value,
302 void>
::type> : std::true_type{};
306 typename
std::enable_if<std::is_base_of<CompressedObjectPtr, T>::value,
311#define DEFINE_COMPRESSED_POINTER(klass, base) \
312 class Compressed##klass##Ptr : public Compressed##base##Ptr { \
314 Compressed##klass##Ptr* operator->() { \
317 const Compressed##klass##Ptr* operator->() const { \
320 explicit Compressed##klass##Ptr(klass##Ptr uncompressed) \
321 : Compressed##base##Ptr(uncompressed) {} \
322 const klass##Ptr& operator=(const klass##Ptr& other) { \
323 compressed_pointer_ = static_cast<uint32_t>(static_cast<uword>(other)); \
326 klass##Ptr Decompress(uword heap_base) const { \
327 return klass##Ptr(CompressedObjectPtr::Decompress(heap_base)); \
332#define DEFINE_TAGGED_POINTER(klass, base) \
333 class Untagged##klass; \
334 class klass##Ptr : public base##Ptr { \
336 klass##Ptr* operator->() { \
339 const klass##Ptr* operator->() const { \
342 Untagged##klass* untag() { \
343 return reinterpret_cast<Untagged##klass*>(untagged_pointer()); \
346 Untagged##klass* untag() const { \
347 return reinterpret_cast<Untagged##klass*>(untagged_pointer()); \
349 klass##Ptr& operator=(const klass##Ptr& other) = default; \
350 constexpr klass##Ptr(const klass##Ptr& other) = default; \
351 explicit constexpr klass##Ptr(const ObjectPtr& other) \
352 : base##Ptr(other) {} \
353 klass##Ptr() : base##Ptr() {} \
354 explicit constexpr klass##Ptr(uword tagged) : base##Ptr(tagged) {} \
355 explicit constexpr klass##Ptr(intptr_t tagged) : base##Ptr(tagged) {} \
356 constexpr klass##Ptr(std::nullptr_t) : base##Ptr(nullptr) {} \
357 explicit klass##Ptr(const UntaggedObject* untagged) \
358 : base##Ptr(reinterpret_cast<uword>(untagged) + kHeapObjectTag) {} \
359 klass##Ptr Decompress(uword heap_base) const { \
363 DEFINE_COMPRESSED_POINTER(klass, base)
457#undef DEFINE_TAGGED_POINTER
460#if !defined(DART_COMPRESSED_POINTERS)
461 const intptr_t
value =
static_cast<intptr_t
>(raw_value);
463 const intptr_t
value =
static_cast<intptr_t
>(
static_cast<int32_t
>(
464 static_cast<uint32_t
>(
static_cast<uintptr_t
>(raw_value))));
#define CLASS_LIST_FFI(V)
#define CLASS_LIST_TYPED_DATA(V)
constexpr ObjectPtr(std::nullptr_t)
constexpr bool operator!=(const std::nullptr_t &other) const
ObjectPtr(UntaggedObject *heap_object)
ObjectPtr DecompressSmi() const
bool IsDartInstance() const
void Validate(IsolateGroup *isolate_group) const
bool IsFreeListElement() const
constexpr ObjectPtr(uword tagged)
ObjectPtr Decompress(uword heap_base) const
constexpr ObjectPtr(const ObjectPtr &other)=default
bool operator==(const std::nullptr_t &other)
constexpr bool operator==(const std::nullptr_t &other) const
bool operator!=(const std::nullptr_t &other)
UntaggedObject * untag() const
bool IsStringInstance() const
bool IsForwardingCorpse() const
intptr_t GetClassId() const
uword untagged_pointer() const
intptr_t GetClassIdMayBeSmi() const
ObjectPtr & operator=(const ObjectPtr &other)=default
constexpr ObjectPtr(intptr_t tagged)
bool IsPseudoObject() const
static constexpr uintptr_t kHeapBaseMask
intptr_t RawSmiValue(const SmiPtr raw_value)
static void Finalizer(void *isolate_callback_data, void *buffer)
bool IsInternalOnlyClassId(intptr_t index)
bool IsStringClassId(intptr_t index)
ObjectPtr CompressedObjectPtr
std::ostream & operator<<(std::ostream &out, const impeller::Color &c)
typename std::enable_if< is_uncompressed_ptr< T >::value, ObjectPtr >::type type
#define DEFINE_TAGGED_POINTER(klass, base)
#define OBJECT_POINTER_CORE_FUNCTIONS(type, ptr)
#define DEFINE_IS_CID(clazz)