1 /*
2 * Copyright (c) 2003, 2018, 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 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "memory/universe.inline.hpp"
28 #include "prims/jvmtiGetLoadedClasses.hpp"
29 #include "runtime/thread.hpp"
30 #if INCLUDE_ALL_GCS
31 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
32 #endif
33
34
35 // The closure for GetLoadedClasses
36 class LoadedClassesClosure : public KlassClosure {
37 private:
38 Stack<jclass, mtInternal> _classStack;
39 JvmtiEnv* _env;
40
41 // Tell the GC to keep this klass alive
ensure_klass_alive(oop o)42 static void ensure_klass_alive(oop o) {
43 // A klass that was previously considered dead can be looked up in the
44 // CLD/SD, and its _java_mirror or _class_loader can be stored in a root
45 // or a reachable object making it alive again. The SATB part of G1 needs
46 // to get notified about this potential resurrection, otherwise the marking
47 // might not find the object.
48 #if INCLUDE_ALL_GCS
49 if (UseG1GC && o != NULL) {
50 G1SATBCardTableModRefBS::enqueue(o);
51 }
52 #endif
53 }
54
55 public:
LoadedClassesClosure(JvmtiEnv * env)56 LoadedClassesClosure(JvmtiEnv* env) {
57 _env = env;
58 }
59
do_klass(Klass * k)60 void do_klass(Klass* k) {
61 // Collect all jclasses
62 _classStack.push((jclass) _env->jni_reference(k->java_mirror()));
63 ensure_klass_alive(k->java_mirror());
64 }
65
extract(jclass * result_list)66 int extract(jclass* result_list) {
67 // The size of the Stack will be 0 after extract, so get it here
68 int count = (int)_classStack.size();
69 int i = count;
70
71 // Pop all jclasses, fill backwards
72 while (!_classStack.is_empty()) {
73 result_list[--i] = _classStack.pop();
74 }
75
76 // Return the number of elements written
77 return count;
78 }
79
80 // Return current size of the Stack
get_count()81 int get_count() {
82 return (int)_classStack.size();
83 }
84 };
85
86 // The closure for GetClassLoaderClasses
87 class JvmtiGetLoadedClassesClosure : public StackObj {
88 // Since the SystemDictionary::classes_do callback
89 // doesn't pass a closureData pointer,
90 // we use a thread-local slot to hold a pointer to
91 // a stack allocated instance of this structure.
92 private:
93 jobject _initiatingLoader;
94 int _count;
95 Handle* _list;
96 int _index;
97
98 private:
99 // Getting and setting the thread local pointer
get_this()100 static JvmtiGetLoadedClassesClosure* get_this() {
101 JvmtiGetLoadedClassesClosure* result = NULL;
102 JavaThread* thread = JavaThread::current();
103 result = thread->get_jvmti_get_loaded_classes_closure();
104 return result;
105 }
set_this(JvmtiGetLoadedClassesClosure * that)106 static void set_this(JvmtiGetLoadedClassesClosure* that) {
107 JavaThread* thread = JavaThread::current();
108 thread->set_jvmti_get_loaded_classes_closure(that);
109 }
110
111 public:
112 // Constructor/Destructor
JvmtiGetLoadedClassesClosure()113 JvmtiGetLoadedClassesClosure() {
114 JvmtiGetLoadedClassesClosure* that = get_this();
115 assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
116 _initiatingLoader = NULL;
117 _count = 0;
118 _list = NULL;
119 _index = 0;
120 set_this(this);
121 }
122
JvmtiGetLoadedClassesClosure(jobject initiatingLoader)123 JvmtiGetLoadedClassesClosure(jobject initiatingLoader) {
124 JvmtiGetLoadedClassesClosure* that = get_this();
125 assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
126 _initiatingLoader = initiatingLoader;
127 _count = 0;
128 _list = NULL;
129 _index = 0;
130 set_this(this);
131 }
132
~JvmtiGetLoadedClassesClosure()133 ~JvmtiGetLoadedClassesClosure() {
134 JvmtiGetLoadedClassesClosure* that = get_this();
135 assert(that != NULL, "JvmtiGetLoadedClassesClosure not found");
136 set_this(NULL);
137 _initiatingLoader = NULL;
138 _count = 0;
139 if (_list != NULL) {
140 FreeHeap(_list);
141 _list = NULL;
142 }
143 _index = 0;
144 }
145
146 // Accessors.
get_initiatingLoader()147 jobject get_initiatingLoader() {
148 return _initiatingLoader;
149 }
150
get_count()151 int get_count() {
152 return _count;
153 }
154
set_count(int value)155 void set_count(int value) {
156 _count = value;
157 }
158
get_list()159 Handle* get_list() {
160 return _list;
161 }
162
set_list(Handle * value)163 void set_list(Handle* value) {
164 _list = value;
165 }
166
get_index()167 int get_index() {
168 return _index;
169 }
170
set_index(int value)171 void set_index(int value) {
172 _index = value;
173 }
174
get_element(int index)175 Handle get_element(int index) {
176 if ((_list != NULL) && (index < _count)) {
177 return _list[index];
178 } else {
179 assert(false, "empty get_element");
180 return Handle();
181 }
182 }
183
set_element(int index,Handle value)184 void set_element(int index, Handle value) {
185 if ((_list != NULL) && (index < _count)) {
186 _list[index] = value;
187 } else {
188 assert(false, "bad set_element");
189 }
190 }
191
192 // Other predicates
available()193 bool available() {
194 return (_list != NULL);
195 }
196
197 #ifdef ASSERT
198 // For debugging.
check(int limit)199 void check(int limit) {
200 for (int i = 0; i < limit; i += 1) {
201 assert(Universe::heap()->is_in(get_element(i)()), "check fails");
202 }
203 }
204 #endif
205
206 // Public methods that get called within the scope of the closure
allocate()207 void allocate() {
208 _list = NEW_C_HEAP_ARRAY(Handle, _count, mtInternal);
209 assert(_list != NULL, "Out of memory");
210 if (_list == NULL) {
211 _count = 0;
212 }
213 }
214
extract(JvmtiEnv * env,jclass * result)215 void extract(JvmtiEnv *env, jclass* result) {
216 for (int index = 0; index < _count; index += 1) {
217 result[index] = (jclass) env->jni_reference(get_element(index));
218 }
219 }
220
increment_with_loader(Klass * k,ClassLoaderData * loader_data)221 static void increment_with_loader(Klass* k, ClassLoaderData* loader_data) {
222 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
223 oop class_loader = loader_data->class_loader();
224 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
225 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
226 that->set_count(that->get_count() + 1);
227 }
228 }
229 }
230
prim_array_increment_with_loader(Klass * array,ClassLoaderData * loader_data)231 static void prim_array_increment_with_loader(Klass* array, ClassLoaderData* loader_data) {
232 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
233 oop class_loader = loader_data->class_loader();
234 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
235 that->set_count(that->get_count() + 1);
236 }
237 }
238
add_with_loader(Klass * k,ClassLoaderData * loader_data)239 static void add_with_loader(Klass* k, ClassLoaderData* loader_data) {
240 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
241 if (that->available()) {
242 oop class_loader = loader_data->class_loader();
243 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
244 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
245 oop mirror = l->java_mirror();
246 that->set_element(that->get_index(), mirror);
247 that->set_index(that->get_index() + 1);
248 }
249 }
250 }
251 }
252
253 // increment the count for the given basic type array class (and any
254 // multi-dimensional arrays). For example, for [B we check for
255 // [[B, [[[B, .. and the count is incremented for each one that exists.
increment_for_basic_type_arrays(Klass * k)256 static void increment_for_basic_type_arrays(Klass* k) {
257 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
258 assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
259 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
260 that->set_count(that->get_count() + 1);
261 }
262 }
263
264 // add the basic type array class and its multi-dimensional array classes to the list
add_for_basic_type_arrays(Klass * k)265 static void add_for_basic_type_arrays(Klass* k) {
266 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
267 assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
268 assert(that->available(), "no list");
269 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
270 oop mirror = l->java_mirror();
271 that->set_element(that->get_index(), mirror);
272 that->set_index(that->get_index() + 1);
273 }
274 }
275 };
276
277
278 jvmtiError
getLoadedClasses(JvmtiEnv * env,jint * classCountPtr,jclass ** classesPtr)279 JvmtiGetLoadedClasses::getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr) {
280
281 LoadedClassesClosure closure(env);
282 {
283 // To get a consistent list of classes we need MultiArray_lock to ensure
284 // array classes aren't created.
285 MutexLocker ma(MultiArray_lock);
286
287 // Iterate through all classes in ClassLoaderDataGraph
288 // and collect them using the LoadedClassesClosure
289 ClassLoaderDataGraph::loaded_classes_do(&closure);
290 }
291
292 // Return results by extracting the collected contents into a list
293 // allocated via JvmtiEnv
294 jclass* result_list;
295 jvmtiError error = env->Allocate(closure.get_count() * sizeof(jclass),
296 (unsigned char**)&result_list);
297
298 if (error == JVMTI_ERROR_NONE) {
299 int count = closure.extract(result_list);
300 *classCountPtr = count;
301 *classesPtr = result_list;
302 }
303 return error;
304 }
305
306 jvmtiError
getClassLoaderClasses(JvmtiEnv * env,jobject initiatingLoader,jint * classCountPtr,jclass ** classesPtr)307 JvmtiGetLoadedClasses::getClassLoaderClasses(JvmtiEnv *env, jobject initiatingLoader,
308 jint* classCountPtr, jclass** classesPtr) {
309 // Since SystemDictionary::classes_do only takes a function pointer
310 // and doesn't call back with a closure data pointer,
311 // we can only pass static methods.
312 JvmtiGetLoadedClassesClosure closure(initiatingLoader);
313 {
314 // To get a consistent list of classes we need MultiArray_lock to ensure
315 // array classes aren't created, and SystemDictionary_lock to ensure that
316 // classes aren't added to the system dictionary,
317 MutexLocker ma(MultiArray_lock);
318 MutexLocker sd(SystemDictionary_lock);
319 // First, count the classes in the system dictionary which have this loader recorded
320 // as an initiating loader. For basic type arrays this information is not recorded
321 // so GetClassLoaderClasses will return all of the basic type arrays. This is okay
322 // because the defining loader for basic type arrays is always the boot class loader
323 // and these classes are "visible" to all loaders.
324 SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::increment_with_loader);
325 Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::increment_for_basic_type_arrays);
326 // Next, fill in the classes
327 closure.allocate();
328 SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::add_with_loader);
329 Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::add_for_basic_type_arrays);
330 // Drop the SystemDictionary_lock, so the results could be wrong from here,
331 // but we still have a snapshot.
332 }
333 // Post results
334 jclass* result_list;
335 jvmtiError err = env->Allocate(closure.get_count() * sizeof(jclass),
336 (unsigned char**)&result_list);
337 if (err != JVMTI_ERROR_NONE) {
338 return err;
339 }
340 closure.extract(env, result_list);
341 *classCountPtr = closure.get_count();
342 *classesPtr = result_list;
343 return JVMTI_ERROR_NONE;
344 }
345