1 /*
2 * Copyright (c) 2017, 2023, 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/globalDefinitions.hpp"
33 #include "utilities/growableArray.hpp"
34 #include "utilities/macros.hpp"
35 #include "utilities/resizeableResourceHash.hpp"
36 #include <type_traits>
37
38 // The metadata hierarchy is separate from the oop hierarchy
39 class MetaspaceObj; // no C++ vtable
40 //class Array; // no C++ vtable
41 class Annotations; // no C++ vtable
42 class ConstantPoolCache; // no C++ vtable
43 class ConstMethod; // no C++ vtable
44 class MethodCounters; // no C++ vtable
45 class Symbol; // no C++ vtable
46 class Metadata; // has C++ vtable (so do all subclasses)
47 class ConstantPool;
48 class MethodData;
49 class Method;
50 class Klass;
51 class InstanceKlass;
87 // size_t size(); -- to determine how much data to copy
88 // void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers
89 //
90 // Calling these methods would be trivial if these two were virtual methods.
91 // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced
92 // only in the Metadata class.
93 //
94 // To work around the lack of a vtable, we use the Ref class with templates
95 // (see MSORef, OtherArrayRef, MSOArrayRef, and MSOPointerArrayRef)
96 // so that we can statically discover the type of a object. The use of Ref
97 // depends on the fact that:
98 //
99 // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses
100 // of Metadata. I.e., we don't do this:
101 // class Klass {
102 // MetaspaceObj *_obj;
103 // Array<int>* foo() { return (Array<int>*)_obj; }
104 // Symbol* bar() { return (Symbol*) _obj; }
105 //
106 // [2] All Array<T> dimensions are statically declared.
107 class Ref : public CHeapObj<mtMetaspace> {
108 Writability _writability;
109 address _enclosing_obj;
110 Ref* _next;
111 NONCOPYABLE(Ref);
112
113 protected:
114 virtual void** mpp() const = 0;
115 Ref(Writability w) : _writability(w), _enclosing_obj(nullptr), _next(nullptr) {}
116 public:
117 virtual bool not_null() const = 0;
118 virtual int size() const = 0;
119 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0;
120 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0;
121 virtual MetaspaceObj::Type msotype() const = 0;
122 virtual bool is_read_only_by_default() const = 0;
123 virtual ~Ref() {}
124
125 address obj() const {
126 return *addr();
127 }
128
129 address* addr() const {
130 return (address*)mpp();
131 }
132
133 // See comments in ArchiveBuilder::remember_embedded_pointer_in_enclosing_obj()
134 address enclosing_obj() const {
135 return _enclosing_obj;
136 }
137 void set_enclosing_obj(address obj) {
138 _enclosing_obj = obj;
139 }
140
141 Writability writability() const { return _writability; };
142 void set_next(Ref* n) { _next = n; }
143 Ref* next() const { return _next; }
144 };
145
146 private:
147 // MSORef -- iterate an instance of MetaspaceObj
148 template <class T> class MSORef : public Ref {
149 T** _mpp;
150 T* dereference() const {
151 return *_mpp;
152 }
153 protected:
154 virtual void** mpp() const {
155 return (void**)_mpp;
156 }
157
158 public:
159 MSORef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {}
160
161 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); }
162 virtual bool not_null() const { return dereference() != nullptr; }
163 virtual int size() const { return dereference()->size(); }
164 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); }
165
166 virtual void metaspace_pointers_do(MetaspaceClosure *it) const {
167 dereference()->metaspace_pointers_do(it);
168 }
169 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const {
170 ((T*)new_loc)->metaspace_pointers_do(it);
171 }
172 };
173
174 // abstract base class for MSOArrayRef, MSOPointerArrayRef and OtherArrayRef
175 template <class T> class ArrayRef : public Ref {
176 Array<T>** _mpp;
177 protected:
178 Array<T>* dereference() const {
179 return *_mpp;
180 }
181 virtual void** mpp() const {
182 return (void**)_mpp;
183 }
184
185 ArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {}
186
187 // all Arrays are read-only by default
188 virtual bool is_read_only_by_default() const { return true; }
189 virtual bool not_null() const { return dereference() != nullptr; }
190 virtual int size() const { return dereference()->size(); }
191 virtual MetaspaceObj::Type msotype() const { return MetaspaceObj::array_type(sizeof(T)); }
192 };
193
194 // OtherArrayRef -- iterate an instance of Array<T>, where T is NOT a subtype of MetaspaceObj.
195 // T can be a primitive type, such as int, or a structure. However, we do not scan
196 // the fields inside T, so you should not embed any pointers inside T.
197 template <class T> class OtherArrayRef : public ArrayRef<T> {
198 public:
199 OtherArrayRef(Array<T>** mpp, Writability w) : ArrayRef<T>(mpp, w) {}
|
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;
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) {}
|