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 enum SpecialRef { 79 _method_entry_ref 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 Ref class with templates 96 // (see ObjectRef, PrimitiveArrayRef and PointerArrayRef) 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 class Ref : public CHeapObj<mtInternal> { 109 Writability _writability; 110 Ref* _next; 111 // Noncopyable. 112 Ref(const Ref&); 113 Ref& operator=(const Ref&); 114 protected: 115 virtual void** mpp() const = 0; 116 Ref(Writability w) : _writability(w), _next(NULL) {} 117 public: 118 virtual bool not_null() const = 0; 119 virtual int size() const = 0; 120 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0; 121 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0; 122 virtual MetaspaceObj::Type msotype() const = 0; 123 virtual bool is_read_only_by_default() const = 0; 124 virtual ~Ref() {} 125 126 address obj() const { 127 // In some rare cases (see CPSlot in constantPool.hpp) we store some flags in the lowest 128 // 2 bits of a MetaspaceObj pointer. Unmask these when manipulating the pointer. 129 uintx p = (uintx)*mpp(); 130 return (address)(p & (~FLAG_MASK)); 131 } 132 133 address* addr() const { 134 return (address*)mpp(); 135 } 136 137 void update(address new_loc) const; 138 139 Writability writability() const { return _writability; }; 140 void set_next(Ref* n) { _next = n; } 141 Ref* next() const { return _next; } 142 143 private: 144 static const uintx FLAG_MASK = 0x03; 145 146 int flag_bits() const { 147 uintx p = (uintx)*mpp(); 148 return (int)(p & FLAG_MASK); 149 } 150 }; 151 152 private: 153 // -------------------------------------------------- ObjectRef 154 template <class T> class ObjectRef : public Ref { 155 T** _mpp; 156 T* dereference() const { 157 return *_mpp; 158 } 159 protected: 160 virtual void** mpp() const { 161 return (void**)_mpp; 162 } 163 164 public: 165 ObjectRef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {} 166 167 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); } 168 virtual bool not_null() const { return dereference() != NULL; } 169 virtual int size() const { return dereference()->size(); } 170 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); } 171 172 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 173 dereference()->metaspace_pointers_do(it); 174 } 175 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 176 ((T*)new_loc)->metaspace_pointers_do(it); 177 } 178 }; 179 180 // -------------------------------------------------- PrimitiveArrayRef 181 template <class T> class PrimitiveArrayRef : public Ref { 182 Array<T>** _mpp; 183 Array<T>* dereference() const { 184 return *_mpp; 185 } 186 protected: 187 virtual void** mpp() const { 188 return (void**)_mpp; 189 } 190 191 public: 192 PrimitiveArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {} 193 194 // all Arrays are read-only by default 195 virtual bool is_read_only_by_default() const { return true; } 196 virtual bool not_null() const { return dereference() != NULL; } 197 virtual int size() const { return dereference()->size(); } 198 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T)); } 199 200 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 201 Array<T>* array = dereference(); 202 log_trace(cds)("Iter(PrimitiveArray): %p [%d]", array, array->length()); 203 } 204 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 205 Array<T>* array = (Array<T>*)new_loc; 206 log_trace(cds)("Iter(PrimitiveArray): %p [%d]", array, array->length()); 207 } 208 }; 209 210 // -------------------------------------------------- PointerArrayRef 211 template <class T> class PointerArrayRef : public Ref { 212 Array<T*>** _mpp; 213 Array<T*>* dereference() const { 214 return *_mpp; 215 } 216 protected: 217 virtual void** mpp() const { 218 return (void**)_mpp; 219 } 220 221 public: 222 PointerArrayRef(Array<T*>** mpp, Writability w) : Ref(w), _mpp(mpp) {} 223 224 // all Arrays are read-only by default 225 virtual bool is_read_only_by_default() const { return true; } 226 virtual bool not_null() const { return dereference() != NULL; } 227 virtual int size() const { return dereference()->size(); } 228 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T*)); } 229 230 virtual void metaspace_pointers_do(MetaspaceClosure *it) const { 231 metaspace_pointers_do_at_impl(it, dereference()); 232 } 233 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const { 234 metaspace_pointers_do_at_impl(it, (Array<T*>*)new_loc); 235 } 236 private: 237 void metaspace_pointers_do_at_impl(MetaspaceClosure *it, Array<T*>* array) const { 238 log_trace(cds)("Iter(ObjectArray): %p [%d]", array, array->length()); 239 for (int i = 0; i < array->length(); i++) { 240 T** mpp = array->adr_at(i); 241 it->push(mpp); 242 } 243 } 244 }; 245 246 // If recursion is too deep, save the Refs in _pending_refs, and push them later using 247 // MetaspaceClosure::finish() 248 static const int MAX_NEST_LEVEL = 5; 249 Ref* _pending_refs; 250 int _nest_level; 251 252 void push_impl(Ref* ref); 253 void do_push(Ref* ref); 254 255 public: 256 MetaspaceClosure(): _pending_refs(NULL), _nest_level(0) {} 257 ~MetaspaceClosure(); 258 259 void finish(); 260 261 // returns true if we want to keep iterating the pointers embedded inside <ref> 262 virtual bool do_ref(Ref* ref, bool read_only) = 0; 263 264 // When you do: 265 // void MyType::metaspace_pointers_do(MetaspaceClosure* it) { 266 // it->push(_my_field) 267 // 268 // C++ will try to match the "most specific" template function. This one will 269 // will be matched if possible (if mpp is an Array<> of any pointer type). 270 template <typename T> void push(Array<T*>** mpp, Writability w = _default) { 271 push_impl(new PointerArrayRef<T>(mpp, w)); 272 } 273 274 // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then 275 // this is the second choice. 276 template <typename T> void push(Array<T>** mpp, Writability w = _default) { 277 push_impl(new PrimitiveArrayRef<T>(mpp, w)); 278 } 279 280 // If the above function doesn't match (mpp is not an Array<> type), then 281 // this will be matched by default. 282 template <class T> void push(T** mpp, Writability w = _default) { 283 push_impl(new ObjectRef<T>(mpp, w)); 284 } 285 286 template <class T> void push_method_entry(T** mpp, intptr_t* p) { 287 push_special(_method_entry_ref, new ObjectRef<T>(mpp, _default), (intptr_t*)p); 288 } 289 290 // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently 291 // used to mark the method entry points in Method/ConstMethod. 292 virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) { 293 assert(type == _method_entry_ref, "only special type allowed for now"); 294 } 295 }; 296 297 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. 298 class UniqueMetaspaceClosure : public MetaspaceClosure { 299 static const int INITIAL_TABLE_SIZE = 15889; 300 static const int MAX_TABLE_SIZE = 1000000; 301 302 // Do not override. Returns true if we are discovering ref->obj() for the first time. 303 virtual bool do_ref(Ref* ref, bool read_only); 304 305 public: 306 // Gets called the first time we discover an object. 307 virtual bool do_unique_ref(Ref* ref, bool read_only) = 0; 308 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {} 309 310 private: 311 KVHashtable<address, bool, mtInternal> _has_been_visited; 312 }; 313 314 #endif // SHARE_MEMORY_METASPACECLOSURE_HPP