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