1 /* 2 * Copyright (c) 2017, 2019, 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 "oops/array.hpp" 31 #include "utilities/growableArray.hpp" 32 #include "utilities/hashtable.inline.hpp" 33 34 // The metadata hierarchy is separate from the oop hierarchy 35 class MetaspaceObj; // no C++ vtable 36 //class Array; // no C++ vtable 37 class Annotations; // no C++ vtable 38 class ConstantPoolCache; // no C++ vtable 39 class ConstMethod; // no C++ vtable 40 class MethodCounters; // no C++ vtable 41 class Symbol; // no C++ vtable 42 class Metadata; // has C++ vtable (so do all subclasses) 43 class ConstantPool; 44 class MethodData; 45 class Method; 46 class Klass; 47 class InstanceKlass; 48 class InstanceMirrorKlass; 49 class InstanceClassLoaderKlass; 50 class InstanceRefKlass; 51 class ArrayKlass; 52 class ObjArrayKlass; 53 class TypeArrayKlass; 54 55 // class MetaspaceClosure -- 56 // 57 // This class is used for iterating the objects in the HotSpot Metaspaces. It 58 // provides an API to walk all the reachable objects starting from a set of 59 // root references (such as all Klass'es in the SystemDictionary). 60 // 61 // Currently it is used for compacting the CDS archive by eliminate temporary 62 // objects allocated during archive creation time. See ArchiveCompactor in 63 // metaspaceShared.cpp for an example. 64 // 65 // To support MetaspaceClosure, each subclass of MetaspaceObj must provide 66 // a method of the type void metaspace_pointers_do(MetaspaceClosure*). This method 67 // should call MetaspaceClosure::push() on every pointer fields of this 68 // class that points to a MetaspaceObj. See Annotations::metaspace_pointers_do() 69 // for an example. 70 class MetaspaceClosure { 71 public: 72 enum Writability { 73 _writable, 74 _not_writable, 75 _default 76 }; 77 78 // class MetaspaceClosure::Ref -- 79 // 80 // MetaspaceClosure can be viewed as a very simple type of copying garbage 81 // collector. For it to function properly, it requires each subclass of 82 // MetaspaceObj to provide two methods: 83 // 84 // size_t size(); -- to determine how much data to copy 85 // void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers 86 // 87 // Calling these methods would be trivial if these two were virtual methods. 88 // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced 89 // only in the Metadata class. 90 // 91 // To work around the lack of a vtable, we use Ref class with templates 92 // (see ObjectRef, PrimitiveArrayRef and PointerArrayRef) 93 // so that we can statically discover the type of a object. The use of Ref 94 // depends on the fact that: 95 // 96 // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses 97 // of Metadata. I.e., we don't do this: 98 // class Klass { 99 // MetaspaceObj *_obj; 100 // Array<int>* foo() { return (Array<int>*)_obj; } 101 // Symbol* bar() { return (Symbol*) _obj; } 102 // 103 // [2] All Array<T> dimensions are statically declared. 104 class Ref : public CHeapObj<mtInternal> { 105 Writability _writability; 106 Ref* _next; 107 // Noncopyable. 108 Ref(const Ref&); 109 Ref& operator=(const Ref&); 110 protected: 111 virtual void** mpp() const = 0; 112 Ref(Writability w) : _writability(w), _next(NULL) {} 113 public: 114 virtual bool not_null() const = 0; 115 virtual int size() const = 0; 116 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0; 117 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0; 118 virtual MetaspaceObj::Type msotype() const = 0; 119 virtual bool is_read_only_by_default() const = 0; 120 virtual ~Ref() {} 121 122 address obj() const { 123 // In some rare cases (see CPSlot in constantPool.hpp) we store some flags in the lowest 124 // 2 bits of a MetaspaceObj pointer. Unmask these when manipulating the pointer. 125 uintx p = (uintx)*mpp(); 126 return (address)(p & (~FLAG_MASK)); 127 } 128 129 address* addr() const { 130 return (address*)mpp(); 131 } 132 133 void update(address new_loc) const; 134 135 Writability writability() const { return _writability; }; 136 void set_next(Ref* n) { _next = n; } 137 Ref* next() const { return _next; } 138 139 private: 140 static const uintx FLAG_MASK = 0x03; 141 142 int flag_bits() const { 143 uintx p = (uintx)*mpp(); 144 return (int)(p & FLAG_MASK); 145 } 146 }; 147 148 private: 149 // -------------------------------------------------- ObjectRef 150 template <class T> class ObjectRef : public Ref { 151 T** _mpp; 152 T* dereference() const { 153 return *_mpp; 154 } 155 protected: 156 virtual void** mpp() const { 157 return (void**)_mpp; 158 } 159 160 public: 161 ObjectRef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {} 162 163 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); } 164 virtual bool not_null() const { return dereference() != NULL; } 165 virtual int size() const { return dereference()->size(); } 166 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); } 167 168 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 169 dereference()->metaspace_pointers_do(it); 170 } 171 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 172 ((T*)new_loc)->metaspace_pointers_do(it); 173 } 174 }; 175 176 // -------------------------------------------------- PrimitiveArrayRef 177 template <class T> class PrimitiveArrayRef : public Ref { 178 Array<T>** _mpp; 179 Array<T>* dereference() const { 180 return *_mpp; 181 } 182 protected: 183 virtual void** mpp() const { 184 return (void**)_mpp; 185 } 186 187 public: 188 PrimitiveArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {} 189 190 // all Arrays are read-only by default 191 virtual bool is_read_only_by_default() const { return true; } 192 virtual bool not_null() const { return dereference() != NULL; } 193 virtual int size() const { return dereference()->size(); } 194 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T)); } 195 196 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 197 Array<T>* array = dereference(); 198 log_trace(cds)("Iter(PrimitiveArray): %p [%d]", array, array->length()); 199 } 200 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 201 Array<T>* array = (Array<T>*)new_loc; 202 log_trace(cds)("Iter(PrimitiveArray): %p [%d]", array, array->length()); 203 } 204 }; 205 206 // -------------------------------------------------- PointerArrayRef 207 template <class T> class PointerArrayRef : public Ref { 208 Array<T*>** _mpp; 209 Array<T*>* dereference() const { 210 return *_mpp; 211 } 212 protected: 213 virtual void** mpp() const { 214 return (void**)_mpp; 215 } 216 217 public: 218 PointerArrayRef(Array<T*>** mpp, Writability w) : Ref(w), _mpp(mpp) {} 219 220 // all Arrays are read-only by default 221 virtual bool is_read_only_by_default() const { return true; } 222 virtual bool not_null() const { return dereference() != NULL; } 223 virtual int size() const { return dereference()->size(); } 224 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T*)); } 225 226 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 227 metaspace_pointers_do_at_impl(it, dereference()); 228 } 229 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 230 metaspace_pointers_do_at_impl(it, (Array<T*>*)new_loc); 231 } 232 private: 233 void metaspace_pointers_do_at_impl(MetaspaceClosure *it, Array<T*>* array) const { 234 log_trace(cds)("Iter(ObjectArray): %p [%d]", array, array->length()); 235 for (int i = 0; i < array->length(); i++) { 236 T** mpp = array->adr_at(i); 237 it->push(mpp); 238 } 239 } 240 }; 241 242 // If recursion is too deep, save the Refs in _pending_refs, and push them later using 243 // MetaspaceClosure::finish() 244 static const int MAX_NEST_LEVEL = 5; 245 Ref* _pending_refs; 246 int _nest_level; 247 248 void push_impl(Ref* ref); 249 void do_push(Ref* ref); 250 251 public: 252 MetaspaceClosure(): _pending_refs(NULL), _nest_level(0) {} 253 ~MetaspaceClosure(); 254 255 void finish(); 256 257 // returns true if we want to keep iterating the pointers embedded inside <ref> 258 virtual bool do_ref(Ref* ref, bool read_only) = 0; 259 260 // When you do: 261 // void MyType::metaspace_pointers_do(MetaspaceClosure* it) { 262 // it->push(_my_field) 263 // 264 // C++ will try to match the "most specific" template function. This one will 265 // will be matched if possible (if mpp is an Array<> of any pointer type). 266 template <typename T> void push(Array<T*>** mpp, Writability w = _default) { 267 push_impl(new PointerArrayRef<T>(mpp, w)); 268 } 269 270 // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then 271 // this is the second choice. 272 template <typename T> void push(Array<T>** mpp, Writability w = _default) { 273 push_impl(new PrimitiveArrayRef<T>(mpp, w)); 274 } 275 276 // If the above function doesn't match (mpp is not an Array<> type), then 277 // this will be matched by default. 278 template <class T> void push(T** mpp, Writability w = _default) { 279 push_impl(new ObjectRef<T>(mpp, w)); 280 } 281 }; 282 283 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. 284 class UniqueMetaspaceClosure : public MetaspaceClosure { 285 static const int INITIAL_TABLE_SIZE = 15889; 286 static const int MAX_TABLE_SIZE = 1000000; 287 288 // Do not override. Returns true if we are discovering ref->obj() for the first time. 289 virtual bool do_ref(Ref* ref, bool read_only); 290 291 public: 292 // Gets called the first time we discover an object. 293 virtual bool do_unique_ref(Ref* ref, bool read_only) = 0; 294 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {} 295 296 private: 297 KVHashtable<address, bool, mtInternal> _has_been_visited; 298 }; 299 300 #endif // SHARE_MEMORY_METASPACECLOSURE_HPP