src/share/vm/prims/jvmtiGetLoadedClasses.cpp

Thu, 08 Feb 2018 00:23:31 +0000

author
poonam
date
Thu, 08 Feb 2018 00:23:31 +0000
changeset 9195
9ffa7549c389
parent 6198
55fb97c4c58d
child 9203
53eec13fbaa5
permissions
-rw-r--r--

8187577: JVM crash during gc doing concurrent marking
Summary: Inform G1's SATB that a klass has been resurrected and it should not be unloaded
Reviewed-by: coleenp, tschatzl, kbarrett

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

mercurial