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