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/common/ptr-compr-inl.h"
9 #include "src/objects/maybe-object.h"
10 #include "src/objects/smi-inl.h"
11 #include "src/objects/tagged-impl-inl.h"
12
13 namespace v8 {
14 namespace internal {
15
16 //
17 // MaybeObject implementation.
18 //
19
20 // static
FromSmi(Smi smi)21 MaybeObject MaybeObject::FromSmi(Smi smi) {
22 DCHECK(HAS_SMI_TAG(smi.ptr()));
23 return MaybeObject(smi.ptr());
24 }
25
26 // static
FromObject(Object object)27 MaybeObject MaybeObject::FromObject(Object object) {
28 DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(object.ptr()));
29 return MaybeObject(object.ptr());
30 }
31
MakeWeak(MaybeObject object)32 MaybeObject MaybeObject::MakeWeak(MaybeObject object) {
33 DCHECK(object.IsStrongOrWeak());
34 return MaybeObject(object.ptr() | kWeakHeapObjectMask);
35 }
36
37 // static
Create(MaybeObject o)38 MaybeObject MaybeObject::Create(MaybeObject o) { return o; }
39
40 // static
Create(Object o)41 MaybeObject MaybeObject::Create(Object o) { return FromObject(o); }
42
43 // static
Create(Smi smi)44 MaybeObject MaybeObject::Create(Smi smi) { return FromSmi(smi); }
45
46 //
47 // HeapObjectReference implementation.
48 //
49
HeapObjectReference(Object object)50 HeapObjectReference::HeapObjectReference(Object object)
51 : MaybeObject(object.ptr()) {}
52
53 // static
Strong(Object object)54 HeapObjectReference HeapObjectReference::Strong(Object object) {
55 DCHECK(!object.IsSmi());
56 DCHECK(!HasWeakHeapObjectTag(object));
57 return HeapObjectReference(object);
58 }
59
60 // static
Weak(Object object)61 HeapObjectReference HeapObjectReference::Weak(Object object) {
62 DCHECK(!object.IsSmi());
63 DCHECK(!HasWeakHeapObjectTag(object));
64 return HeapObjectReference(object.ptr() | kWeakHeapObjectMask);
65 }
66
67 // static
From(Object object,HeapObjectReferenceType type)68 HeapObjectReference HeapObjectReference::From(Object object,
69 HeapObjectReferenceType type) {
70 DCHECK(!object.IsSmi());
71 DCHECK(!HasWeakHeapObjectTag(object));
72 switch (type) {
73 case HeapObjectReferenceType::STRONG:
74 return HeapObjectReference::Strong(object);
75 case HeapObjectReferenceType::WEAK:
76 return HeapObjectReference::Weak(object);
77 }
78 }
79
80 // static
ClearedValue(PtrComprCageBase cage_base)81 HeapObjectReference HeapObjectReference::ClearedValue(
82 PtrComprCageBase cage_base) {
83 // Construct cleared weak ref value.
84 #ifdef V8_COMPRESS_POINTERS
85 // This is necessary to make pointer decompression computation also
86 // suitable for cleared weak references.
87 Address raw_value =
88 DecompressTaggedPointer(cage_base, kClearedWeakHeapObjectLower32);
89 #else
90 Address raw_value = kClearedWeakHeapObjectLower32;
91 #endif
92 // The rest of the code will check only the lower 32-bits.
93 DCHECK_EQ(kClearedWeakHeapObjectLower32, static_cast<uint32_t>(raw_value));
94 return HeapObjectReference(raw_value);
95 }
96
97 template <typename THeapObjectSlot>
Update(THeapObjectSlot slot,HeapObject value)98 void HeapObjectReference::Update(THeapObjectSlot slot, HeapObject value) {
99 static_assert(std::is_same<THeapObjectSlot, FullHeapObjectSlot>::value ||
100 std::is_same<THeapObjectSlot, HeapObjectSlot>::value,
101 "Only FullHeapObjectSlot and HeapObjectSlot are expected here");
102 Address old_value = (*slot).ptr();
103 DCHECK(!HAS_SMI_TAG(old_value));
104 Address new_value = value.ptr();
105 DCHECK(Internals::HasHeapObjectTag(new_value));
106
107 #ifdef DEBUG
108 bool weak_before = HAS_WEAK_HEAP_OBJECT_TAG(old_value);
109 #endif
110
111 slot.store(
112 HeapObjectReference(new_value | (old_value & kWeakHeapObjectMask)));
113
114 #ifdef DEBUG
115 bool weak_after = HAS_WEAK_HEAP_OBJECT_TAG((*slot).ptr());
116 DCHECK_EQ(weak_before, weak_after);
117 #endif
118 }
119
120 } // namespace internal
121 } // namespace v8
122
123 #endif // V8_OBJECTS_MAYBE_OBJECT_INL_H_
124