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