1 /* 2 * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_MEMORY_METASPACECLOSURE_HPP 26 #define SHARE_MEMORY_METASPACECLOSURE_HPP 27 28 #include "logging/log.hpp" 29 #include "memory/allocation.hpp" 30 #include "metaprogramming/enableIf.hpp" 31 #include "oops/array.hpp" 32 #include "utilities/debug.hpp" 33 #include "utilities/globalDefinitions.hpp" 34 #include "utilities/growableArray.hpp" 35 #include "utilities/macros.hpp" 36 #include "utilities/resizeableResourceHash.hpp" 37 #include <type_traits> 38 39 // The metadata hierarchy is separate from the oop hierarchy 40 class MetaspaceObj; // no C++ vtable 41 //class Array; // no C++ vtable 42 class Annotations; // no C++ vtable 43 class ConstantPoolCache; // no C++ vtable 44 class ConstMethod; // no C++ vtable 45 class MethodCounters; // no C++ vtable 46 class Symbol; // no C++ vtable 47 class Metadata; // has C++ vtable (so do all subclasses) 48 class ConstantPool; 49 class MethodData; 50 class Method; 51 class Klass; 52 class InstanceKlass; 53 class InstanceMirrorKlass; 54 class InstanceClassLoaderKlass; 55 class InstanceRefKlass; 56 class ArrayKlass; 57 class ObjArrayKlass; 58 class TypeArrayKlass; 59 60 // class MetaspaceClosure -- 61 // 62 // This class is used for iterating the objects in the HotSpot Metaspaces. It 63 // provides an API to walk all the reachable objects starting from a set of 64 // root references (such as all Klass'es in the SystemDictionary). 65 // 66 // Currently it is used for compacting the CDS archive by eliminate temporary 67 // objects allocated during archive creation time. See ArchiveBuilder for an example. 68 // 69 // To support MetaspaceClosure, each subclass of MetaspaceObj must provide 70 // a method of the type void metaspace_pointers_do(MetaspaceClosure*). This method 71 // should call MetaspaceClosure::push() on every pointer fields of this 72 // class that points to a MetaspaceObj. See Annotations::metaspace_pointers_do() 73 // for an example. 74 class MetaspaceClosure { 75 public: 76 enum Writability { 77 _writable, 78 _not_writable, 79 _default 80 }; 81 82 // class MetaspaceClosure::Ref -- 83 // 84 // MetaspaceClosure can be viewed as a very simple type of copying garbage 85 // collector. For it to function properly, it requires each subclass of 86 // MetaspaceObj to provide two methods: 87 // 88 // size_t size(); -- to determine how much data to copy 89 // void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers 90 // 91 // Calling these methods would be trivial if these two were virtual methods. 92 // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced 93 // only in the Metadata class. 94 // 95 // To work around the lack of a vtable, we use the Ref class with templates 96 // (see MSORef, OtherArrayRef, MSOArrayRef, and MSOPointerArrayRef) 97 // so that we can statically discover the type of a object. The use of Ref 98 // depends on the fact that: 99 // 100 // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses 101 // of Metadata. I.e., we don't do this: 102 // class Klass { 103 // MetaspaceObj *_obj; 104 // Array<int>* foo() { return (Array<int>*)_obj; } 105 // Symbol* bar() { return (Symbol*) _obj; } 106 // 107 // [2] All Array<T> dimensions are statically declared. 108 // 109 // Pointer Tagging 110 // 111 // All metaspace pointers are at least 4 byte aligned. Therefore, it's possible for 112 // certain pointers to contain "tags" in their lowest 2 bits. 113 // 114 // Ref::obj() clears the tag bits in the return values. As a result, most 115 // callers who just want walk a closure of metaspace objects do not need to worry 116 // about the tag bits. 117 // 118 // If you need to use the tags, you can access the tagged pointer with Ref::addr() 119 // and manipulate its parts with strip_tags(), decode_tags() and add_tags() 120 class Ref : public CHeapObj<mtMetaspace> { 121 Writability _writability; 122 address _enclosing_obj; 123 Ref* _next; 124 NONCOPYABLE(Ref); 125 126 protected: 127 virtual void** mpp() const = 0; 128 Ref(Writability w) : _writability(w), _enclosing_obj(nullptr), _next(nullptr) {} 129 public: 130 virtual bool not_null() const = 0; 131 virtual int size() const = 0; 132 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0; 133 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0; 134 virtual MetaspaceObj::Type msotype() const = 0; 135 virtual bool is_read_only_by_default() const = 0; 136 virtual ~Ref() {} 137 138 address obj() const { 139 return strip_tags(*addr()); 140 } 141 142 address* addr() const { 143 return (address*)mpp(); 144 } 145 146 // See comments in ArchiveBuilder::remember_embedded_pointer_in_enclosing_obj() 147 address enclosing_obj() const { 148 return _enclosing_obj; 149 } 150 void set_enclosing_obj(address obj) { 151 _enclosing_obj = obj; 152 } 153 154 Writability writability() const { return _writability; }; 155 void set_next(Ref* n) { _next = n; } 156 Ref* next() const { return _next; } 157 }; 158 159 // Pointer tagging support 160 constexpr static uintx TAG_MASK = 0x03; 161 162 template <typename T> 163 static T strip_tags(T ptr_with_tags) { 164 uintx n = (uintx)ptr_with_tags; 165 return (T)(n & ~TAG_MASK); 166 } 167 168 template <typename T> 169 static uintx decode_tags(T ptr_with_tags) { 170 uintx n = (uintx)ptr_with_tags; 171 return (n & TAG_MASK); 172 } 173 174 template <typename T> 175 static T add_tags(T ptr, uintx tags) { 176 uintx n = (uintx)ptr; 177 assert((n & TAG_MASK) == 0, "sanity"); 178 assert(tags <= TAG_MASK, "sanity"); 179 return (T)(n | tags); 180 } 181 182 private: 183 // MSORef -- iterate an instance of MetaspaceObj 184 template <class T> class MSORef : public Ref { 185 T** _mpp; 186 T* dereference() const { 187 return strip_tags(*_mpp); 188 } 189 protected: 190 virtual void** mpp() const { 191 return (void**)_mpp; 192 } 193 194 public: 195 MSORef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {} 196 197 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); } 198 virtual bool not_null() const { return dereference() != nullptr; } 199 virtual int size() const { return dereference()->size(); } 200 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); } 201 202 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 203 dereference()->metaspace_pointers_do(it); 204 } 205 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 206 ((T*)new_loc)->metaspace_pointers_do(it); 207 } 208 }; 209 210 // abstract base class for MSOArrayRef, MSOPointerArrayRef and OtherArrayRef 211 template <class T> class ArrayRef : public Ref { 212 Array<T>** _mpp; 213 protected: 214 Array<T>* dereference() const { 215 return strip_tags(*_mpp); 216 } 217 virtual void** mpp() const { 218 return (void**)_mpp; 219 } 220 221 ArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {} 222 223 // all Arrays are read-only by default 224 virtual bool is_read_only_by_default() const { return true; } 225 virtual bool not_null() const { return dereference() != nullptr; } 226 virtual int size() const { return dereference()->size(); } 227 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T)); } 228 }; 229 230 // OtherArrayRef -- iterate an instance of Array<T>, where T is NOT a subtype of MetaspaceObj. 231 // T can be a primitive type, such as int, or a structure. However, we do not scan 232 // the fields inside T, so you should not embed any pointers inside T. 233 template <class T> class OtherArrayRef : public ArrayRef<T> { 234 public: 235 OtherArrayRef(Array<T>** mpp, Writability w) : ArrayRef<T>(mpp, w) {} 236 237 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 238 Array<T>* array = ArrayRef<T>::dereference(); 239 log_trace(cds)("Iter(OtherArray): %p [%d]", array, array->length()); 240 } 241 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 242 Array<T>* array = (Array<T>*)new_loc; 243 log_trace(cds)("Iter(OtherArray): %p [%d]", array, array->length()); 244 } 245 }; 246 247 // MSOArrayRef -- iterate an instance of Array<T>, where T is a subtype of MetaspaceObj. 248 // We recursively call T::metaspace_pointers_do() for each element in this array. 249 template <class T> class MSOArrayRef : public ArrayRef<T> { 250 public: 251 MSOArrayRef(Array<T>** mpp, Writability w) : ArrayRef<T>(mpp, w) {} 252 253 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 254 metaspace_pointers_do_at_impl(it, ArrayRef<T>::dereference()); 255 } 256 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 257 metaspace_pointers_do_at_impl(it, (Array<T>*)new_loc); 258 } 259 private: 260 void metaspace_pointers_do_at_impl(MetaspaceClosure *it, Array<T>* array) const { 261 log_trace(cds)("Iter(MSOArray): %p [%d]", array, array->length()); 262 for (int i = 0; i < array->length(); i++) { 263 T* elm = array->adr_at(i); 264 elm->metaspace_pointers_do(it); 265 } 266 } 267 }; 268 269 // MSOPointerArrayRef -- iterate an instance of Array<T*>, where T is a subtype of MetaspaceObj. 270 // We recursively call MetaspaceClosure::push() for each pointer in this array. 271 template <class T> class MSOPointerArrayRef : public ArrayRef<T*> { 272 public: 273 MSOPointerArrayRef(Array<T*>** mpp, Writability w) : ArrayRef<T*>(mpp, w) {} 274 275 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 276 metaspace_pointers_do_at_impl(it, ArrayRef<T*>::dereference()); 277 } 278 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 279 metaspace_pointers_do_at_impl(it, (Array<T*>*)new_loc); 280 } 281 private: 282 void metaspace_pointers_do_at_impl(MetaspaceClosure *it, Array<T*>* array) const { 283 log_trace(cds)("Iter(MSOPointerArray): %p [%d]", array, array->length()); 284 for (int i = 0; i < array->length(); i++) { 285 T** mpp = array->adr_at(i); 286 it->push(mpp); 287 } 288 } 289 }; 290 291 // Normally, chains of references like a->b->c->d are iterated recursively. However, 292 // if recursion is too deep, we save the Refs in _pending_refs, and push them later in 293 // MetaspaceClosure::finish(). This avoids overflowing the C stack. 294 // 295 // When we are visting d, the _enclosing_ref is c, 296 // When we are visting c, the _enclosing_ref is b, ... and so on. 297 static const int MAX_NEST_LEVEL = 5; 298 Ref* _pending_refs; 299 int _nest_level; 300 Ref* _enclosing_ref; 301 302 void push_impl(Ref* ref); 303 void do_push(Ref* ref); 304 305 public: 306 MetaspaceClosure(): _pending_refs(nullptr), _nest_level(0), _enclosing_ref(nullptr) {} 307 ~MetaspaceClosure(); 308 309 void finish(); 310 311 // returns true if we want to keep iterating the pointers embedded inside <ref> 312 virtual bool do_ref(Ref* ref, bool read_only) = 0; 313 314 private: 315 template <class REF_TYPE, typename T> 316 void push_with_ref(T** mpp, Writability w) { 317 // We cannot make stack allocation because the Ref may need to be saved in 318 // _pending_refs to avoid overflowing the C call stack 319 push_impl(new REF_TYPE(mpp, w)); 320 } 321 322 public: 323 // When MetaspaceClosure::push(...) is called, pick the correct Ref subtype to handle it: 324 // 325 // MetaspaceClosure* it = ...; 326 // Klass* o = ...; it->push(&o); => MSORef 327 // Array<int>* a1 = ...; it->push(&a1); => OtherArrayRef 328 // Array<Annotation>* a2 = ...; it->push(&a2); => MSOArrayRef 329 // Array<Klass*>* a3 = ...; it->push(&a3); => MSOPointerArrayRef 330 // Array<Array<Klass*>*>* a4 = ...; it->push(&a4); => MSOPointerArrayRef 331 // Array<Annotation*>* a5 = ...; it->push(&a5); => MSOPointerArrayRef 332 // 333 // Note that the following will fail to compile (to prevent you from adding new fields 334 // into the MetaspaceObj subtypes that cannot be properly copied by CDS): 335 // 336 // MemoryPool* p = ...; it->push(&p); => MemoryPool is not a subclass of MetaspaceObj 337 // Array<MemoryPool*>* a6 = ...; it->push(&a6); => MemoryPool is not a subclass of MetaspaceObj 338 // Array<int*>* a7 = ...; it->push(&a7); => int is not a subclass of MetaspaceObj 339 340 template <typename T> 341 void push(T** mpp, Writability w = _default) { 342 static_assert(std::is_base_of<MetaspaceObj, T>::value, "Do not push pointers of arbitrary types"); 343 push_with_ref<MSORef<T>>(mpp, w); 344 } 345 346 template <typename T, ENABLE_IF(!std::is_base_of<MetaspaceObj, T>::value)> 347 void push(Array<T>** mpp, Writability w = _default) { 348 push_with_ref<OtherArrayRef<T>>(mpp, w); 349 } 350 351 template <typename T, ENABLE_IF(std::is_base_of<MetaspaceObj, T>::value)> 352 void push(Array<T>** mpp, Writability w = _default) { 353 push_with_ref<MSOArrayRef<T>>(mpp, w); 354 } 355 356 template <typename T> 357 void push(Array<T*>** mpp, Writability w = _default) { 358 static_assert(std::is_base_of<MetaspaceObj, T>::value, "Do not push Arrays of arbitrary pointer types"); 359 push_with_ref<MSOPointerArrayRef<T>>(mpp, w); 360 } 361 }; 362 363 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. 364 class UniqueMetaspaceClosure : public MetaspaceClosure { 365 static const int INITIAL_TABLE_SIZE = 15889; 366 static const int MAX_TABLE_SIZE = 1000000; 367 368 // Do not override. Returns true if we are discovering ref->obj() for the first time. 369 virtual bool do_ref(Ref* ref, bool read_only); 370 371 public: 372 // Gets called the first time we discover an object. 373 virtual bool do_unique_ref(Ref* ref, bool read_only) = 0; 374 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE) {} 375 376 private: 377 ResizeableResourceHashtable<address, bool, AnyObj::C_HEAP, 378 mtClassShared> _has_been_visited; 379 }; 380 381 #endif // SHARE_MEMORY_METASPACECLOSURE_HPP