src/share/vm/prims/jvmtiGetLoadedClasses.cpp

Wed, 03 Jul 2019 20:42:37 +0800

author
aoqi
date
Wed, 03 Jul 2019 20:42:37 +0800
changeset 9637
eef07cd490d4
parent 9203
53eec13fbaa5
permissions
-rw-r--r--

Merge

aoqi@0 1 /*
poonam@9195 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/systemDictionary.hpp"
aoqi@0 27 #include "memory/universe.inline.hpp"
aoqi@0 28 #include "prims/jvmtiGetLoadedClasses.hpp"
aoqi@0 29 #include "runtime/thread.hpp"
poonam@9195 30 #if INCLUDE_ALL_GCS
poonam@9195 31 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
poonam@9195 32 #endif
aoqi@0 33
aoqi@0 34
aoqi@0 35 // The closure for GetLoadedClasses
aoqi@0 36 class LoadedClassesClosure : public KlassClosure {
aoqi@0 37 private:
aoqi@0 38 Stack<jclass, mtInternal> _classStack;
aoqi@0 39 JvmtiEnv* _env;
aoqi@0 40
poonam@9195 41 // Tell the GC to keep this klass alive
poonam@9195 42 static void ensure_klass_alive(oop o) {
poonam@9195 43 // A klass that was previously considered dead can be looked up in the
poonam@9195 44 // CLD/SD, and its _java_mirror or _class_loader can be stored in a root
poonam@9195 45 // or a reachable object making it alive again. The SATB part of G1 needs
poonam@9195 46 // to get notified about this potential resurrection, otherwise the marking
poonam@9195 47 // might not find the object.
poonam@9195 48 #if INCLUDE_ALL_GCS
poonam@9195 49 if (UseG1GC && o != NULL) {
poonam@9195 50 G1SATBCardTableModRefBS::enqueue(o);
poonam@9195 51 }
poonam@9195 52 #endif
poonam@9195 53 }
poonam@9195 54
aoqi@0 55 public:
aoqi@0 56 LoadedClassesClosure(JvmtiEnv* env) {
aoqi@0 57 _env = env;
aoqi@0 58 }
aoqi@0 59
aoqi@0 60 void do_klass(Klass* k) {
aoqi@0 61 // Collect all jclasses
aoqi@0 62 _classStack.push((jclass) _env->jni_reference(k->java_mirror()));
poonam@9195 63 ensure_klass_alive(k->java_mirror());
aoqi@0 64 }
aoqi@0 65
aoqi@0 66 int extract(jclass* result_list) {
aoqi@0 67 // The size of the Stack will be 0 after extract, so get it here
aoqi@0 68 int count = (int)_classStack.size();
aoqi@0 69 int i = count;
aoqi@0 70
aoqi@0 71 // Pop all jclasses, fill backwards
aoqi@0 72 while (!_classStack.is_empty()) {
aoqi@0 73 result_list[--i] = _classStack.pop();
aoqi@0 74 }
aoqi@0 75
aoqi@0 76 // Return the number of elements written
aoqi@0 77 return count;
aoqi@0 78 }
aoqi@0 79
aoqi@0 80 // Return current size of the Stack
aoqi@0 81 int get_count() {
aoqi@0 82 return (int)_classStack.size();
aoqi@0 83 }
aoqi@0 84 };
aoqi@0 85
aoqi@0 86 // The closure for GetClassLoaderClasses
aoqi@0 87 class JvmtiGetLoadedClassesClosure : public StackObj {
aoqi@0 88 // Since the SystemDictionary::classes_do callback
aoqi@0 89 // doesn't pass a closureData pointer,
aoqi@0 90 // we use a thread-local slot to hold a pointer to
aoqi@0 91 // a stack allocated instance of this structure.
aoqi@0 92 private:
aoqi@0 93 jobject _initiatingLoader;
aoqi@0 94 int _count;
aoqi@0 95 Handle* _list;
aoqi@0 96 int _index;
aoqi@0 97
aoqi@0 98 private:
aoqi@0 99 // Getting and setting the thread local pointer
aoqi@0 100 static JvmtiGetLoadedClassesClosure* get_this() {
aoqi@0 101 JvmtiGetLoadedClassesClosure* result = NULL;
aoqi@0 102 JavaThread* thread = JavaThread::current();
aoqi@0 103 result = thread->get_jvmti_get_loaded_classes_closure();
aoqi@0 104 return result;
aoqi@0 105 }
aoqi@0 106 static void set_this(JvmtiGetLoadedClassesClosure* that) {
aoqi@0 107 JavaThread* thread = JavaThread::current();
aoqi@0 108 thread->set_jvmti_get_loaded_classes_closure(that);
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 public:
aoqi@0 112 // Constructor/Destructor
aoqi@0 113 JvmtiGetLoadedClassesClosure() {
aoqi@0 114 JvmtiGetLoadedClassesClosure* that = get_this();
aoqi@0 115 assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
aoqi@0 116 _initiatingLoader = NULL;
aoqi@0 117 _count = 0;
aoqi@0 118 _list = NULL;
aoqi@0 119 _index = 0;
aoqi@0 120 set_this(this);
aoqi@0 121 }
aoqi@0 122
aoqi@0 123 JvmtiGetLoadedClassesClosure(jobject initiatingLoader) {
aoqi@0 124 JvmtiGetLoadedClassesClosure* that = get_this();
aoqi@0 125 assert(that == NULL, "JvmtiGetLoadedClassesClosure in use");
aoqi@0 126 _initiatingLoader = initiatingLoader;
aoqi@0 127 _count = 0;
aoqi@0 128 _list = NULL;
aoqi@0 129 _index = 0;
aoqi@0 130 set_this(this);
aoqi@0 131 }
aoqi@0 132
aoqi@0 133 ~JvmtiGetLoadedClassesClosure() {
aoqi@0 134 JvmtiGetLoadedClassesClosure* that = get_this();
aoqi@0 135 assert(that != NULL, "JvmtiGetLoadedClassesClosure not found");
aoqi@0 136 set_this(NULL);
aoqi@0 137 _initiatingLoader = NULL;
aoqi@0 138 _count = 0;
aoqi@0 139 if (_list != NULL) {
aoqi@0 140 FreeHeap(_list);
aoqi@0 141 _list = NULL;
aoqi@0 142 }
aoqi@0 143 _index = 0;
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 // Accessors.
aoqi@0 147 jobject get_initiatingLoader() {
aoqi@0 148 return _initiatingLoader;
aoqi@0 149 }
aoqi@0 150
aoqi@0 151 int get_count() {
aoqi@0 152 return _count;
aoqi@0 153 }
aoqi@0 154
aoqi@0 155 void set_count(int value) {
aoqi@0 156 _count = value;
aoqi@0 157 }
aoqi@0 158
aoqi@0 159 Handle* get_list() {
aoqi@0 160 return _list;
aoqi@0 161 }
aoqi@0 162
aoqi@0 163 void set_list(Handle* value) {
aoqi@0 164 _list = value;
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 int get_index() {
aoqi@0 168 return _index;
aoqi@0 169 }
aoqi@0 170
aoqi@0 171 void set_index(int value) {
aoqi@0 172 _index = value;
aoqi@0 173 }
aoqi@0 174
aoqi@0 175 Handle get_element(int index) {
aoqi@0 176 if ((_list != NULL) && (index < _count)) {
aoqi@0 177 return _list[index];
aoqi@0 178 } else {
aoqi@0 179 assert(false, "empty get_element");
aoqi@0 180 return Handle();
aoqi@0 181 }
aoqi@0 182 }
aoqi@0 183
aoqi@0 184 void set_element(int index, Handle value) {
aoqi@0 185 if ((_list != NULL) && (index < _count)) {
aoqi@0 186 _list[index] = value;
aoqi@0 187 } else {
aoqi@0 188 assert(false, "bad set_element");
aoqi@0 189 }
aoqi@0 190 }
aoqi@0 191
aoqi@0 192 // Other predicates
aoqi@0 193 bool available() {
aoqi@0 194 return (_list != NULL);
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 #ifdef ASSERT
aoqi@0 198 // For debugging.
aoqi@0 199 void check(int limit) {
aoqi@0 200 for (int i = 0; i < limit; i += 1) {
aoqi@0 201 assert(Universe::heap()->is_in(get_element(i)()), "check fails");
aoqi@0 202 }
aoqi@0 203 }
aoqi@0 204 #endif
aoqi@0 205
aoqi@0 206 // Public methods that get called within the scope of the closure
aoqi@0 207 void allocate() {
aoqi@0 208 _list = NEW_C_HEAP_ARRAY(Handle, _count, mtInternal);
aoqi@0 209 assert(_list != NULL, "Out of memory");
aoqi@0 210 if (_list == NULL) {
aoqi@0 211 _count = 0;
aoqi@0 212 }
aoqi@0 213 }
aoqi@0 214
aoqi@0 215 void extract(JvmtiEnv *env, jclass* result) {
aoqi@0 216 for (int index = 0; index < _count; index += 1) {
aoqi@0 217 result[index] = (jclass) env->jni_reference(get_element(index));
aoqi@0 218 }
aoqi@0 219 }
aoqi@0 220
aoqi@0 221 static void increment_with_loader(Klass* k, ClassLoaderData* loader_data) {
aoqi@0 222 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
aoqi@0 223 oop class_loader = loader_data->class_loader();
aoqi@0 224 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
aoqi@0 225 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
aoqi@0 226 that->set_count(that->get_count() + 1);
aoqi@0 227 }
aoqi@0 228 }
aoqi@0 229 }
aoqi@0 230
aoqi@0 231 static void prim_array_increment_with_loader(Klass* array, ClassLoaderData* loader_data) {
aoqi@0 232 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
aoqi@0 233 oop class_loader = loader_data->class_loader();
aoqi@0 234 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
aoqi@0 235 that->set_count(that->get_count() + 1);
aoqi@0 236 }
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 static void add_with_loader(Klass* k, ClassLoaderData* loader_data) {
aoqi@0 240 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
aoqi@0 241 if (that->available()) {
aoqi@0 242 oop class_loader = loader_data->class_loader();
aoqi@0 243 if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
aoqi@0 244 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
aoqi@0 245 oop mirror = l->java_mirror();
aoqi@0 246 that->set_element(that->get_index(), mirror);
aoqi@0 247 that->set_index(that->get_index() + 1);
aoqi@0 248 }
aoqi@0 249 }
aoqi@0 250 }
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 // increment the count for the given basic type array class (and any
aoqi@0 254 // multi-dimensional arrays). For example, for [B we check for
aoqi@0 255 // [[B, [[[B, .. and the count is incremented for each one that exists.
aoqi@0 256 static void increment_for_basic_type_arrays(Klass* k) {
aoqi@0 257 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
aoqi@0 258 assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
aoqi@0 259 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
aoqi@0 260 that->set_count(that->get_count() + 1);
aoqi@0 261 }
aoqi@0 262 }
aoqi@0 263
aoqi@0 264 // add the basic type array class and its multi-dimensional array classes to the list
aoqi@0 265 static void add_for_basic_type_arrays(Klass* k) {
aoqi@0 266 JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
aoqi@0 267 assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
aoqi@0 268 assert(that->available(), "no list");
aoqi@0 269 for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
aoqi@0 270 oop mirror = l->java_mirror();
aoqi@0 271 that->set_element(that->get_index(), mirror);
aoqi@0 272 that->set_index(that->get_index() + 1);
aoqi@0 273 }
aoqi@0 274 }
aoqi@0 275 };
aoqi@0 276
aoqi@0 277
aoqi@0 278 jvmtiError
aoqi@0 279 JvmtiGetLoadedClasses::getLoadedClasses(JvmtiEnv *env, jint* classCountPtr, jclass** classesPtr) {
aoqi@0 280
aoqi@0 281 LoadedClassesClosure closure(env);
aoqi@0 282 {
aoqi@0 283 // To get a consistent list of classes we need MultiArray_lock to ensure
aoqi@0 284 // array classes aren't created.
aoqi@0 285 MutexLocker ma(MultiArray_lock);
aoqi@0 286
aoqi@0 287 // Iterate through all classes in ClassLoaderDataGraph
aoqi@0 288 // and collect them using the LoadedClassesClosure
aoqi@0 289 ClassLoaderDataGraph::loaded_classes_do(&closure);
aoqi@0 290 }
aoqi@0 291
aoqi@0 292 // Return results by extracting the collected contents into a list
aoqi@0 293 // allocated via JvmtiEnv
aoqi@0 294 jclass* result_list;
aoqi@0 295 jvmtiError error = env->Allocate(closure.get_count() * sizeof(jclass),
aoqi@0 296 (unsigned char**)&result_list);
aoqi@0 297
aoqi@0 298 if (error == JVMTI_ERROR_NONE) {
aoqi@0 299 int count = closure.extract(result_list);
aoqi@0 300 *classCountPtr = count;
aoqi@0 301 *classesPtr = result_list;
aoqi@0 302 }
aoqi@0 303 return error;
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 jvmtiError
aoqi@0 307 JvmtiGetLoadedClasses::getClassLoaderClasses(JvmtiEnv *env, jobject initiatingLoader,
aoqi@0 308 jint* classCountPtr, jclass** classesPtr) {
aoqi@0 309 // Since SystemDictionary::classes_do only takes a function pointer
aoqi@0 310 // and doesn't call back with a closure data pointer,
aoqi@0 311 // we can only pass static methods.
aoqi@0 312 JvmtiGetLoadedClassesClosure closure(initiatingLoader);
aoqi@0 313 {
aoqi@0 314 // To get a consistent list of classes we need MultiArray_lock to ensure
aoqi@0 315 // array classes aren't created, and SystemDictionary_lock to ensure that
aoqi@0 316 // classes aren't added to the system dictionary,
aoqi@0 317 MutexLocker ma(MultiArray_lock);
aoqi@0 318 MutexLocker sd(SystemDictionary_lock);
aoqi@0 319 // First, count the classes in the system dictionary which have this loader recorded
aoqi@0 320 // as an initiating loader. For basic type arrays this information is not recorded
aoqi@0 321 // so GetClassLoaderClasses will return all of the basic type arrays. This is okay
aoqi@0 322 // because the defining loader for basic type arrays is always the boot class loader
aoqi@0 323 // and these classes are "visible" to all loaders.
aoqi@0 324 SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::increment_with_loader);
aoqi@0 325 Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::increment_for_basic_type_arrays);
aoqi@0 326 // Next, fill in the classes
aoqi@0 327 closure.allocate();
aoqi@0 328 SystemDictionary::classes_do(&JvmtiGetLoadedClassesClosure::add_with_loader);
aoqi@0 329 Universe::basic_type_classes_do(&JvmtiGetLoadedClassesClosure::add_for_basic_type_arrays);
aoqi@0 330 // Drop the SystemDictionary_lock, so the results could be wrong from here,
aoqi@0 331 // but we still have a snapshot.
aoqi@0 332 }
aoqi@0 333 // Post results
aoqi@0 334 jclass* result_list;
aoqi@0 335 jvmtiError err = env->Allocate(closure.get_count() * sizeof(jclass),
aoqi@0 336 (unsigned char**)&result_list);
aoqi@0 337 if (err != JVMTI_ERROR_NONE) {
aoqi@0 338 return err;
aoqi@0 339 }
aoqi@0 340 closure.extract(env, result_list);
aoqi@0 341 *classCountPtr = closure.get_count();
aoqi@0 342 *classesPtr = result_list;
aoqi@0 343 return JVMTI_ERROR_NONE;
aoqi@0 344 }

mercurial