• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "include/v8-internal.h"
9 #include "include/v8.h"
10 #include "src/common/globals.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // An TaggedImpl is a base class for Object (which is either a Smi or a strong
16 // reference to a HeapObject) and MaybeObject (which is either a Smi, a strong
17 // reference to a HeapObject, a weak reference to a HeapObject, or a cleared
18 // weak reference.
19 // This class provides storage and one canonical implementation of various
20 // predicates that check Smi and heap object tags' values and also take into
21 // account whether the tagged value is expected to be weak reference to a
22 // HeapObject or cleared weak reference.
23 template <HeapObjectReferenceType kRefType, typename StorageType>
24 class TaggedImpl {
25  public:
26   static_assert(std::is_same<StorageType, Address>::value ||
27                     std::is_same<StorageType, Tagged_t>::value,
28                 "StorageType must be either Address or Tagged_t");
29 
30   // True for those TaggedImpl instantiations that represent uncompressed
31   // tagged values and false for TaggedImpl instantiations that represent
32   // compressed tagged values.
33   static const bool kIsFull = sizeof(StorageType) == kSystemPointerSize;
34 
35   static const bool kCanBeWeak = kRefType == HeapObjectReferenceType::WEAK;
36 
TaggedImpl()37   constexpr TaggedImpl() : ptr_{} {}
TaggedImpl(StorageType ptr)38   explicit constexpr TaggedImpl(StorageType ptr) : ptr_(ptr) {}
39 
40   // Make clang on Linux catch what MSVC complains about on Windows:
41   operator bool() const = delete;
42 
43   template <typename U>
44   constexpr bool operator==(TaggedImpl<kRefType, U> other) const {
45     static_assert(
46         std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
47         "U must be either Address or Tagged_t");
48     return static_cast<Tagged_t>(ptr_) == static_cast<Tagged_t>(other.ptr());
49   }
50   template <typename U>
51   constexpr bool operator!=(TaggedImpl<kRefType, U> other) const {
52     static_assert(
53         std::is_same<U, Address>::value || std::is_same<U, Tagged_t>::value,
54         "U must be either Address or Tagged_t");
55     return static_cast<Tagged_t>(ptr_) != static_cast<Tagged_t>(other.ptr());
56   }
57 
58   // For using in std::set and std::map.
59   constexpr bool operator<(TaggedImpl other) const {
60     return static_cast<Tagged_t>(ptr_) < static_cast<Tagged_t>(other.ptr());
61   }
62 
ptr()63   constexpr StorageType ptr() const { return ptr_; }
64 
65   // Returns true if this tagged value is a strong pointer to a HeapObject or
66   // Smi.
IsObject()67   constexpr inline bool IsObject() const { return !IsWeakOrCleared(); }
68 
69   // Returns true if this tagged value is a Smi.
IsSmi()70   constexpr bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
71   inline bool ToSmi(Smi* value) const;
72   inline Smi ToSmi() const;
73 
74   // Returns true if this tagged value is a strong pointer to a HeapObject.
IsHeapObject()75   constexpr inline bool IsHeapObject() const { return IsStrong(); }
76 
77   // Returns true if this tagged value is a cleared weak reference.
IsCleared()78   constexpr inline bool IsCleared() const {
79     return kCanBeWeak &&
80            (static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32);
81   }
82 
83   // Returns true if this tagged value is a strong or weak pointer to a
84   // HeapObject.
IsStrongOrWeak()85   constexpr inline bool IsStrongOrWeak() const {
86     return !IsSmi() && !IsCleared();
87   }
88 
89   // Returns true if this tagged value is a strong pointer to a HeapObject.
IsStrong()90   constexpr inline bool IsStrong() const {
91     CONSTEXPR_DCHECK(kCanBeWeak ||
92                      (!IsSmi() == HAS_STRONG_HEAP_OBJECT_TAG(ptr_)));
93     return kCanBeWeak ? HAS_STRONG_HEAP_OBJECT_TAG(ptr_) : !IsSmi();
94   }
95 
96   // Returns true if this tagged value is a weak pointer to a HeapObject.
IsWeak()97   constexpr inline bool IsWeak() const {
98     return IsWeakOrCleared() && !IsCleared();
99   }
100 
101   // Returns true if this tagged value is a weak pointer to a HeapObject or
102   // cleared weak reference.
IsWeakOrCleared()103   constexpr inline bool IsWeakOrCleared() const {
104     return kCanBeWeak && HAS_WEAK_HEAP_OBJECT_TAG(ptr_);
105   }
106 
107   //
108   // The following set of methods get HeapObject out of the tagged value
109   // which may involve decompression in which case the isolate root is required.
110   // If the pointer compression is not enabled then the variants with
111   // isolate parameter will be exactly the same as the ones witout isolate
112   // parameter.
113   //
114 
115   // If this tagged value is a strong pointer to a HeapObject, returns true and
116   // sets *result. Otherwise returns false.
117   inline bool GetHeapObjectIfStrong(HeapObject* result) const;
118   inline bool GetHeapObjectIfStrong(Isolate* isolate, HeapObject* result) const;
119 
120   // DCHECKs that this tagged value is a strong pointer to a HeapObject and
121   // returns the HeapObject.
122   inline HeapObject GetHeapObjectAssumeStrong() const;
123   inline HeapObject GetHeapObjectAssumeStrong(Isolate* isolate) const;
124 
125   // If this tagged value is a weak pointer to a HeapObject, returns true and
126   // sets *result. Otherwise returns false.
127   inline bool GetHeapObjectIfWeak(HeapObject* result) const;
128   inline bool GetHeapObjectIfWeak(Isolate* isolate, HeapObject* result) const;
129 
130   // DCHECKs that this tagged value is a weak pointer to a HeapObject and
131   // returns the HeapObject.
132   inline HeapObject GetHeapObjectAssumeWeak() const;
133   inline HeapObject GetHeapObjectAssumeWeak(Isolate* isolate) const;
134 
135   // If this tagged value is a strong or weak pointer to a HeapObject, returns
136   // true and sets *result. Otherwise returns false.
137   inline bool GetHeapObject(HeapObject* result) const;
138   inline bool GetHeapObject(Isolate* isolate, HeapObject* result) const;
139 
140   inline bool GetHeapObject(HeapObject* result,
141                             HeapObjectReferenceType* reference_type) const;
142   inline bool GetHeapObject(Isolate* isolate, HeapObject* result,
143                             HeapObjectReferenceType* reference_type) const;
144 
145   // DCHECKs that this tagged value is a strong or a weak pointer to a
146   // HeapObject and returns the HeapObject.
147   inline HeapObject GetHeapObject() const;
148   inline HeapObject GetHeapObject(Isolate* isolate) const;
149 
150   // DCHECKs that this tagged value is a strong or a weak pointer to a
151   // HeapObject or a Smi and returns the HeapObject or Smi.
152   inline Object GetHeapObjectOrSmi() const;
153   inline Object GetHeapObjectOrSmi(Isolate* isolate) const;
154 
155   // Cast operation is available only for full non-weak tagged values.
156   template <typename T>
cast()157   T cast() const {
158     CHECK(kIsFull);
159     DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
160     return T::cast(Object(ptr_));
161   }
162 
163   // Prints this object without details.
164   void ShortPrint(FILE* out = stdout);
165 
166   // Prints this object without details to a message accumulator.
167   void ShortPrint(StringStream* accumulator);
168 
169   void ShortPrint(std::ostream& os);
170 
171 #ifdef OBJECT_PRINT
172   void Print();
173   void Print(std::ostream& os);
174 #else
Print()175   void Print() { ShortPrint(); }
Print(std::ostream & os)176   void Print(std::ostream& os) { ShortPrint(os); }
177 #endif
178 
179  private:
180   friend class CompressedObjectSlot;
181   friend class FullObjectSlot;
182 
183   StorageType ptr_;
184 };
185 
186 }  // namespace internal
187 }  // namespace v8
188 
189 #endif  // V8_OBJECTS_TAGGED_IMPL_H_
190