1 /* |
1 /* |
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
34 // The closure for GetLoadedClasses |
34 // The closure for GetLoadedClasses |
35 class LoadedClassesClosure : public KlassClosure { |
35 class LoadedClassesClosure : public KlassClosure { |
36 private: |
36 private: |
37 Stack<jclass, mtInternal> _classStack; |
37 Stack<jclass, mtInternal> _classStack; |
38 JvmtiEnv* _env; |
38 JvmtiEnv* _env; |
|
39 Thread* _cur_thread; |
39 |
40 |
40 public: |
41 public: |
41 LoadedClassesClosure(JvmtiEnv* env) { |
42 LoadedClassesClosure(Thread* thread, JvmtiEnv* env) : _cur_thread(thread), _env(env) { |
42 _env = env; |
43 assert(_cur_thread == Thread::current(), "must be current thread"); |
43 } |
44 } |
44 |
45 |
45 void do_klass(Klass* k) { |
46 void do_klass(Klass* k) { |
46 // Collect all jclasses |
47 // Collect all jclasses |
47 _classStack.push((jclass) _env->jni_reference(k->java_mirror())); |
48 _classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror()))); |
48 } |
49 } |
49 |
50 |
50 int extract(jclass* result_list) { |
51 int extract(jclass* result_list) { |
51 // The size of the Stack will be 0 after extract, so get it here |
52 // The size of the Stack will be 0 after extract, so get it here |
52 int count = (int)_classStack.size(); |
53 int count = (int)_classStack.size(); |
223 static void add_with_loader(Klass* k, ClassLoaderData* loader_data) { |
224 static void add_with_loader(Klass* k, ClassLoaderData* loader_data) { |
224 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this(); |
225 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this(); |
225 if (that->available()) { |
226 if (that->available()) { |
226 oop class_loader = loader_data->class_loader(); |
227 oop class_loader = loader_data->class_loader(); |
227 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) { |
228 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) { |
|
229 Thread *thread = Thread::current(); |
228 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) { |
230 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) { |
229 oop mirror = l->java_mirror(); |
231 Handle mirror(thread, l->java_mirror()); |
230 that->set_element(that->get_index(), mirror); |
232 that->set_element(that->get_index(), mirror); |
231 that->set_index(that->get_index() + 1); |
233 that->set_index(that->get_index() + 1); |
232 } |
234 } |
233 } |
235 } |
234 } |
236 } |
248 // add the basic type array class and its multi-dimensional array classes to the list |
250 // add the basic type array class and its multi-dimensional array classes to the list |
249 static void add_for_basic_type_arrays(Klass* k) { |
251 static void add_for_basic_type_arrays(Klass* k) { |
250 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this(); |
252 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this(); |
251 assert(that != NULL, "no JvmtiGetLoadedClassesClosure"); |
253 assert(that != NULL, "no JvmtiGetLoadedClassesClosure"); |
252 assert(that->available(), "no list"); |
254 assert(that->available(), "no list"); |
|
255 Thread *thread = Thread::current(); |
253 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) { |
256 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) { |
254 oop mirror = l->java_mirror(); |
257 Handle mirror(thread, l->java_mirror()); |
255 that->set_element(that->get_index(), mirror); |
258 that->set_element(that->get_index(), mirror); |
256 that->set_index(that->get_index() + 1); |
259 that->set_index(that->get_index() + 1); |
257 } |
260 } |
258 } |
261 } |
259 }; |
262 }; |
260 |
263 |
261 |
264 |
262 jvmtiError |
265 jvmtiError |
263 JvmtiGetLoadedClasses::getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr) { |
266 JvmtiGetLoadedClasses::getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr) { |
264 |
267 |
265 LoadedClassesClosure closure(env); |
268 LoadedClassesClosure closure(Thread::current(), env); |
266 { |
269 { |
267 // To get a consistent list of classes we need MultiArray_lock to ensure |
270 // To get a consistent list of classes we need MultiArray_lock to ensure |
268 // array classes aren't created. |
271 // array classes aren't created. |
269 MutexLocker ma(MultiArray_lock); |
272 MutexLocker ma(MultiArray_lock); |
270 |
273 |