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