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/globalDefinitions.hpp" 32 #include "utilities/growableArray.hpp" 33 #include "utilities/hashtable.inline.hpp" 34 35 // The metadata hierarchy is separate from the oop hierarchy 36 class MetaspaceObj; // no C++ vtable 37 //class Array; // no C++ vtable 38 class Annotations; // no C++ vtable 39 class ConstantPoolCache; // no C++ vtable 40 class ConstMethod; // no C++ vtable 41 class MethodCounters; // no C++ vtable 42 class Symbol; // no C++ vtable 43 class Metadata; // has C++ vtable (so do all subclasses) 44 class ConstantPool; 45 class MethodData; 46 class Method; 47 class Klass; 48 class InstanceKlass; 49 class InstanceMirrorKlass; 50 class InstanceClassLoaderKlass; 51 class InstanceRefKlass; 52 class ArrayKlass; 53 class ObjArrayKlass; 54 class TypeArrayKlass; 55 56 // class MetaspaceClosure -- 57 // 58 // This class is used for iterating the objects in the HotSpot Metaspaces. It 59 // provides an API to walk all the reachable objects starting from a set of 60 // root references (such as all Klass'es in the SystemDictionary). 61 // 62 // Currently it is used for compacting the CDS archive by eliminate temporary 63 // objects allocated during archive creation time. See ArchiveCompactor in 64 // metaspaceShared.cpp for an example. 65 // 66 // To support MetaspaceClosure, each subclass of MetaspaceObj must provide 67 // a method of the type void metaspace_pointers_do(MetaspaceClosure*). This method 68 // should call MetaspaceClosure::push() on every pointer fields of this 69 // class that points to a MetaspaceObj. See Annotations::metaspace_pointers_do() 70 // for an example. 71 class MetaspaceClosure { 72 public: 73 enum Writability { 74 _writable, 75 _not_writable, 76 _default 77 }; 78 79 enum SpecialRef { 80 _method_entry_ref 81 }; 82 83 // class MetaspaceClosure::Ref -- 84 // 85 // MetaspaceClosure can be viewed as a very simple type of copying garbage 86 // collector. For it to function properly, it requires each subclass of 87 // MetaspaceObj to provide two methods: 88 // 89 // size_t size(); -- to determine how much data to copy 90 // void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers 91 // 92 // Calling these methods would be trivial if these two were virtual methods. 93 // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced 94 // only in the Metadata class. 95 // 96 // To work around the lack of a vtable, we use Ref class with templates 97 // (see ObjectRef, PrimitiveArrayRef and PointerArrayRef) 98 // so that we can statically discover the type of a object. The use of Ref 99 // depends on the fact that: 100 // 101 // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses 102 // of Metadata. I.e., we don't do this: 103 // class Klass { 104 // MetaspaceObj *_obj; 105 // Array<int>* foo() { return (Array<int>*)_obj; } 106 // Symbol* bar() { return (Symbol*) _obj; } 107 // 108 // [2] All Array<T> dimensions are statically declared. 109 class Ref : public CHeapObj<mtMetaspace> { 110 Writability _writability; 111 Ref* _next; 112 NONCOPYABLE(Ref); 113 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 // 269 // C++ will try to match the "most specific" template function. This one will 270 // will be matched if possible (if mpp is an Array<> of any pointer type). 271 template <typename T> void push(Array<T*>** mpp, Writability w = _default) { 272 push_impl(new PointerArrayRef<T>(mpp, w)); 273 } 274 275 // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then 276 // this is the second choice. 277 template <typename T> void push(Array<T>** mpp, Writability w = _default) { 278 push_impl(new PrimitiveArrayRef<T>(mpp, w)); 279 } 280 281 // If the above function doesn't match (mpp is not an Array<> type), then 282 // this will be matched by default. 283 template <class T> void push(T** mpp, Writability w = _default) { 284 push_impl(new ObjectRef<T>(mpp, w)); 285 } 286 287 template <class T> void push_method_entry(T** mpp, intptr_t* p) { 288 push_special(_method_entry_ref, new ObjectRef<T>(mpp, _default), (intptr_t*)p); 289 } 290 291 // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently 292 // used to mark the method entry points in Method/ConstMethod. 293 virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) { 294 assert(type == _method_entry_ref, "only special type allowed for now"); 295 } 296 }; 297 298 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. 299 class UniqueMetaspaceClosure : public MetaspaceClosure { 300 static const int INITIAL_TABLE_SIZE = 15889; 301 static const int MAX_TABLE_SIZE = 1000000; 302 303 // Do not override. Returns true if we are discovering ref->obj() for the first time. 304 virtual bool do_ref(Ref* ref, bool read_only); 305 306 public: 307 // Gets called the first time we discover an object. 308 virtual bool do_unique_ref(Ref* ref, bool read_only) = 0; 309 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {} 310 311 private: 312 KVHashtable<address, bool, mtInternal> _has_been_visited; 313 }; 314 315 #endif // SHARE_MEMORY_METASPACECLOSURE_HPP