Home | History | Annotate | Download | only in objects
      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.h"
      9 #include "src/globals.h"
     10 #include "src/objects.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 class HeapObject;
     16 class Smi;
     17 class StringStream;
     18 
     19 // A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak
     20 // reference to a HeapObject, or a cleared weak reference. It's used for
     21 // implementing in-place weak references (see design doc: goo.gl/j6SdcK )
     22 class MaybeObject {
     23  public:
     24   bool IsSmi() const { return HAS_SMI_TAG(this); }
     25   inline bool ToSmi(Smi** value);
     26   inline Smi* ToSmi();
     27 
     28   bool IsClearedWeakHeapObject() const {
     29     return ::v8::internal::IsClearedWeakHeapObject(this);
     30   }
     31 
     32   inline bool IsStrongOrWeakHeapObject() const;
     33   inline bool ToStrongOrWeakHeapObject(HeapObject** result);
     34   inline bool ToStrongOrWeakHeapObject(HeapObject** result,
     35                                        HeapObjectReferenceType* reference_type);
     36   inline bool IsStrongHeapObject() const;
     37   inline bool ToStrongHeapObject(HeapObject** result);
     38   inline HeapObject* ToStrongHeapObject();
     39   inline bool IsWeakHeapObject() const;
     40   inline bool IsWeakOrClearedHeapObject() const;
     41   inline bool ToWeakHeapObject(HeapObject** result);
     42   inline HeapObject* ToWeakHeapObject();
     43 
     44   // Returns the HeapObject pointed to (either strongly or weakly).
     45   inline HeapObject* GetHeapObject();
     46   inline Object* GetHeapObjectOrSmi();
     47 
     48   inline bool IsObject() const;
     49   inline Object* ToObject();
     50 
     51   static MaybeObject* FromSmi(Smi* smi) {
     52     DCHECK(HAS_SMI_TAG(smi));
     53     return reinterpret_cast<MaybeObject*>(smi);
     54   }
     55 
     56   static MaybeObject* FromObject(Object* object) {
     57     DCHECK(!HasWeakHeapObjectTag(object));
     58     return reinterpret_cast<MaybeObject*>(object);
     59   }
     60 
     61   static inline MaybeObject* MakeWeak(MaybeObject* object);
     62 
     63 #ifdef VERIFY_HEAP
     64   static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject* p);
     65 #endif
     66 
     67   // Prints this object without details.
     68   void ShortPrint(FILE* out = stdout);
     69 
     70   // Prints this object without details to a message accumulator.
     71   void ShortPrint(StringStream* accumulator);
     72 
     73   void ShortPrint(std::ostream& os);
     74 
     75 #ifdef OBJECT_PRINT
     76   void Print();
     77   void Print(std::ostream& os);
     78 #else
     79   void Print() { ShortPrint(); }
     80   void Print(std::ostream& os) { ShortPrint(os); }
     81 #endif
     82 
     83  private:
     84   DISALLOW_IMPLICIT_CONSTRUCTORS(MaybeObject);
     85 };
     86 
     87 // A HeapObjectReference is either a strong reference to a HeapObject, a weak
     88 // reference to a HeapObject, or a cleared weak reference.
     89 class HeapObjectReference : public MaybeObject {
     90  public:
     91   static HeapObjectReference* Strong(Object* object) {
     92     DCHECK(!object->IsSmi());
     93     DCHECK(!HasWeakHeapObjectTag(object));
     94     return reinterpret_cast<HeapObjectReference*>(object);
     95   }
     96 
     97   static HeapObjectReference* Weak(Object* object) {
     98     DCHECK(!object->IsSmi());
     99     DCHECK(!HasWeakHeapObjectTag(object));
    100     return AddWeakHeapObjectMask(object);
    101   }
    102 
    103   static HeapObjectReference* ClearedValue() {
    104     return reinterpret_cast<HeapObjectReference*>(kClearedWeakHeapObject);
    105   }
    106 
    107   static void Update(HeapObjectReference** slot, HeapObject* value) {
    108     DCHECK(!HAS_SMI_TAG(*slot));
    109     DCHECK(Internals::HasHeapObjectTag(value));
    110 
    111 #ifdef DEBUG
    112     bool weak_before = HasWeakHeapObjectTag(*slot);
    113 #endif
    114 
    115     *slot = reinterpret_cast<HeapObjectReference*>(
    116         reinterpret_cast<intptr_t>(value) |
    117         (reinterpret_cast<intptr_t>(*slot) & kWeakHeapObjectMask));
    118 
    119 #ifdef DEBUG
    120     bool weak_after = HasWeakHeapObjectTag(*slot);
    121     DCHECK_EQ(weak_before, weak_after);
    122 #endif
    123   }
    124 
    125  private:
    126   DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObjectReference);
    127 };
    128 
    129 }  // namespace internal
    130 }  // namespace v8
    131 
    132 #endif  // V8_OBJECTS_MAYBE_OBJECT_H_
    133