| // Copyright 2018 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_OBJECTS_MAYBE_OBJECT_H_ | |
| #define V8_OBJECTS_MAYBE_OBJECT_H_ | |
| #include "include/v8.h" | |
| #include "src/globals.h" | |
| #include "src/objects.h" | |
| namespace v8 { | |
| namespace internal { | |
| class HeapObject; | |
| class Smi; | |
| class StringStream; | |
| // A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak | |
| // reference to a HeapObject, or a cleared weak reference. It's used for | |
| // implementing in-place weak references (see design doc: goo.gl/j6SdcK ) | |
| class MaybeObject { | |
| public: | |
| bool IsSmi() const { return HAS_SMI_TAG(this); } | |
| inline bool ToSmi(Smi** value); | |
| inline Smi* ToSmi(); | |
| bool IsClearedWeakHeapObject() const { | |
| return ::v8::internal::IsClearedWeakHeapObject(this); | |
| } | |
| inline bool IsStrongOrWeakHeapObject() const; | |
| inline bool ToStrongOrWeakHeapObject(HeapObject** result); | |
| inline bool ToStrongOrWeakHeapObject(HeapObject** result, | |
| HeapObjectReferenceType* reference_type); | |
| inline bool IsStrongHeapObject() const; | |
| inline bool ToStrongHeapObject(HeapObject** result); | |
| inline HeapObject* ToStrongHeapObject(); | |
| inline bool IsWeakHeapObject() const; | |
| inline bool IsWeakOrClearedHeapObject() const; | |
| inline bool ToWeakHeapObject(HeapObject** result); | |
| inline HeapObject* ToWeakHeapObject(); | |
| // Returns the HeapObject pointed to (either strongly or weakly). | |
| inline HeapObject* GetHeapObject(); | |
| inline Object* GetHeapObjectOrSmi(); | |
| inline bool IsObject() const; | |
| inline Object* ToObject(); | |
| static MaybeObject* FromSmi(Smi* smi) { | |
| DCHECK(HAS_SMI_TAG(smi)); | |
| return reinterpret_cast<MaybeObject*>(smi); | |
| } | |
| static MaybeObject* FromObject(Object* object) { | |
| DCHECK(!HasWeakHeapObjectTag(object)); | |
| return reinterpret_cast<MaybeObject*>(object); | |
| } | |
| static inline MaybeObject* MakeWeak(MaybeObject* object); | |
| #ifdef VERIFY_HEAP | |
| static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject* p); | |
| #endif | |
| // Prints this object without details. | |
| void ShortPrint(FILE* out = stdout); | |
| // Prints this object without details to a message accumulator. | |
| void ShortPrint(StringStream* accumulator); | |
| void ShortPrint(std::ostream& os); | |
| #ifdef OBJECT_PRINT | |
| void Print(); | |
| void Print(std::ostream& os); | |
| #else | |
| void Print() { ShortPrint(); } | |
| void Print(std::ostream& os) { ShortPrint(os); } | |
| #endif | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(MaybeObject); | |
| }; | |
| // A HeapObjectReference is either a strong reference to a HeapObject, a weak | |
| // reference to a HeapObject, or a cleared weak reference. | |
| class HeapObjectReference : public MaybeObject { | |
| public: | |
| static HeapObjectReference* Strong(Object* object) { | |
| DCHECK(!object->IsSmi()); | |
| DCHECK(!HasWeakHeapObjectTag(object)); | |
| return reinterpret_cast<HeapObjectReference*>(object); | |
| } | |
| static HeapObjectReference* Weak(Object* object) { | |
| DCHECK(!object->IsSmi()); | |
| DCHECK(!HasWeakHeapObjectTag(object)); | |
| return AddWeakHeapObjectMask(object); | |
| } | |
| static HeapObjectReference* ClearedValue() { | |
| return reinterpret_cast<HeapObjectReference*>(kClearedWeakHeapObject); | |
| } | |
| static void Update(HeapObjectReference** slot, HeapObject* value) { | |
| DCHECK(!HAS_SMI_TAG(*slot)); | |
| DCHECK(Internals::HasHeapObjectTag(value)); | |
| #ifdef DEBUG | |
| bool weak_before = HasWeakHeapObjectTag(*slot); | |
| #endif | |
| *slot = reinterpret_cast<HeapObjectReference*>( | |
| reinterpret_cast<intptr_t>(value) | | |
| (reinterpret_cast<intptr_t>(*slot) & kWeakHeapObjectMask)); | |
| #ifdef DEBUG | |
| bool weak_after = HasWeakHeapObjectTag(*slot); | |
| DCHECK_EQ(weak_before, weak_after); | |
| #endif | |
| } | |
| private: | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObjectReference); | |
| }; | |
| } // namespace internal | |
| } // namespace v8 | |
| #endif // V8_OBJECTS_MAYBE_OBJECT_H_ |