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