v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
tagged-impl.h
Go to the documentation of this file.
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_TAGGED_IMPL_H_
6#define V8_OBJECTS_TAGGED_IMPL_H_
7
10#include "src/base/macros.h"
11#include "src/common/checks.h"
12#include "src/common/globals.h"
14
15namespace v8 {
16namespace internal {
17
18#if defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
19// When V8_EXTERNAL_CODE_SPACE or V8_ENABLE_SANDBOX is enabled, comparing
20// objects in the code- or trusted space with "regular" objects by looking only
21// at compressed values is not correct. Full pointers must be compared instead.
22bool V8_EXPORT_PRIVATE CheckObjectComparisonAllowed(Address a, Address b);
23#endif
24
25// An TaggedImpl is a base class for Object (which is either a Smi or a strong
26// reference to a HeapObject) and Tagged<MaybeObject> (which is either a Smi, a
27// strong reference to a HeapObject, a weak reference to a HeapObject, or a
28// cleared weak reference. This class provides storage and one canonical
29// implementation of various predicates that check Smi and heap object tags'
30// values and also take into account whether the tagged value is expected to be
31// weak reference to a HeapObject or cleared weak reference.
32template <HeapObjectReferenceType kRefType, typename StorageType>
34 public:
35 static_assert(std::is_same<StorageType, Address>::value ||
36 std::is_same<StorageType, Tagged_t>::value,
37 "StorageType must be either Address or Tagged_t");
38
39 // True for those TaggedImpl instantiations that represent uncompressed
40 // tagged values and false for TaggedImpl instantiations that represent
41 // compressed tagged values.
42 static const bool kIsFull = sizeof(StorageType) == kSystemPointerSize;
43
44 static const bool kCanBeWeak = kRefType == HeapObjectReferenceType::WEAK;
45
46 V8_INLINE constexpr TaggedImpl() : ptr_{} {}
47 V8_INLINE explicit constexpr TaggedImpl(StorageType ptr) : ptr_(ptr) {}
48
49 // Make clang on Linux catch what MSVC complains about on Windows:
50 explicit operator bool() const = delete;
51
52 // Don't use this operator for comparing with stale or invalid pointers
53 // because CheckObjectComparisonAllowed() might crash when trying to access
54 // the object's page header. Use SafeEquals() instead.
55 template <HeapObjectReferenceType kOtherRefType, typename U>
56 constexpr bool operator==(TaggedImpl<kOtherRefType, U> other) const {
57 static_assert(
58 std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
59 "U must be either Address or Tagged_t");
60#if defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
61 // When comparing two full pointer values ensure that it's allowed.
62 if (std::is_same<StorageType, Address>::value &&
63 std::is_same<U, Address>::value) {
64 SLOW_DCHECK(CheckObjectComparisonAllowed(ptr_, other.ptr()));
65 }
66#endif // defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
67 return static_cast<Tagged_t>(ptr_) == static_cast<Tagged_t>(other.ptr());
68 }
69
70 // Don't use this operator for comparing with stale or invalid pointers
71 // because CheckObjectComparisonAllowed() might crash when trying to access
72 // the object's page header. Use SafeEquals() instead.
73 template <HeapObjectReferenceType kOtherRefType, typename U>
74 constexpr bool operator!=(TaggedImpl<kOtherRefType, U> other) const {
75 static_assert(
76 std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
77 "U must be either Address or Tagged_t");
78#if defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
79 // When comparing two full pointer values ensure that it's allowed.
80 if (std::is_same<StorageType, Address>::value &&
81 std::is_same<U, Address>::value) {
82 SLOW_DCHECK(CheckObjectComparisonAllowed(ptr_, other.ptr()));
83 }
84#endif // defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
85 return static_cast<Tagged_t>(ptr_) != static_cast<Tagged_t>(other.ptr());
86 }
87
88 // A variant of operator== which allows comparing objects in different
89 // pointer compression cages. In particular, this should be used when
90 // comparing objects in trusted- or code space with objects in the main
91 // pointer compression cage.
92 template <HeapObjectReferenceType kOtherRefType>
93 constexpr bool SafeEquals(
95 static_assert(std::is_same<StorageType, Address>::value,
96 "Safe comparison is allowed only for full tagged values");
98 return ptr_ == other.ptr();
99 }
100 return this->operator==(other);
101 }
102
103 // For using in std::set and std::map.
104 constexpr bool operator<(TaggedImpl other) const {
105#if defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
106 // When comparing two full pointer values ensure that it's allowed.
107 if (std::is_same<StorageType, Address>::value) {
108 SLOW_DCHECK(CheckObjectComparisonAllowed(ptr_, other.ptr()));
109 }
110#endif // defined(V8_EXTERNAL_CODE_SPACE) || defined(V8_ENABLE_SANDBOX)
111 return static_cast<Tagged_t>(ptr_) < static_cast<Tagged_t>(other.ptr());
112 }
113
114 V8_INLINE constexpr StorageType ptr() const { return ptr_; }
115
116 // Returns true if this tagged value is a strong pointer to a HeapObject or
117 // Smi.
118 constexpr inline bool IsObject() const { return !IsWeakOrCleared(); }
119
120 // Returns true if this tagged value is a Smi.
121 constexpr bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
122 inline bool ToSmi(Tagged<Smi>* value) const;
123 inline Tagged<Smi> ToSmi() const;
124
125 // Returns true if this tagged value is a strong pointer to a HeapObject.
126 constexpr inline bool IsHeapObject() const { return IsStrong(); }
127
128 // Returns true if this tagged value is a cleared weak reference.
129 constexpr inline bool IsCleared() const {
130 return kCanBeWeak &&
131 (static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32);
132 }
133
134 // Returns true if this tagged value is a strong or weak pointer to a
135 // HeapObject.
136 constexpr inline bool IsStrongOrWeak() const {
137 return !IsSmi() && !IsCleared();
138 }
139
140 // Returns true if this tagged value is a strong pointer to a HeapObject.
141 constexpr inline bool IsStrong() const {
144 }
145
146 // Returns true if this tagged value is a strong pointer to a HeapObject, or a
147 // Smi.
148 constexpr inline bool IsStrongOrSmi() const {
150 }
151
152 // Returns true if this tagged value is a weak pointer to a HeapObject.
153 constexpr inline bool IsWeak() const {
154 return IsWeakOrCleared() && !IsCleared();
155 }
156
157 // Returns true if this tagged value is a weak pointer to a HeapObject or
158 // cleared weak reference.
159 constexpr inline bool IsWeakOrCleared() const {
161 }
162
163#ifdef V8_COMPRESS_POINTERS
164 // Returns true if this tagged value is a pointer to an object in the given
165 // cage base.
166 constexpr inline bool IsInMainCageBase() {
167 DCHECK(!IsSmi());
169 return S::GetPtrComprCageBaseAddress(ptr_) ==
170 S::GetPtrComprCageBaseAddress(S::base());
171 }
172#endif // V8_COMPRESS_POINTERS
173
174 //
175 // The following set of methods get HeapObject out of the tagged value
176 // which may involve decompression in which case the isolate root is required.
177 // If the pointer compression is not enabled then the variants with
178 // isolate parameter will be exactly the same as the ones witout isolate
179 // parameter.
180 //
181
182 // If this tagged value is a strong pointer to a HeapObject, returns true and
183 // sets *result. Otherwise returns false.
185 inline bool GetHeapObjectIfStrong(Isolate* isolate,
187
188 // DCHECKs that this tagged value is a strong pointer to a HeapObject and
189 // returns the HeapObject.
192
193 // If this tagged value is a weak pointer to a HeapObject, returns true and
194 // sets *result. Otherwise returns false.
196 inline bool GetHeapObjectIfWeak(Isolate* isolate,
198
199 // DCHECKs that this tagged value is a weak pointer to a HeapObject and
200 // returns the HeapObject.
203
204 // If this tagged value is a strong or weak pointer to a HeapObject, returns
205 // true and sets *result. Otherwise returns false.
206 inline bool GetHeapObject(Tagged<HeapObject>* result) const;
207 inline bool GetHeapObject(Isolate* isolate, Tagged<HeapObject>* result) const;
208
210 HeapObjectReferenceType* reference_type) const;
211 inline bool GetHeapObject(Isolate* isolate, Tagged<HeapObject>* result,
212 HeapObjectReferenceType* reference_type) const;
213
214 // DCHECKs that this tagged value is a strong or a weak pointer to a
215 // HeapObject and returns the HeapObject.
216 inline Tagged<HeapObject> GetHeapObject() const;
217 inline Tagged<HeapObject> GetHeapObject(Isolate* isolate) const;
218
219 // DCHECKs that this tagged value is a strong or a weak pointer to a
220 // HeapObject or a Smi and returns the HeapObject or Smi.
221 inline Tagged<Object> GetHeapObjectOrSmi() const;
222 inline Tagged<Object> GetHeapObjectOrSmi(Isolate* isolate) const;
223
224 // Cast operation is available only for full non-weak tagged values.
225 template <typename T>
231
232 protected:
233 StorageType* ptr_location() { return &ptr_; }
234 const StorageType* ptr_location() const { return &ptr_; }
235
236 private:
239 friend class FullObjectSlot;
241 friend class FullHeapObjectSlot;
242
243 StorageType ptr_;
244};
245
246// Prints this object without details.
247template <HeapObjectReferenceType kRefType, typename StorageType>
249void ShortPrint(TaggedImpl<kRefType, StorageType> ptr, FILE* out = stdout);
250
251// Prints this object without details to a message accumulator.
252template <HeapObjectReferenceType kRefType, typename StorageType>
255 StringStream* accumulator);
256
257template <HeapObjectReferenceType kRefType, typename StorageType>
259void ShortPrint(TaggedImpl<kRefType, StorageType> ptr, std::ostream& os);
260
261#ifdef OBJECT_PRINT
262template <HeapObjectReferenceType kRefType, typename StorageType>
265template <HeapObjectReferenceType kRefType, typename StorageType>
267void Print(TaggedImpl<kRefType, StorageType> ptr, std::ostream& os);
268#else
269template <HeapObjectReferenceType kRefType, typename StorageType>
273template <HeapObjectReferenceType kRefType, typename StorageType>
274void Print(TaggedImpl<kRefType, StorageType> ptr, std::ostream& os) {
275 ShortPrint(ptr, os);
276}
277#endif
278
279} // namespace internal
280} // namespace v8
281
282#endif // V8_OBJECTS_TAGGED_IMPL_H_
#define SLOW_DCHECK(condition)
Definition checks.h:21
V8_INLINE constexpr StorageType ptr() const
constexpr bool operator<(TaggedImpl other) const
bool GetHeapObjectIfStrong(Tagged< HeapObject > *result) const
constexpr bool IsStrong() const
constexpr bool SafeEquals(TaggedImpl< kOtherRefType, StorageType > other) const
Definition tagged-impl.h:93
friend class CompressedObjectSlot
Tagged< HeapObject > GetHeapObjectAssumeStrong() const
constexpr bool operator!=(TaggedImpl< kOtherRefType, U > other) const
Definition tagged-impl.h:74
constexpr bool IsStrongOrWeak() const
V8_INLINE constexpr TaggedImpl(StorageType ptr)
Definition tagged-impl.h:47
constexpr bool IsCleared() const
bool GetHeapObjectIfWeak(Tagged< HeapObject > *result) const
Tagged< Smi > ToSmi() const
V8_INLINE constexpr TaggedImpl()
Definition tagged-impl.h:46
friend class CompressedMaybeObjectSlot
Tagged< HeapObject > GetHeapObject() const
static const bool kCanBeWeak
Definition tagged-impl.h:44
constexpr bool operator==(TaggedImpl< kOtherRefType, U > other) const
Definition tagged-impl.h:56
const StorageType * ptr_location() const
static const bool kIsFull
Definition tagged-impl.h:42
constexpr bool IsWeak() const
constexpr bool IsSmi() const
StorageType * ptr_location()
constexpr bool IsWeakOrCleared() const
constexpr bool IsObject() const
Tagged< Object > GetHeapObjectOrSmi() const
Tagged< T > cast() const
constexpr bool IsStrongOrSmi() const
constexpr bool IsHeapObject() const
Tagged< HeapObject > GetHeapObjectAssumeWeak() const
#define HAS_STRONG_HEAP_OBJECT_TAG(value)
Definition globals.h:1774
#define V8_EXTERNAL_CODE_SPACE_BOOL
Definition globals.h:255
#define HAS_SMI_TAG(value)
Definition globals.h:1771
#define V8_ENABLE_SANDBOX_BOOL
Definition globals.h:160
#define HAS_WEAK_HEAP_OBJECT_TAG(value)
Definition globals.h:1778
#define EXPORT_TEMPLATE_DECLARE(export)
ZoneVector< RpoNumber > & result
kInterpreterTrampolineOffset Tagged< HeapObject >
Address Tagged_t
Definition globals.h:547
void Print(Tagged< Object > obj)
Definition objects.h:774
constexpr int kSystemPointerSize
Definition globals.h:410
constexpr int S
void ShortPrint(Tagged< Object > obj, FILE *out)
Definition objects.cc:1865
const uint32_t kClearedWeakHeapObjectLower32
Definition globals.h:981
V8HeapCompressionSchemeImpl< MainCage > V8HeapCompressionScheme
Definition globals.h:1137
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define CHECK(condition)
Definition logging.h:124
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_INLINE
Definition v8config.h:500