1 // Copyright 2017 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_VISITORS_H_ 6 #define V8_OBJECTS_VISITORS_H_ 7 8 #include "src/common/globals.h" 9 #include "src/objects/code.h" 10 #include "src/objects/compressed-slots.h" 11 #include "src/objects/foreign.h" 12 #include "src/objects/slots.h" 13 14 namespace v8 { 15 namespace internal { 16 17 class CodeDataContainer; 18 19 #define ROOT_ID_LIST(V) \ 20 V(kStringTable, "(Internalized strings)") \ 21 V(kExternalStringsTable, "(External strings)") \ 22 V(kReadOnlyRootList, "(Read-only roots)") \ 23 V(kStrongRootList, "(Strong roots)") \ 24 V(kSmiRootList, "(Smi roots)") \ 25 V(kBootstrapper, "(Bootstrapper)") \ 26 V(kStackRoots, "(Stack roots)") \ 27 V(kRelocatable, "(Relocatable)") \ 28 V(kDebug, "(Debugger)") \ 29 V(kCompilationCache, "(Compilation cache)") \ 30 V(kHandleScope, "(Handle scope)") \ 31 V(kBuiltins, "(Builtins)") \ 32 V(kGlobalHandles, "(Global handles)") \ 33 V(kEternalHandles, "(Eternal handles)") \ 34 V(kThreadManager, "(Thread manager)") \ 35 V(kStrongRoots, "(Strong roots)") \ 36 V(kExtensions, "(Extensions)") \ 37 V(kCodeFlusher, "(Code flusher)") \ 38 V(kStartupObjectCache, "(Startup object cache)") \ 39 V(kReadOnlyObjectCache, "(Read-only object cache)") \ 40 V(kSharedHeapObjectCache, "(Shareable object cache)") \ 41 V(kWeakCollections, "(Weak collections)") \ 42 V(kWrapperTracing, "(Wrapper tracing)") \ 43 V(kWriteBarrier, "(Write barrier)") \ 44 V(kRetainMaps, "(Retain maps)") \ 45 V(kClientHeap, "(Client heap)") \ 46 V(kUnknown, "(Unknown)") 47 48 class VisitorSynchronization : public AllStatic { 49 public: 50 #define DECLARE_ENUM(enum_item, ignore) enum_item, 51 enum SyncTag { ROOT_ID_LIST(DECLARE_ENUM) kNumberOfSyncTags }; 52 #undef DECLARE_ENUM 53 }; 54 55 enum class Root { 56 #define DECLARE_ENUM(enum_item, ignore) enum_item, 57 ROOT_ID_LIST(DECLARE_ENUM) 58 #undef DECLARE_ENUM 59 kNumberOfRoots 60 }; 61 62 // Abstract base class for visiting, and optionally modifying, the 63 // pointers contained in roots. Used in GC and serialization/deserialization. 64 class RootVisitor { 65 public: 66 virtual ~RootVisitor() = default; 67 68 // Visits a contiguous arrays of pointers in the half-open range 69 // [start, end). Any or all of the values may be modified on return. 70 virtual void VisitRootPointers(Root root, const char* description, 71 FullObjectSlot start, FullObjectSlot end) = 0; 72 73 // Handy shorthand for visiting a single pointer. VisitRootPointer(Root root,const char * description,FullObjectSlot p)74 virtual void VisitRootPointer(Root root, const char* description, 75 FullObjectSlot p) { 76 VisitRootPointers(root, description, p, p + 1); 77 } 78 79 // Visits a contiguous arrays of off-heap pointers in the half-open range 80 // [start, end). Any or all of the values may be modified on return. VisitRootPointers(Root root,const char * description,OffHeapObjectSlot start,OffHeapObjectSlot end)81 virtual void VisitRootPointers(Root root, const char* description, 82 OffHeapObjectSlot start, 83 OffHeapObjectSlot end) { 84 // This should be implemented for any visitor that visits the string table. 85 // If we ever add new off-heap data-structures that we want to walk as roots 86 // using this function, we should make it generic, by 87 // 88 // 1) Making this function pure virtual, and 89 // 2) Implementing it for all visitors. 90 UNREACHABLE(); 91 } 92 93 // Visits a single pointer which is Code from the execution stack. VisitRunningCode(FullObjectSlot p)94 virtual void VisitRunningCode(FullObjectSlot p) { 95 // For most visitors, currently running Code is no different than any other 96 // on-stack pointer. 97 VisitRootPointer(Root::kStackRoots, nullptr, p); 98 } 99 100 // Intended for serialization/deserialization checking: insert, or 101 // check for the presence of, a tag at this position in the stream. 102 // Also used for marking up GC roots in heap snapshots. Synchronize(VisitorSynchronization::SyncTag tag)103 virtual void Synchronize(VisitorSynchronization::SyncTag tag) {} 104 105 static const char* RootName(Root root); 106 }; 107 108 class RelocIterator; 109 110 // Abstract base class for visiting, and optionally modifying, the 111 // pointers contained in Objects. Used in GC and serialization/deserialization. 112 class ObjectVisitor { 113 public: 114 virtual ~ObjectVisitor() = default; 115 116 // Visits a contiguous arrays of pointers in the half-open range 117 // [start, end). Any or all of the values may be modified on return. 118 virtual void VisitPointers(HeapObject host, ObjectSlot start, 119 ObjectSlot end) = 0; 120 virtual void VisitPointers(HeapObject host, MaybeObjectSlot start, 121 MaybeObjectSlot end) = 0; 122 // When V8_EXTERNAL_CODE_SPACE is enabled, visits a Code pointer slot. 123 // The values may be modified on return. 124 // Not used when V8_EXTERNAL_CODE_SPACE is not enabled (the Code pointer 125 // slots are visited as a part of on-heap slot visitation - via 126 // VisitPointers()). 127 virtual void VisitCodePointer(HeapObject host, CodeObjectSlot slot) = 0; 128 129 // Custom weak pointers must be ignored by the GC but not other 130 // visitors. They're used for e.g., lists that are recreated after GC. The 131 // default implementation treats them as strong pointers. Visitors who want to 132 // ignore them must override this function with empty. VisitCustomWeakPointers(HeapObject host,ObjectSlot start,ObjectSlot end)133 virtual void VisitCustomWeakPointers(HeapObject host, ObjectSlot start, 134 ObjectSlot end) { 135 VisitPointers(host, start, end); 136 } 137 138 // Handy shorthand for visiting a single pointer. VisitPointer(HeapObject host,ObjectSlot p)139 virtual void VisitPointer(HeapObject host, ObjectSlot p) { 140 VisitPointers(host, p, p + 1); 141 } VisitPointer(HeapObject host,MaybeObjectSlot p)142 virtual void VisitPointer(HeapObject host, MaybeObjectSlot p) { 143 VisitPointers(host, p, p + 1); 144 } VisitCustomWeakPointer(HeapObject host,ObjectSlot p)145 virtual void VisitCustomWeakPointer(HeapObject host, ObjectSlot p) { 146 VisitCustomWeakPointers(host, p, p + 1); 147 } 148 VisitEphemeron(HeapObject host,int index,ObjectSlot key,ObjectSlot value)149 virtual void VisitEphemeron(HeapObject host, int index, ObjectSlot key, 150 ObjectSlot value) { 151 VisitPointer(host, key); 152 VisitPointer(host, value); 153 } 154 155 // To allow lazy clearing of inline caches the visitor has 156 // a rich interface for iterating over Code objects ... 157 158 // Visits a code target in the instruction stream. 159 virtual void VisitCodeTarget(Code host, RelocInfo* rinfo) = 0; 160 161 // Visit pointer embedded into a code object. 162 virtual void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) = 0; 163 164 // Visits a runtime entry in the instruction stream. VisitRuntimeEntry(Code host,RelocInfo * rinfo)165 virtual void VisitRuntimeEntry(Code host, RelocInfo* rinfo) {} 166 167 // Visits an external reference embedded into a code object. VisitExternalReference(Code host,RelocInfo * rinfo)168 virtual void VisitExternalReference(Code host, RelocInfo* rinfo) {} 169 170 // Visits an external reference. VisitExternalReference(Foreign host,Address * p)171 virtual void VisitExternalReference(Foreign host, Address* p) {} 172 173 // Visits an (encoded) internal reference. VisitInternalReference(Code host,RelocInfo * rinfo)174 virtual void VisitInternalReference(Code host, RelocInfo* rinfo) {} 175 176 // Visits an off-heap target in the instruction stream. VisitOffHeapTarget(Code host,RelocInfo * rinfo)177 virtual void VisitOffHeapTarget(Code host, RelocInfo* rinfo) {} 178 179 // Visits the relocation info using the given iterator. 180 void VisitRelocInfo(RelocIterator* it); 181 182 // Visits the object's map pointer, decoding as necessary VisitMapPointer(HeapObject host)183 virtual void VisitMapPointer(HeapObject host) { UNREACHABLE(); } 184 185 // Visits an external pointer. This is currently only guaranteed to be called 186 // when the sandbox is enabled. VisitExternalPointer(HeapObject host,ExternalPointer_t ptr)187 virtual void VisitExternalPointer(HeapObject host, ExternalPointer_t ptr) {} 188 }; 189 190 // Helper version of ObjectVisitor that also takes care of caching base values 191 // of the main pointer compression cage and for the code cage. 192 class ObjectVisitorWithCageBases : public ObjectVisitor { 193 public: 194 inline ObjectVisitorWithCageBases(PtrComprCageBase cage_base, 195 PtrComprCageBase code_cage_base); 196 inline explicit ObjectVisitorWithCageBases(Isolate* isolate); 197 inline explicit ObjectVisitorWithCageBases(Heap* heap); 198 199 // The pointer compression cage base value used for decompression of all 200 // tagged values except references to Code objects. cage_base()201 PtrComprCageBase cage_base() const { 202 #if V8_COMPRESS_POINTERS 203 return cage_base_; 204 #else 205 return PtrComprCageBase{}; 206 #endif // V8_COMPRESS_POINTERS 207 } 208 209 // The pointer compression cage base value used for decompression of 210 // references to Code objects. code_cage_base()211 PtrComprCageBase code_cage_base() const { 212 #ifdef V8_EXTERNAL_CODE_SPACE 213 return code_cage_base_; 214 #else 215 return cage_base(); 216 #endif // V8_EXTERNAL_CODE_SPACE 217 } 218 219 private: 220 #if V8_COMPRESS_POINTERS 221 const PtrComprCageBase cage_base_; 222 #ifdef V8_EXTERNAL_CODE_SPACE 223 const PtrComprCageBase code_cage_base_; 224 #endif // V8_EXTERNAL_CODE_SPACE 225 #endif // V8_COMPRESS_POINTERS 226 }; 227 228 } // namespace internal 229 } // namespace v8 230 231 #endif // V8_OBJECTS_VISITORS_H_ 232