99 // MetaspaceObj *_obj; |
99 // MetaspaceObj *_obj; |
100 // Array<int>* foo() { return (Array<int>*)_obj; } |
100 // Array<int>* foo() { return (Array<int>*)_obj; } |
101 // Symbol* bar() { return (Symbol*) _obj; } |
101 // Symbol* bar() { return (Symbol*) _obj; } |
102 // |
102 // |
103 // [2] All Array<T> dimensions are statically declared. |
103 // [2] All Array<T> dimensions are statically declared. |
104 class Ref { |
104 class Ref : public CHeapObj<mtInternal> { |
|
105 Writability _writability; |
|
106 Ref* _next; |
|
107 // Noncopyable. |
|
108 Ref(const Ref&); |
|
109 Ref& operator=(const Ref&); |
105 protected: |
110 protected: |
106 virtual void** mpp() const = 0; |
111 virtual void** mpp() const = 0; |
|
112 Ref(Writability w) : _writability(w), _next(NULL) {} |
107 public: |
113 public: |
108 virtual bool not_null() const = 0; |
114 virtual bool not_null() const = 0; |
109 virtual int size() const = 0; |
115 virtual int size() const = 0; |
110 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0; |
116 virtual void metaspace_pointers_do(MetaspaceClosure *it) const = 0; |
111 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0; |
117 virtual void metaspace_pointers_do_at(MetaspaceClosure *it, address new_loc) const = 0; |
112 virtual MetaspaceObj::Type msotype() const = 0; |
118 virtual MetaspaceObj::Type msotype() const = 0; |
113 virtual bool is_read_only_by_default() const = 0; |
119 virtual bool is_read_only_by_default() const = 0; |
|
120 virtual ~Ref() {} |
114 |
121 |
115 address obj() const { |
122 address obj() const { |
116 // In some rare cases (see CPSlot in constantPool.hpp) we store some flags in the lowest |
123 // In some rare cases (see CPSlot in constantPool.hpp) we store some flags in the lowest |
117 // 2 bits of a MetaspaceObj pointer. Unmask these when manipulating the pointer. |
124 // 2 bits of a MetaspaceObj pointer. Unmask these when manipulating the pointer. |
118 uintx p = (uintx)*mpp(); |
125 uintx p = (uintx)*mpp(); |
119 return (address)(p & (~FLAG_MASK)); |
126 return (address)(p & (~FLAG_MASK)); |
120 } |
127 } |
121 |
128 |
|
129 address* addr() const { |
|
130 return (address*)mpp(); |
|
131 } |
|
132 |
122 void update(address new_loc) const; |
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; } |
123 |
138 |
124 private: |
139 private: |
125 static const uintx FLAG_MASK = 0x03; |
140 static const uintx FLAG_MASK = 0x03; |
126 |
141 |
127 int flag_bits() const { |
142 int flag_bits() const { |
141 virtual void** mpp() const { |
156 virtual void** mpp() const { |
142 return (void**)_mpp; |
157 return (void**)_mpp; |
143 } |
158 } |
144 |
159 |
145 public: |
160 public: |
146 ObjectRef(T** mpp) : _mpp(mpp) {} |
161 ObjectRef(T** mpp, Writability w) : Ref(w), _mpp(mpp) {} |
147 |
162 |
148 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); } |
163 virtual bool is_read_only_by_default() const { return T::is_read_only_by_default(); } |
149 virtual bool not_null() const { return dereference() != NULL; } |
164 virtual bool not_null() const { return dereference() != NULL; } |
150 virtual int size() const { return dereference()->size(); } |
165 virtual int size() const { return dereference()->size(); } |
151 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); } |
166 virtual MetaspaceObj::Type msotype() const { return dereference()->type(); } |
168 virtual void** mpp() const { |
183 virtual void** mpp() const { |
169 return (void**)_mpp; |
184 return (void**)_mpp; |
170 } |
185 } |
171 |
186 |
172 public: |
187 public: |
173 PrimitiveArrayRef(Array<T>** mpp) : _mpp(mpp) {} |
188 PrimitiveArrayRef(Array<T>** mpp, Writability w) : Ref(w), _mpp(mpp) {} |
174 |
189 |
175 // all Arrays are read-only by default |
190 // all Arrays are read-only by default |
176 virtual bool is_read_only_by_default() const { return true; } |
191 virtual bool is_read_only_by_default() const { return true; } |
177 virtual bool not_null() const { return dereference() != NULL; } |
192 virtual bool not_null() const { return dereference() != NULL; } |
178 virtual int size() const { return dereference()->size(); } |
193 virtual int size() const { return dereference()->size(); } |
198 virtual void** mpp() const { |
213 virtual void** mpp() const { |
199 return (void**)_mpp; |
214 return (void**)_mpp; |
200 } |
215 } |
201 |
216 |
202 public: |
217 public: |
203 PointerArrayRef(Array<T*>** mpp) : _mpp(mpp) {} |
218 PointerArrayRef(Array<T*>** mpp, Writability w) : Ref(w), _mpp(mpp) {} |
204 |
219 |
205 // all Arrays are read-only by default |
220 // all Arrays are read-only by default |
206 virtual bool is_read_only_by_default() const { return true; } |
221 virtual bool is_read_only_by_default() const { return true; } |
207 virtual bool not_null() const { return dereference() != NULL; } |
222 virtual bool not_null() const { return dereference() != NULL; } |
208 virtual int size() const { return dereference()->size(); } |
223 virtual int size() const { return dereference()->size(); } |
222 it->push(mpp); |
237 it->push(mpp); |
223 } |
238 } |
224 } |
239 } |
225 }; |
240 }; |
226 |
241 |
227 void push_impl(Ref* ref, Writability w); |
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); |
228 |
250 |
229 public: |
251 public: |
|
252 MetaspaceClosure(): _pending_refs(NULL), _nest_level(0) {} |
|
253 ~MetaspaceClosure(); |
|
254 |
|
255 void finish(); |
|
256 |
230 // returns true if we want to keep iterating the pointers embedded inside <ref> |
257 // returns true if we want to keep iterating the pointers embedded inside <ref> |
231 virtual bool do_ref(Ref* ref, bool read_only) = 0; |
258 virtual bool do_ref(Ref* ref, bool read_only) = 0; |
232 |
259 |
233 // When you do: |
260 // When you do: |
234 // void MyType::metaspace_pointers_do(MetaspaceClosure* it) { |
261 // void MyType::metaspace_pointers_do(MetaspaceClosure* it) { |
235 // it->push(_my_field) |
262 // it->push(_my_field) |
236 // |
263 // |
237 // C++ will try to match the "most specific" template function. This one will |
264 // C++ will try to match the "most specific" template function. This one will |
238 // will be matched if possible (if mpp is an Array<> of any pointer type). |
265 // will be matched if possible (if mpp is an Array<> of any pointer type). |
239 template <typename T> void push(Array<T*>** mpp, Writability w = _default) { |
266 template <typename T> void push(Array<T*>** mpp, Writability w = _default) { |
240 PointerArrayRef<T> ref(mpp); |
267 push_impl(new PointerArrayRef<T>(mpp, w)); |
241 push_impl(&ref, w); |
|
242 } |
268 } |
243 |
269 |
244 // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then |
270 // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then |
245 // this is the second choice. |
271 // this is the second choice. |
246 template <typename T> void push(Array<T>** mpp, Writability w = _default) { |
272 template <typename T> void push(Array<T>** mpp, Writability w = _default) { |
247 PrimitiveArrayRef<T> ref(mpp); |
273 push_impl(new PrimitiveArrayRef<T>(mpp, w)); |
248 push_impl(&ref, w); |
|
249 } |
274 } |
250 |
275 |
251 // If the above function doesn't match (mpp is not an Array<> type), then |
276 // If the above function doesn't match (mpp is not an Array<> type), then |
252 // this will be matched by default. |
277 // this will be matched by default. |
253 template <class T> void push(T** mpp, Writability w = _default) { |
278 template <class T> void push(T** mpp, Writability w = _default) { |
254 ObjectRef<T> ref(mpp); |
279 push_impl(new ObjectRef<T>(mpp, w)); |
255 push_impl(&ref, w); |
|
256 } |
280 } |
257 }; |
281 }; |
258 |
282 |
259 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. |
283 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once. |
260 class UniqueMetaspaceClosure : public MetaspaceClosure { |
284 class UniqueMetaspaceClosure : public MetaspaceClosure { |
264 // Do not override. Returns true if we are discovering ref->obj() for the first time. |
288 // Do not override. Returns true if we are discovering ref->obj() for the first time. |
265 virtual bool do_ref(Ref* ref, bool read_only); |
289 virtual bool do_ref(Ref* ref, bool read_only); |
266 |
290 |
267 public: |
291 public: |
268 // Gets called the first time we discover an object. |
292 // Gets called the first time we discover an object. |
269 virtual void do_unique_ref(Ref* ref, bool read_only) = 0; |
293 virtual bool do_unique_ref(Ref* ref, bool read_only) = 0; |
270 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {} |
294 UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {} |
271 |
295 |
272 private: |
296 private: |
273 KVHashtable<address, bool, mtInternal> _has_been_visited; |
297 KVHashtable<address, bool, mtInternal> _has_been_visited; |
274 }; |
298 }; |