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