| 1 | /* |
| 2 | * Copyright (c) 2018, 2019, 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 | #ifndef SHARE_CLASSFILE_CLASSLOADERDATAGRAPH_HPP |
| 26 | #define SHARE_CLASSFILE_CLASSLOADERDATAGRAPH_HPP |
| 27 | |
| 28 | #include "classfile/classLoaderData.hpp" |
| 29 | #include "memory/allocation.hpp" |
| 30 | #include "utilities/growableArray.hpp" |
| 31 | #include "utilities/macros.hpp" |
| 32 | |
| 33 | // GC root for walking class loader data created |
| 34 | |
| 35 | class ClassLoaderDataGraph : public AllStatic { |
| 36 | friend class ClassLoaderData; |
| 37 | friend class ClassLoaderDataGraphMetaspaceIterator; |
| 38 | friend class ClassLoaderDataGraphKlassIteratorAtomic; |
| 39 | friend class ClassLoaderDataGraphKlassIteratorStatic; |
| 40 | friend class ClassLoaderDataGraphIterator; |
| 41 | friend class VMStructs; |
| 42 | private: |
| 43 | // All CLDs (except the null CLD) can be reached by walking _head->_next->... |
| 44 | static ClassLoaderData* volatile _head; |
| 45 | static ClassLoaderData* _unloading; |
| 46 | // CMS support. |
| 47 | static ClassLoaderData* _saved_head; |
| 48 | static ClassLoaderData* _saved_unloading; |
| 49 | static bool _should_purge; |
| 50 | |
| 51 | // Set if there's anything to purge in the deallocate lists or previous versions |
| 52 | // during a safepoint after class unloading in a full GC. |
| 53 | static bool _should_clean_deallocate_lists; |
| 54 | static bool _safepoint_cleanup_needed; |
| 55 | |
| 56 | // OOM has been seen in metaspace allocation. Used to prevent some |
| 57 | // allocations until class unloading |
| 58 | static bool _metaspace_oom; |
| 59 | |
| 60 | static volatile size_t _num_instance_classes; |
| 61 | static volatile size_t _num_array_classes; |
| 62 | |
| 63 | static ClassLoaderData* add_to_graph(Handle class_loader, bool is_unsafe_anonymous); |
| 64 | static ClassLoaderData* add(Handle class_loader, bool is_unsafe_anonymous); |
| 65 | |
| 66 | public: |
| 67 | static ClassLoaderData* find_or_create(Handle class_loader); |
| 68 | static void clean_module_and_package_info(); |
| 69 | static void purge(); |
| 70 | static void clear_claimed_marks(); |
| 71 | static void clear_claimed_marks(int claim); |
| 72 | // Iteration through CLDG inside a safepoint; GC support |
| 73 | static void cld_do(CLDClosure* cl); |
| 74 | static void cld_unloading_do(CLDClosure* cl); |
| 75 | static void roots_cld_do(CLDClosure* strong, CLDClosure* weak); |
| 76 | static void always_strong_cld_do(CLDClosure* cl); |
| 77 | // Iteration through CLDG not by GC. |
| 78 | static void loaded_cld_do(CLDClosure* cl); |
| 79 | // klass do |
| 80 | // Walking classes through the ClassLoaderDataGraph include array classes. It also includes |
| 81 | // classes that are allocated but not loaded, classes that have errors, and scratch classes |
| 82 | // for redefinition. These classes are removed during the next class unloading. |
| 83 | // Walking the ClassLoaderDataGraph also includes unsafe anonymous classes. |
| 84 | static void classes_do(KlassClosure* klass_closure); |
| 85 | static void classes_do(void f(Klass* const)); |
| 86 | static void methods_do(void f(Method*)); |
| 87 | static void modules_do(void f(ModuleEntry*)); |
| 88 | static void modules_unloading_do(void f(ModuleEntry*)); |
| 89 | static void packages_do(void f(PackageEntry*)); |
| 90 | static void packages_unloading_do(void f(PackageEntry*)); |
| 91 | static void loaded_classes_do(KlassClosure* klass_closure); |
| 92 | static void unlocked_loaded_classes_do(KlassClosure* klass_closure); |
| 93 | static void classes_unloading_do(void f(Klass* const)); |
| 94 | static bool do_unloading(); |
| 95 | |
| 96 | // Expose state to avoid logging overhead in safepoint cleanup tasks. |
| 97 | static inline bool should_clean_metaspaces_and_reset(); |
| 98 | static void set_should_clean_deallocate_lists() { _should_clean_deallocate_lists = true; } |
| 99 | static void clean_deallocate_lists(bool purge_previous_versions); |
| 100 | static void walk_metadata_and_clean_metaspaces(); |
| 101 | |
| 102 | // dictionary do |
| 103 | // Iterate over all klasses in dictionary, but |
| 104 | // just the classes from defining class loaders. |
| 105 | static void dictionary_classes_do(void f(InstanceKlass*)); |
| 106 | // Added for initialize_itable_for_klass to handle exceptions. |
| 107 | static void dictionary_classes_do(void f(InstanceKlass*, TRAPS), TRAPS); |
| 108 | |
| 109 | // VM_CounterDecay iteration support |
| 110 | static InstanceKlass* try_get_next_class(); |
| 111 | static void adjust_saved_class(ClassLoaderData* cld); |
| 112 | static void adjust_saved_class(Klass* klass); |
| 113 | |
| 114 | static void verify_dictionary(); |
| 115 | static void print_dictionary(outputStream* st); |
| 116 | static void print_table_statistics(outputStream* st); |
| 117 | |
| 118 | // CMS support. |
| 119 | static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); } |
| 120 | static GrowableArray<ClassLoaderData*>* new_clds(); |
| 121 | |
| 122 | static void set_should_purge(bool b) { _should_purge = b; } |
| 123 | static bool should_purge_and_reset() { |
| 124 | bool res = _should_purge; |
| 125 | // reset for next time. |
| 126 | set_should_purge(false); |
| 127 | return res; |
| 128 | } |
| 129 | |
| 130 | static int resize_dictionaries(); |
| 131 | |
| 132 | static bool has_metaspace_oom() { return _metaspace_oom; } |
| 133 | static void set_metaspace_oom(bool value) { _metaspace_oom = value; } |
| 134 | |
| 135 | static void print_on(outputStream * const out) PRODUCT_RETURN; |
| 136 | static void print(); |
| 137 | static void verify(); |
| 138 | |
| 139 | // instance and array class counters |
| 140 | static inline size_t num_instance_classes(); |
| 141 | static inline size_t num_array_classes(); |
| 142 | static inline void inc_instance_classes(size_t count); |
| 143 | static inline void dec_instance_classes(size_t count); |
| 144 | static inline void inc_array_classes(size_t count); |
| 145 | static inline void dec_array_classes(size_t count); |
| 146 | |
| 147 | #ifndef PRODUCT |
| 148 | static bool contains_loader_data(ClassLoaderData* loader_data); |
| 149 | #endif |
| 150 | |
| 151 | // Check if ClassLoaderData is part of the ClassLoaderDataGraph (not unloaded) |
| 152 | // Usage without lock only allowed during error reporting. |
| 153 | static bool is_valid(ClassLoaderData* loader_data); |
| 154 | }; |
| 155 | |
| 156 | class LockedClassesDo : public KlassClosure { |
| 157 | typedef void (*classes_do_func_t)(Klass*); |
| 158 | classes_do_func_t _function; |
| 159 | public: |
| 160 | LockedClassesDo(); // For callers who provide their own do_klass |
| 161 | LockedClassesDo(classes_do_func_t function); |
| 162 | ~LockedClassesDo(); |
| 163 | |
| 164 | void do_klass(Klass* k) { |
| 165 | (*_function)(k); |
| 166 | } |
| 167 | }; |
| 168 | |
| 169 | // An iterator that distributes Klasses to parallel worker threads. |
| 170 | class ClassLoaderDataGraphKlassIteratorAtomic : public StackObj { |
| 171 | Klass* volatile _next_klass; |
| 172 | public: |
| 173 | ClassLoaderDataGraphKlassIteratorAtomic(); |
| 174 | Klass* next_klass(); |
| 175 | private: |
| 176 | static Klass* next_klass_in_cldg(Klass* klass); |
| 177 | }; |
| 178 | |
| 179 | class ClassLoaderDataGraphMetaspaceIterator : public StackObj { |
| 180 | ClassLoaderData* _data; |
| 181 | public: |
| 182 | ClassLoaderDataGraphMetaspaceIterator(); |
| 183 | ~ClassLoaderDataGraphMetaspaceIterator(); |
| 184 | bool repeat() { return _data != NULL; } |
| 185 | ClassLoaderMetaspace* get_next(); |
| 186 | }; |
| 187 | #endif // SHARE_CLASSFILE_CLASSLOADERDATAGRAPH_HPP |
| 188 | |