src/share/vm/prims/jvmtiGetLoadedClasses.cpp

Mon, 12 Nov 2012 16:15:05 -0500

author
hseigel
date
Mon, 12 Nov 2012 16:15:05 -0500
changeset 4278
070d523b96a7
parent 4037
da91efe96a93
child 6024
e64f1fe9756b
permissions
-rw-r--r--

8001471: Klass::cast() does nothing
Summary: Remove function Klass::cast() and calls to it.
Reviewed-by: dholmes, coleenp

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

mercurial