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_INL_H_ |
6 | #define V8_OBJECTS_MAYBE_OBJECT_INL_H_ |
7 | |
8 | #include "src/objects/maybe-object.h" |
9 | |
10 | #ifdef V8_COMPRESS_POINTERS |
11 | #include "src/isolate.h" |
12 | #endif |
13 | #include "src/objects/heap-object-inl.h" |
14 | #include "src/objects/slots-inl.h" |
15 | #include "src/objects/smi-inl.h" |
16 | |
17 | namespace v8 { |
18 | namespace internal { |
19 | |
20 | bool MaybeObject::ToSmi(Smi* value) { |
21 | if (HAS_SMI_TAG(ptr_)) { |
22 | *value = Smi::cast(Object(ptr_)); |
23 | return true; |
24 | } |
25 | return false; |
26 | } |
27 | |
28 | Smi MaybeObject::ToSmi() const { |
29 | DCHECK(HAS_SMI_TAG(ptr_)); |
30 | return Smi::cast(Object(ptr_)); |
31 | } |
32 | |
33 | bool MaybeObject::IsStrongOrWeak() const { |
34 | if (IsSmi() || IsCleared()) { |
35 | return false; |
36 | } |
37 | return true; |
38 | } |
39 | |
40 | bool MaybeObject::GetHeapObject(HeapObject* result) const { |
41 | if (IsSmi() || IsCleared()) { |
42 | return false; |
43 | } |
44 | *result = GetHeapObject(); |
45 | return true; |
46 | } |
47 | |
48 | bool MaybeObject::GetHeapObject(HeapObject* result, |
49 | HeapObjectReferenceType* reference_type) const { |
50 | if (IsSmi() || IsCleared()) { |
51 | return false; |
52 | } |
53 | *reference_type = HasWeakHeapObjectTag(ptr_) |
54 | ? HeapObjectReferenceType::WEAK |
55 | : HeapObjectReferenceType::STRONG; |
56 | *result = GetHeapObject(); |
57 | return true; |
58 | } |
59 | |
60 | bool MaybeObject::IsStrong() const { |
61 | return !HasWeakHeapObjectTag(ptr_) && !IsSmi(); |
62 | } |
63 | |
64 | bool MaybeObject::GetHeapObjectIfStrong(HeapObject* result) const { |
65 | if (!HasWeakHeapObjectTag(ptr_) && !IsSmi()) { |
66 | *result = HeapObject::cast(Object(ptr_)); |
67 | return true; |
68 | } |
69 | return false; |
70 | } |
71 | |
72 | HeapObject MaybeObject::GetHeapObjectAssumeStrong() const { |
73 | DCHECK(IsStrong()); |
74 | return HeapObject::cast(Object(ptr_)); |
75 | } |
76 | |
77 | bool MaybeObject::IsWeak() const { |
78 | return HasWeakHeapObjectTag(ptr_) && !IsCleared(); |
79 | } |
80 | |
81 | bool MaybeObject::IsWeakOrCleared() const { return HasWeakHeapObjectTag(ptr_); } |
82 | |
83 | bool MaybeObject::GetHeapObjectIfWeak(HeapObject* result) const { |
84 | if (IsWeak()) { |
85 | *result = GetHeapObject(); |
86 | return true; |
87 | } |
88 | return false; |
89 | } |
90 | |
91 | HeapObject MaybeObject::GetHeapObjectAssumeWeak() const { |
92 | DCHECK(IsWeak()); |
93 | return GetHeapObject(); |
94 | } |
95 | |
96 | HeapObject MaybeObject::GetHeapObject() const { |
97 | DCHECK(!IsSmi()); |
98 | DCHECK(!IsCleared()); |
99 | return HeapObject::cast(Object(ptr_ & ~kWeakHeapObjectMask)); |
100 | } |
101 | |
102 | Object MaybeObject::GetHeapObjectOrSmi() const { |
103 | if (IsSmi()) { |
104 | return Object(ptr_); |
105 | } |
106 | return GetHeapObject(); |
107 | } |
108 | |
109 | bool MaybeObject::IsObject() const { return IsSmi() || IsStrong(); } |
110 | |
111 | MaybeObject MaybeObject::MakeWeak(MaybeObject object) { |
112 | DCHECK(object.IsStrongOrWeak()); |
113 | return MaybeObject(object.ptr_ | kWeakHeapObjectMask); |
114 | } |
115 | |
116 | // static |
117 | HeapObjectReference HeapObjectReference::ClearedValue(Isolate* isolate) { |
118 | // Construct cleared weak ref value. |
119 | Address raw_value = kClearedWeakHeapObjectLower32; |
120 | #ifdef V8_COMPRESS_POINTERS |
121 | // This is necessary to make pointer decompression computation also |
122 | // suitable for cleared weak references. |
123 | Address isolate_root = isolate->isolate_root(); |
124 | raw_value |= isolate_root; |
125 | DCHECK_EQ(raw_value & (~static_cast<Address>(kClearedWeakHeapObjectLower32)), |
126 | isolate_root); |
127 | #endif |
128 | // The rest of the code will check only the lower 32-bits. |
129 | DCHECK_EQ(kClearedWeakHeapObjectLower32, static_cast<uint32_t>(raw_value)); |
130 | return HeapObjectReference(raw_value); |
131 | } |
132 | |
133 | template <typename THeapObjectSlot> |
134 | void HeapObjectReference::Update(THeapObjectSlot slot, HeapObject value) { |
135 | static_assert(std::is_same<THeapObjectSlot, FullHeapObjectSlot>::value || |
136 | std::is_same<THeapObjectSlot, HeapObjectSlot>::value, |
137 | "Only FullHeapObjectSlot and HeapObjectSlot are expected here"); |
138 | Address old_value = (*slot).ptr(); |
139 | DCHECK(!HAS_SMI_TAG(old_value)); |
140 | Address new_value = value->ptr(); |
141 | DCHECK(Internals::HasHeapObjectTag(new_value)); |
142 | |
143 | #ifdef DEBUG |
144 | bool weak_before = HasWeakHeapObjectTag(old_value); |
145 | #endif |
146 | |
147 | slot.store( |
148 | HeapObjectReference(new_value | (old_value & kWeakHeapObjectMask))); |
149 | |
150 | #ifdef DEBUG |
151 | bool weak_after = HasWeakHeapObjectTag((*slot).ptr()); |
152 | DCHECK_EQ(weak_before, weak_after); |
153 | #endif |
154 | } |
155 | |
156 | } // namespace internal |
157 | } // namespace v8 |
158 | |
159 | #endif // V8_OBJECTS_MAYBE_OBJECT_INL_H_ |
160 |