Line data Source code
1 : // Copyright 2018 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_MAYBE_OBJECT_H_
6 : #define V8_OBJECTS_MAYBE_OBJECT_H_
7 :
8 : #include "include/v8-internal.h"
9 : #include "include/v8.h"
10 : #include "src/globals.h"
11 : #include "src/objects.h"
12 : #include "src/objects/smi.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : class HeapObject;
18 : class Isolate;
19 : class StringStream;
20 :
21 : // A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak
22 : // reference to a HeapObject, or a cleared weak reference. It's used for
23 : // implementing in-place weak references (see design doc: goo.gl/j6SdcK )
24 : class MaybeObject {
25 : public:
26 190448025 : MaybeObject() : ptr_(kNullAddress) {}
27 : explicit MaybeObject(Address ptr) : ptr_(ptr) {}
28 :
29 63333434 : bool operator==(const MaybeObject& other) const { return ptr_ == other.ptr_; }
30 5655893 : bool operator!=(const MaybeObject& other) const { return ptr_ != other.ptr_; }
31 :
32 55279208 : Address ptr() const { return ptr_; }
33 :
34 : // Enable incremental transition of client code.
35 : MaybeObject* operator->() { return this; }
36 889 : const MaybeObject* operator->() const { return this; }
37 :
38 4610641370 : bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
39 : inline bool ToSmi(Smi* value);
40 : inline Smi ToSmi() const;
41 :
42 : bool IsCleared() const {
43 1469372374 : return static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32;
44 : }
45 :
46 : inline bool IsStrongOrWeak() const;
47 : inline bool IsStrong() const;
48 :
49 : // If this MaybeObject is a strong pointer to a HeapObject, returns true and
50 : // sets *result. Otherwise returns false.
51 : inline bool GetHeapObjectIfStrong(HeapObject* result) const;
52 :
53 : // DCHECKs that this MaybeObject is a strong pointer to a HeapObject and
54 : // returns the HeapObject.
55 : inline HeapObject GetHeapObjectAssumeStrong() const;
56 :
57 : inline bool IsWeak() const;
58 : inline bool IsWeakOrCleared() const;
59 :
60 : // If this MaybeObject is a weak pointer to a HeapObject, returns true and
61 : // sets *result. Otherwise returns false.
62 : inline bool GetHeapObjectIfWeak(HeapObject* result) const;
63 :
64 : // DCHECKs that this MaybeObject is a weak pointer to a HeapObject and
65 : // returns the HeapObject.
66 : inline HeapObject GetHeapObjectAssumeWeak() const;
67 :
68 : // If this MaybeObject is a strong or weak pointer to a HeapObject, returns
69 : // true and sets *result. Otherwise returns false.
70 : inline bool GetHeapObject(HeapObject* result) const;
71 : inline bool GetHeapObject(HeapObject* result,
72 : HeapObjectReferenceType* reference_type) const;
73 :
74 : // DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject
75 : // and returns the HeapObject.
76 : inline HeapObject GetHeapObject() const;
77 :
78 : // DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject
79 : // or a SMI and returns the HeapObject or SMI.
80 : inline Object GetHeapObjectOrSmi() const;
81 :
82 : inline bool IsObject() const;
83 : template <typename T>
84 : T cast() const {
85 : DCHECK(!HasWeakHeapObjectTag(ptr_));
86 36749758 : return T::cast(Object(ptr_));
87 : }
88 :
89 : static MaybeObject FromSmi(Smi smi) {
90 : DCHECK(HAS_SMI_TAG(smi->ptr()));
91 : return MaybeObject(smi->ptr());
92 : }
93 :
94 313312 : static MaybeObject FromObject(Object object) {
95 : DCHECK(!HasWeakHeapObjectTag(object.ptr()));
96 313312 : return MaybeObject(object.ptr());
97 : }
98 :
99 : static inline MaybeObject MakeWeak(MaybeObject object);
100 :
101 : #ifdef VERIFY_HEAP
102 : static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p);
103 : #endif
104 :
105 : // Prints this object without details.
106 : void ShortPrint(FILE* out = stdout);
107 :
108 : // Prints this object without details to a message accumulator.
109 : void ShortPrint(StringStream* accumulator);
110 :
111 : void ShortPrint(std::ostream& os);
112 :
113 : #ifdef OBJECT_PRINT
114 : void Print();
115 : void Print(std::ostream& os);
116 : #else
117 : void Print() { ShortPrint(); }
118 : void Print(std::ostream& os) { ShortPrint(os); }
119 : #endif
120 :
121 : private:
122 : Address ptr_;
123 : };
124 :
125 : // A HeapObjectReference is either a strong reference to a HeapObject, a weak
126 : // reference to a HeapObject, or a cleared weak reference.
127 : class HeapObjectReference : public MaybeObject {
128 : public:
129 : explicit HeapObjectReference(Address address) : MaybeObject(address) {}
130 : explicit HeapObjectReference(Object object) : MaybeObject(object->ptr()) {}
131 :
132 : static HeapObjectReference Strong(Object object) {
133 : DCHECK(!object->IsSmi());
134 : DCHECK(!HasWeakHeapObjectTag(object));
135 : return HeapObjectReference(object);
136 : }
137 :
138 : static HeapObjectReference Weak(Object object) {
139 : DCHECK(!object->IsSmi());
140 : DCHECK(!HasWeakHeapObjectTag(object));
141 152836460 : return HeapObjectReference(object->ptr() | kWeakHeapObjectMask);
142 : }
143 :
144 : V8_INLINE static HeapObjectReference ClearedValue(Isolate* isolate);
145 :
146 : template <typename THeapObjectSlot>
147 : V8_INLINE static void Update(THeapObjectSlot slot, HeapObject value);
148 : };
149 :
150 : } // namespace internal
151 : } // namespace v8
152 :
153 : #endif // V8_OBJECTS_MAYBE_OBJECT_H_
|