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_HEAP_OBJECT_H_ 6 #define V8_OBJECTS_HEAP_OBJECT_H_ 7 8 #include "src/common/globals.h" 9 #include "src/objects/instance-type.h" 10 #include "src/objects/objects.h" 11 #include "src/objects/tagged-field.h" 12 #include "src/roots/roots.h" 13 #include "src/torque/runtime-macro-shims.h" 14 #include "src/torque/runtime-support.h" 15 16 // Has to be the last include (doesn't have include guards): 17 #include "src/objects/object-macros.h" 18 19 namespace v8 { 20 namespace internal { 21 22 class Heap; 23 class PrimitiveHeapObject; 24 25 // HeapObject is the superclass for all classes describing heap allocated 26 // objects. 27 class HeapObject : public Object { 28 public: is_null()29 bool is_null() const { 30 return static_cast<Tagged_t>(ptr()) == static_cast<Tagged_t>(kNullAddress); 31 } 32 33 // [map]: Contains a map which contains the object's reflective 34 // information. 35 DECL_GETTER(map, Map) 36 inline void set_map(Map value); 37 38 // This method behaves the same as `set_map` but marks the map transition as 39 // safe for the concurrent marker (object layout doesn't change) during 40 // verification. 41 inline void set_map_safe_transition(Map value); 42 43 inline ObjectSlot map_slot() const; 44 45 // The no-write-barrier version. This is OK if the object is white and in 46 // new space, or if the value is an immortal immutable object, like the maps 47 // of primitive (non-JS) objects like strings, heap numbers etc. 48 inline void set_map_no_write_barrier(Map value, 49 RelaxedStoreTag = kRelaxedStore); 50 inline void set_map_no_write_barrier(Map value, ReleaseStoreTag); 51 52 // Access the map using acquire load and release store. 53 DECL_ACQUIRE_GETTER(map, Map) 54 inline void set_map(Map value, ReleaseStoreTag); 55 inline void set_map_safe_transition(Map value, ReleaseStoreTag); 56 57 // Compare-and-swaps map word using release store, returns true if the map 58 // word was actually swapped. 59 inline bool release_compare_and_swap_map_word(MapWord old_map_word, 60 MapWord new_map_word); 61 62 // Initialize the map immediately after the object is allocated. 63 // Do not use this outside Heap. 64 inline void set_map_after_allocation( 65 Map value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 66 67 // During garbage collection, the map word of a heap object does not 68 // necessarily contain a map pointer. 69 DECL_RELAXED_GETTER(map_word, MapWord) 70 inline void set_map_word(MapWord map_word, RelaxedStoreTag); 71 72 // Access the map word using acquire load and release store. 73 DECL_ACQUIRE_GETTER(map_word, MapWord) 74 inline void set_map_word(MapWord map_word, ReleaseStoreTag); 75 76 // This method exists to help remove GetIsolate/GetHeap from HeapObject, in a 77 // way that doesn't require passing Isolate/Heap down huge call chains or to 78 // places where it might not be safe to access it. 79 inline ReadOnlyRoots GetReadOnlyRoots() const; 80 // This version is intended to be used for the isolate values produced by 81 // i::GetPtrComprCageBase(HeapObject) function which may return nullptr. 82 inline ReadOnlyRoots GetReadOnlyRoots(PtrComprCageBase cage_base) const; 83 84 // Whether the object is in the RO heap and the RO heap is shared, or in the 85 // writable shared heap. 86 V8_INLINE bool InSharedHeap() const; 87 88 V8_INLINE bool InSharedWritableHeap() const; 89 90 #define IS_TYPE_FUNCTION_DECL(Type) \ 91 V8_INLINE bool Is##Type() const; \ 92 V8_INLINE bool Is##Type(PtrComprCageBase cage_base) const; 93 HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL) IS_TYPE_FUNCTION_DECL(HashTableBase)94 IS_TYPE_FUNCTION_DECL(HashTableBase) 95 IS_TYPE_FUNCTION_DECL(SmallOrderedHashTable) 96 IS_TYPE_FUNCTION_DECL(CodeT) 97 #undef IS_TYPE_FUNCTION_DECL 98 99 // Oddball checks are faster when they are raw pointer comparisons, so the 100 // isolate/read-only roots overloads should be preferred where possible. 101 #define IS_TYPE_FUNCTION_DECL(Type, Value) \ 102 V8_INLINE bool Is##Type(Isolate* isolate) const; \ 103 V8_INLINE bool Is##Type(LocalIsolate* isolate) const; \ 104 V8_INLINE bool Is##Type(ReadOnlyRoots roots) const; \ 105 V8_INLINE bool Is##Type() const; 106 ODDBALL_LIST(IS_TYPE_FUNCTION_DECL) 107 IS_TYPE_FUNCTION_DECL(NullOrUndefined, /* unused */) 108 #undef IS_TYPE_FUNCTION_DECL 109 110 #define DECL_STRUCT_PREDICATE(NAME, Name, name) \ 111 V8_INLINE bool Is##Name() const; \ 112 V8_INLINE bool Is##Name(PtrComprCageBase cage_base) const; 113 STRUCT_LIST(DECL_STRUCT_PREDICATE) 114 #undef DECL_STRUCT_PREDICATE 115 116 // Converts an address to a HeapObject pointer. 117 static inline HeapObject FromAddress(Address address) { 118 DCHECK_TAG_ALIGNED(address); 119 return HeapObject(address + kHeapObjectTag); 120 } 121 122 // Returns the address of this HeapObject. address()123 inline Address address() const { return ptr() - kHeapObjectTag; } 124 125 // Iterates over pointers contained in the object (including the Map). 126 // If it's not performance critical iteration use the non-templatized 127 // version. 128 void Iterate(PtrComprCageBase cage_base, ObjectVisitor* v); 129 130 template <typename ObjectVisitor> 131 inline void IterateFast(PtrComprCageBase cage_base, ObjectVisitor* v); 132 133 template <typename ObjectVisitor> 134 inline void IterateFast(Map map, int object_size, ObjectVisitor* v); 135 136 // Iterates over all pointers contained in the object except the 137 // first map pointer. The object type is given in the first 138 // parameter. This function does not access the map pointer in the 139 // object, and so is safe to call while the map pointer is modified. 140 // If it's not performance critical iteration use the non-templatized 141 // version. 142 void IterateBody(PtrComprCageBase cage_base, ObjectVisitor* v); 143 void IterateBody(Map map, int object_size, ObjectVisitor* v); 144 145 template <typename ObjectVisitor> 146 inline void IterateBodyFast(PtrComprCageBase cage_base, ObjectVisitor* v); 147 148 template <typename ObjectVisitor> 149 inline void IterateBodyFast(Map map, int object_size, ObjectVisitor* v); 150 151 // Returns true if the object contains a tagged value at given offset. 152 // It is used for invalid slots filtering. If the offset points outside 153 // of the object or to the map word, the result is UNDEFINED (!!!). 154 V8_EXPORT_PRIVATE bool IsValidSlot(Map map, int offset); 155 156 // Returns the heap object's size in bytes 157 DECL_GETTER(Size, int) 158 159 // Given a heap object's map pointer, returns the heap size in bytes 160 // Useful when the map pointer field is used for other purposes. 161 // GC internal. 162 V8_EXPORT_PRIVATE int SizeFromMap(Map map) const; 163 164 // Returns the field at offset in obj, as a read/write Object reference. 165 // Does no checking, and is safe to use during GC, while maps are invalid. 166 // Does not invoke write barrier, so should only be assigned to 167 // during marking GC. 168 inline ObjectSlot RawField(int byte_offset) const; 169 inline MaybeObjectSlot RawMaybeWeakField(int byte_offset) const; 170 inline CodeObjectSlot RawCodeField(int byte_offset) const; 171 inline ExternalPointer_t RawExternalPointerField(int byte_offset) const; 172 173 DECL_CAST(HeapObject) 174 175 // Return the write barrier mode for this. Callers of this function 176 // must be able to present a reference to an DisallowGarbageCollection 177 // object as a sign that they are not going to use this function 178 // from code that allocates and thus invalidates the returned write 179 // barrier mode. 180 inline WriteBarrierMode GetWriteBarrierMode( 181 const DisallowGarbageCollection& promise); 182 183 // Dispatched behavior. 184 void HeapObjectShortPrint(std::ostream& os); 185 #ifdef OBJECT_PRINT 186 void PrintHeader(std::ostream& os, const char* id); 187 #endif 188 DECL_PRINTER(HeapObject) 189 EXPORT_DECL_VERIFIER(HeapObject) 190 #ifdef VERIFY_HEAP 191 inline void VerifyObjectField(Isolate* isolate, int offset); 192 inline void VerifySmiField(int offset); 193 inline void VerifyMaybeObjectField(Isolate* isolate, int offset); 194 195 // Verify a pointer is a valid HeapObject pointer that points to object 196 // areas in the heap. 197 static void VerifyHeapPointer(Isolate* isolate, Object p); 198 static void VerifyCodePointer(Isolate* isolate, Object p); 199 #endif 200 201 static inline AllocationAlignment RequiredAlignment(Map map); 202 203 // Whether the object needs rehashing. That is the case if the object's 204 // content depends on FLAG_hash_seed. When the object is deserialized into 205 // a heap with a different hash seed, these objects need to adapt. 206 bool NeedsRehashing(InstanceType instance_type) const; 207 bool NeedsRehashing(PtrComprCageBase cage_base) const; 208 209 // Rehashing support is not implemented for all objects that need rehashing. 210 // With objects that need rehashing but cannot be rehashed, rehashing has to 211 // be disabled. 212 bool CanBeRehashed(PtrComprCageBase cage_base) const; 213 214 // Rehash the object based on the layout inferred from its map. 215 template <typename IsolateT> 216 void RehashBasedOnMap(IsolateT* isolate); 217 218 // Layout description. 219 #define HEAP_OBJECT_FIELDS(V) \ 220 V(kMapOffset, kTaggedSize) \ 221 /* Header size. */ \ 222 V(kHeaderSize, 0) 223 224 DEFINE_FIELD_OFFSET_CONSTANTS(Object::kHeaderSize, HEAP_OBJECT_FIELDS) 225 #undef HEAP_OBJECT_FIELDS 226 227 STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset); 228 229 using MapField = TaggedField<MapWord, HeapObject::kMapOffset>; 230 231 inline Address GetFieldAddress(int field_offset) const; 232 233 protected: 234 // Special-purpose constructor for subclasses that have fast paths where 235 // their ptr() is a Smi. 236 enum class AllowInlineSmiStorage { kRequireHeapObjectTag, kAllowBeingASmi }; 237 inline HeapObject(Address ptr, AllowInlineSmiStorage allow_smi); 238 239 OBJECT_CONSTRUCTORS(HeapObject, Object); 240 241 private: 242 enum class VerificationMode { 243 kSafeMapTransition, 244 kPotentialLayoutChange, 245 }; 246 247 enum class EmitWriteBarrier { 248 kYes, 249 kNo, 250 }; 251 252 template <EmitWriteBarrier emit_write_barrier, typename MemoryOrder> 253 V8_INLINE void set_map(Map value, MemoryOrder order, VerificationMode mode); 254 }; 255 256 OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object) 257 CAST_ACCESSOR(HeapObject) 258 259 } // namespace internal 260 } // namespace v8 261 262 #include "src/objects/object-macros-undef.h" 263 264 #endif // V8_OBJECTS_HEAP_OBJECT_H_ 265