Bug Summary

File:jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp
Warning:line 487, column 20
Value stored to 'data' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name classLoaderDataGraph.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp
1/*
2 * Copyright (c) 2018, 2021, 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/classLoaderDataGraph.inline.hpp"
27#include "classfile/dictionary.hpp"
28#include "classfile/javaClasses.hpp"
29#include "classfile/metadataOnStackMark.hpp"
30#include "classfile/moduleEntry.hpp"
31#include "classfile/packageEntry.hpp"
32#include "code/dependencyContext.hpp"
33#include "logging/log.hpp"
34#include "logging/logStream.hpp"
35#include "memory/allocation.inline.hpp"
36#include "memory/metaspace.hpp"
37#include "memory/resourceArea.hpp"
38#include "runtime/atomic.hpp"
39#include "runtime/handles.inline.hpp"
40#include "runtime/mutex.hpp"
41#include "runtime/safepoint.hpp"
42#include "runtime/safepointVerifiers.hpp"
43#include "runtime/vmOperations.hpp"
44#include "runtime/vmThread.hpp"
45#include "utilities/growableArray.hpp"
46#include "utilities/macros.hpp"
47#include "utilities/ostream.hpp"
48#include "utilities/vmError.hpp"
49
50volatile size_t ClassLoaderDataGraph::_num_array_classes = 0;
51volatile size_t ClassLoaderDataGraph::_num_instance_classes = 0;
52
53void ClassLoaderDataGraph::clear_claimed_marks() {
54 // The claimed marks of the CLDs in the ClassLoaderDataGraph are cleared
55 // outside a safepoint and without locking the ClassLoaderDataGraph_lock.
56 // This is required to avoid a deadlock between concurrent GC threads and safepointing.
57 //
58 // We need to make sure that the CLD contents are fully visible to the
59 // reader thread. This is accomplished by acquire/release of the _head,
60 // and is sufficient.
61 //
62 // Any ClassLoaderData added after or during walking the list are prepended to
63 // _head. Their claim mark need not be handled here.
64 for (ClassLoaderData* cld = Atomic::load_acquire(&_head); cld != NULL__null; cld = cld->next()) {
65 cld->clear_claim();
66 }
67}
68
69void ClassLoaderDataGraph::clear_claimed_marks(int claim) {
70 for (ClassLoaderData* cld = Atomic::load_acquire(&_head); cld != NULL__null; cld = cld->next()) {
71 cld->clear_claim(claim);
72 }
73}
74// Class iterator used by the compiler. It gets some number of classes at
75// a safepoint to decay invocation counters on the methods.
76class ClassLoaderDataGraphKlassIteratorStatic {
77 ClassLoaderData* _current_loader_data;
78 Klass* _current_class_entry;
79 public:
80
81 ClassLoaderDataGraphKlassIteratorStatic() : _current_loader_data(NULL__null), _current_class_entry(NULL__null) {}
82
83 InstanceKlass* try_get_next_class() {
84 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 84, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "only called at safepoint"); ::breakpoint(); } } while (0)
;
85 size_t max_classes = ClassLoaderDataGraph::num_instance_classes();
86 assert(max_classes > 0, "should not be called with no instance classes")do { if (!(max_classes > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 86, "assert(" "max_classes > 0" ") failed", "should not be called with no instance classes"
); ::breakpoint(); } } while (0)
;
87 for (size_t i = 0; i < max_classes; ) {
88
89 if (_current_class_entry != NULL__null) {
90 Klass* k = _current_class_entry;
91 _current_class_entry = _current_class_entry->next_link();
92
93 if (k->is_instance_klass()) {
94 InstanceKlass* ik = InstanceKlass::cast(k);
95 i++; // count all instance classes found
96 // Not yet loaded classes are counted in max_classes
97 // but only return loaded classes.
98 if (ik->is_loaded()) {
99 return ik;
100 }
101 }
102 } else {
103 // Go to next CLD
104 if (_current_loader_data != NULL__null) {
105 _current_loader_data = _current_loader_data->next();
106 }
107 // Start at the beginning
108 if (_current_loader_data == NULL__null) {
109 _current_loader_data = ClassLoaderDataGraph::_head;
110 }
111
112 _current_class_entry = _current_loader_data->klasses();
113 }
114 }
115 // Should never be reached unless all instance classes have failed or are not fully loaded.
116 // Caller handles NULL.
117 return NULL__null;
118 }
119
120 // If the current class for the static iterator is a class being unloaded or
121 // deallocated, adjust the current class.
122 void adjust_saved_class(ClassLoaderData* cld) {
123 if (_current_loader_data == cld) {
124 _current_loader_data = cld->next();
125 if (_current_loader_data != NULL__null) {
126 _current_class_entry = _current_loader_data->klasses();
127 } // else try_get_next_class will start at the head
128 }
129 }
130
131 void adjust_saved_class(Klass* klass) {
132 if (_current_class_entry == klass) {
133 _current_class_entry = klass->next_link();
134 }
135 }
136};
137
138static ClassLoaderDataGraphKlassIteratorStatic static_klass_iterator;
139
140InstanceKlass* ClassLoaderDataGraph::try_get_next_class() {
141 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 141, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "only called at safepoint"); ::breakpoint(); } } while (0)
;
142 return static_klass_iterator.try_get_next_class();
143}
144
145void ClassLoaderDataGraph::adjust_saved_class(ClassLoaderData* cld) {
146 return static_klass_iterator.adjust_saved_class(cld);
147}
148
149void ClassLoaderDataGraph::adjust_saved_class(Klass* klass) {
150 return static_klass_iterator.adjust_saved_class(klass);
151}
152
153void ClassLoaderDataGraph::clean_deallocate_lists(bool walk_previous_versions) {
154 assert(SafepointSynchronize::is_at_safepoint(), "must only be called at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 154, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must only be called at safepoint"); ::breakpoint(); } } while
(0)
;
155 uint loaders_processed = 0;
156 for (ClassLoaderData* cld = _head; cld != NULL__null; cld = cld->next()) {
157 // is_alive check will be necessary for concurrent class unloading.
158 if (cld->is_alive()) {
159 // clean metaspace
160 if (walk_previous_versions) {
161 cld->classes_do(InstanceKlass::purge_previous_versions);
162 }
163 cld->free_deallocate_list();
164 loaders_processed++;
165 }
166 }
167 log_debug(class, loader, data)(!(LogImpl<(LogTag::_class), (LogTag::_loader), (LogTag::_data
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_class), (LogTag::_loader), (LogTag::_data), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("clean_deallocate_lists: loaders processed %u %s",
168 loaders_processed, walk_previous_versions ? "walk_previous_versions" : "");
169}
170
171void ClassLoaderDataGraph::safepoint_and_clean_metaspaces() {
172 // Safepoint and mark all metadata with MetadataOnStackMark and then deallocate unused bits of metaspace.
173 // This needs to be exclusive to Redefinition, so needs to be a safepoint.
174 VM_CleanClassLoaderDataMetaspaces op;
175 VMThread::execute(&op);
176}
177
178void ClassLoaderDataGraph::walk_metadata_and_clean_metaspaces() {
179 assert(SafepointSynchronize::is_at_safepoint(), "must only be called at safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 179, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must only be called at safepoint"); ::breakpoint(); } } while
(0)
;
180
181 _should_clean_deallocate_lists = false; // assume everything gets cleaned
182
183 // Mark metadata seen on the stack so we can delete unreferenced entries.
184 // Walk all metadata, including the expensive code cache walk, only for class redefinition.
185 // The MetadataOnStackMark walk during redefinition saves previous versions if it finds old methods
186 // on the stack or in the code cache, so we only have to repeat the full walk if
187 // they were found at that time.
188 // TODO: have redefinition clean old methods out of the code cache. They still exist in some places.
189 bool walk_all_metadata = InstanceKlass::has_previous_versions_and_reset();
190
191 MetadataOnStackMark md_on_stack(walk_all_metadata, /*redefinition_walk*/false);
192 clean_deallocate_lists(walk_all_metadata);
193}
194
195// GC root of class loader data created.
196ClassLoaderData* volatile ClassLoaderDataGraph::_head = NULL__null;
197ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL__null;
198
199bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false;
200bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false;
201bool ClassLoaderDataGraph::_metaspace_oom = false;
202
203// Add a new class loader data node to the list. Assign the newly created
204// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
205ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool has_class_mirror_holder) {
206
207 assert_lock_strong(ClassLoaderDataGraph_lock);
208
209 ClassLoaderData* cld;
210
211 // First check if another thread beat us to creating the CLD and installing
212 // it into the loader while we were waiting for the lock.
213 if (!has_class_mirror_holder && loader.not_null()) {
214 cld = java_lang_ClassLoader::loader_data_acquire(loader());
215 if (cld != NULL__null) {
216 return cld;
217 }
218 }
219
220 // We mustn't GC until we've installed the ClassLoaderData in the Graph since the CLD
221 // contains oops in _handles that must be walked. GC doesn't walk CLD from the
222 // loader oop in all collections, particularly young collections.
223 NoSafepointVerifier no_safepoints;
224
225 cld = new ClassLoaderData(loader, has_class_mirror_holder);
226
227 // First install the new CLD to the Graph.
228 cld->set_next(_head);
229 Atomic::release_store(&_head, cld);
230
231 // Next associate with the class_loader.
232 if (!has_class_mirror_holder) {
233 // Use OrderAccess, since readers need to get the loader_data only after
234 // it's added to the Graph
235 java_lang_ClassLoader::release_set_loader_data(loader(), cld);
236 }
237
238 // Lastly log, if requested
239 LogTarget(Trace, class, loader, data)LogTargetImpl<LogLevel::Trace, (LogTag::_class), (LogTag::
_loader), (LogTag::_data), (LogTag::__NO_TAG), (LogTag::__NO_TAG
), (LogTag::__NO_TAG)>
lt;
240 if (lt.is_enabled()) {
241 ResourceMark rm;
242 LogStream ls(lt);
243 ls.print("create ");
244 cld->print_value_on(&ls);
245 ls.cr();
246 }
247 return cld;
248}
249
250ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool has_class_mirror_holder) {
251 MutexLocker ml(ClassLoaderDataGraph_lock);
252 ClassLoaderData* loader_data = add_to_graph(loader, has_class_mirror_holder);
253 return loader_data;
254}
255
256void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) {
257 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
258 for (ClassLoaderData* cld = _unloading; cld != NULL__null; cld = cld->next()) {
259 assert(cld->is_unloading(), "invariant")do { if (!(cld->is_unloading())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 259, "assert(" "cld->is_unloading()" ") failed", "invariant"
); ::breakpoint(); } } while (0)
;
260 cl->do_cld(cld);
261 }
262}
263
264// These are functions called by the GC, which require all of the CLDs, including the
265// unloading ones.
266void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
267 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
268 for (ClassLoaderData* cld = _head; cld != NULL__null; cld = cld->_next) {
269 cl->do_cld(cld);
270 }
271}
272
273void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) {
274 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
275 for (ClassLoaderData* cld = _head; cld != NULL__null; cld = cld->_next) {
276 CLDClosure* closure = cld->keep_alive() ? strong : weak;
277 if (closure != NULL__null) {
278 closure->do_cld(cld);
279 }
280 }
281}
282
283void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) {
284 assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
285 if (ClassUnloading) {
286 roots_cld_do(cl, NULL__null);
287 } else {
288 cld_do(cl);
289 }
290}
291
292// Closure for locking and iterating through classes. Only lock outside of safepoint.
293LockedClassesDo::LockedClassesDo(classes_do_func_t f) : _function(f),
294 _do_lock(!SafepointSynchronize::is_at_safepoint()) {
295 if (_do_lock) {
296 ClassLoaderDataGraph_lock->lock();
297 }
298}
299
300LockedClassesDo::LockedClassesDo() : _function(NULL__null),
301 _do_lock(!SafepointSynchronize::is_at_safepoint()) {
302 // callers provide their own do_klass
303 if (_do_lock) {
304 ClassLoaderDataGraph_lock->lock();
305 }
306}
307
308LockedClassesDo::~LockedClassesDo() {
309 if (_do_lock) {
310 ClassLoaderDataGraph_lock->unlock();
311 }
312}
313
314
315// Iterating over the CLDG needs to be locked because
316// unloading can remove entries concurrently soon.
317class ClassLoaderDataGraphIterator : public StackObj {
318 ClassLoaderData* _next;
319 Thread* _thread;
320 HandleMark _hm; // clean up handles when this is done.
321 Handle _holder;
322 NoSafepointVerifier _nsv; // No safepoints allowed in this scope
323 // unless verifying at a safepoint.
324
325public:
326 ClassLoaderDataGraphIterator() : _next(ClassLoaderDataGraph::_head), _thread(Thread::current()), _hm(_thread) {
327 _thread = Thread::current();
328 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
329 }
330
331 ClassLoaderData* get_next() {
332 ClassLoaderData* cld = _next;
333 // Skip already unloaded CLD for concurrent unloading.
334 while (cld != NULL__null && !cld->is_alive()) {
335 cld = cld->next();
336 }
337 if (cld != NULL__null) {
338 // Keep cld that is being returned alive.
339 _holder = Handle(_thread, cld->holder());
340 _next = cld->next();
341 } else {
342 _next = NULL__null;
343 }
344 return cld;
345 }
346};
347
348void ClassLoaderDataGraph::loaded_cld_do(CLDClosure* cl) {
349 ClassLoaderDataGraphIterator iter;
350 while (ClassLoaderData* cld = iter.get_next()) {
351 cl->do_cld(cld);
352 }
353}
354
355// These functions assume that the caller has locked the ClassLoaderDataGraph_lock
356// if they are not calling the function from a safepoint.
357void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
358 ClassLoaderDataGraphIterator iter;
359 while (ClassLoaderData* cld = iter.get_next()) {
360 cld->classes_do(klass_closure);
361 }
362}
363
364void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
365 ClassLoaderDataGraphIterator iter;
366 while (ClassLoaderData* cld = iter.get_next()) {
367 cld->classes_do(f);
368 }
369}
370
371void ClassLoaderDataGraph::methods_do(void f(Method*)) {
372 ClassLoaderDataGraphIterator iter;
373 while (ClassLoaderData* cld = iter.get_next()) {
374 cld->methods_do(f);
375 }
376}
377
378void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) {
379 assert_locked_or_safepoint(Module_lock);
380 ClassLoaderDataGraphIterator iter;
381 while (ClassLoaderData* cld = iter.get_next()) {
382 cld->modules_do(f);
383 }
384}
385
386void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) {
387 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
388 for (ClassLoaderData* cld = _unloading; cld != NULL__null; cld = cld->next()) {
389 assert(cld->is_unloading(), "invariant")do { if (!(cld->is_unloading())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 389, "assert(" "cld->is_unloading()" ") failed", "invariant"
); ::breakpoint(); } } while (0)
;
390 cld->modules_do(f);
391 }
392}
393
394void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
395 assert_locked_or_safepoint(Module_lock);
396 ClassLoaderDataGraphIterator iter;
397 while (ClassLoaderData* cld = iter.get_next()) {
398 cld->packages_do(f);
399 }
400}
401
402void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) {
403 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
404 for (ClassLoaderData* cld = _unloading; cld != NULL__null; cld = cld->next()) {
405 assert(cld->is_unloading(), "invariant")do { if (!(cld->is_unloading())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 405, "assert(" "cld->is_unloading()" ") failed", "invariant"
); ::breakpoint(); } } while (0)
;
406 cld->packages_do(f);
407 }
408}
409
410void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
411 ClassLoaderDataGraphIterator iter;
412 while (ClassLoaderData* cld = iter.get_next()) {
413 cld->loaded_classes_do(klass_closure);
414 }
415}
416
417void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
418 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
419 for (ClassLoaderData* cld = _unloading; cld != NULL__null; cld = cld->next()) {
420 assert(cld->is_unloading(), "invariant")do { if (!(cld->is_unloading())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 420, "assert(" "cld->is_unloading()" ") failed", "invariant"
); ::breakpoint(); } } while (0)
;
421 cld->classes_do(f);
422 }
423}
424
425#define FOR_ALL_DICTIONARY(X)ClassLoaderDataGraphIterator iter; while (ClassLoaderData* X =
iter.get_next()) if (X->dictionary() != __null)
ClassLoaderDataGraphIterator iter; \
426 while (ClassLoaderData* X = iter.get_next()) \
427 if (X->dictionary() != NULL__null)
428
429void ClassLoaderDataGraph::verify_dictionary() {
430 FOR_ALL_DICTIONARY(cld)ClassLoaderDataGraphIterator iter; while (ClassLoaderData* cld
= iter.get_next()) if (cld->dictionary() != __null)
{
431 cld->dictionary()->verify();
432 }
433}
434
435void ClassLoaderDataGraph::print_dictionary(outputStream* st) {
436 FOR_ALL_DICTIONARY(cld)ClassLoaderDataGraphIterator iter; while (ClassLoaderData* cld
= iter.get_next()) if (cld->dictionary() != __null)
{
437 st->print("Dictionary for ");
438 cld->print_value_on(st);
439 st->cr();
440 cld->dictionary()->print_on(st);
441 st->cr();
442 }
443}
444
445void ClassLoaderDataGraph::print_table_statistics(outputStream* st) {
446 FOR_ALL_DICTIONARY(cld)ClassLoaderDataGraphIterator iter; while (ClassLoaderData* cld
= iter.get_next()) if (cld->dictionary() != __null)
{
447 ResourceMark rm;
448 stringStream tempst;
449 tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
450 cld->dictionary()->print_table_statistics(st, tempst.as_string());
451 }
452}
453
454#ifndef PRODUCT
455bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
456 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
457 for (ClassLoaderData* data = _head; data != NULL__null; data = data->next()) {
458 if (loader_data == data) {
459 return true;
460 }
461 }
462
463 return false;
464}
465#endif // PRODUCT
466
467bool ClassLoaderDataGraph::is_valid(ClassLoaderData* loader_data) {
468 DEBUG_ONLY( if (!VMError::is_error_reported()) { assert_locked_or_safepoint(ClassLoaderDataGraph_lock); } )if (!VMError::is_error_reported()) { assert_locked_or_safepoint
(ClassLoaderDataGraph_lock); }
469 if (loader_data != NULL__null) {
470 if (loader_data == ClassLoaderData::the_null_class_loader_data()) {
471 return true;
472 }
473 for (ClassLoaderData* data = _head; data != NULL__null; data = data->next()) {
474 if (loader_data == data) {
475 return true;
476 }
477 }
478 }
479 return false;
480}
481
482// Move class loader data from main list to the unloaded list for unloading
483// and deallocation later.
484bool ClassLoaderDataGraph::do_unloading() {
485 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
486
487 ClassLoaderData* data = _head;
Value stored to 'data' during its initialization is never read
488 ClassLoaderData* prev = NULL__null;
489 bool seen_dead_loader = false;
490 uint loaders_processed = 0;
491 uint loaders_removed = 0;
492
493 data = _head;
494 while (data != NULL__null) {
495 if (data->is_alive()) {
496 prev = data;
497 data = data->next();
498 loaders_processed++;
499 continue;
500 }
501 seen_dead_loader = true;
502 loaders_removed++;
503 ClassLoaderData* dead = data;
504 dead->unload();
505 data = data->next();
506 // Remove from loader list.
507 // This class loader data will no longer be found
508 // in the ClassLoaderDataGraph.
509 if (prev != NULL__null) {
510 prev->set_next(data);
511 } else {
512 assert(dead == _head, "sanity check")do { if (!(dead == _head)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 512, "assert(" "dead == _head" ") failed", "sanity check");
::breakpoint(); } } while (0)
;
513 _head = data;
514 }
515 dead->set_next(_unloading);
516 _unloading = dead;
517 }
518
519 log_debug(class, loader, data)(!(LogImpl<(LogTag::_class), (LogTag::_loader), (LogTag::_data
), (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG)
>::is_level(LogLevel::Debug))) ? (void)0 : LogImpl<(LogTag
::_class), (LogTag::_loader), (LogTag::_data), (LogTag::__NO_TAG
), (LogTag::__NO_TAG), (LogTag::__NO_TAG)>::write<LogLevel
::Debug>
("do_unloading: loaders processed %u, loaders removed %u", loaders_processed, loaders_removed);
520
521 return seen_dead_loader;
522}
523
524// There's at least one dead class loader. Purge refererences of healthy module
525// reads lists and package export lists to modules belonging to dead loaders.
526void ClassLoaderDataGraph::clean_module_and_package_info() {
527 assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
528
529 ClassLoaderData* data = _head;
530 while (data != NULL__null) {
531 // Walk a ModuleEntry's reads, and a PackageEntry's exports
532 // lists to determine if there are modules on those lists that are now
533 // dead and should be removed. A module's life cycle is equivalent
534 // to its defining class loader's life cycle. Since a module is
535 // considered dead if its class loader is dead, these walks must
536 // occur after each class loader's aliveness is determined.
537 if (data->packages() != NULL__null) {
538 data->packages()->purge_all_package_exports();
539 }
540 if (data->modules_defined()) {
541 data->modules()->purge_all_module_reads();
542 }
543 data = data->next();
544 }
545}
546
547void ClassLoaderDataGraph::purge(bool at_safepoint) {
548 ClassLoaderData* list = _unloading;
549 _unloading = NULL__null;
550 ClassLoaderData* next = list;
551 bool classes_unloaded = false;
552 while (next != NULL__null) {
553 ClassLoaderData* purge_me = next;
554 next = purge_me->next();
555 delete purge_me;
556 classes_unloaded = true;
557 }
558 if (classes_unloaded) {
559 Metaspace::purge();
560 set_metaspace_oom(false);
561 }
562 DependencyContext::purge_dependency_contexts();
563
564 // If we're purging metadata at a safepoint, clean remaining
565 // metaspaces if we need to.
566 if (at_safepoint) {
567 _safepoint_cleanup_needed = true; // tested and reset next.
568 if (should_clean_metaspaces_and_reset()) {
569 walk_metadata_and_clean_metaspaces();
570 }
571 } else {
572 // Tell service thread this is a good time to check to see if we should
573 // clean loaded CLDGs. This causes another safepoint.
574 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
575 _safepoint_cleanup_needed = true;
576 Service_lock->notify_all();
577 }
578}
579
580int ClassLoaderDataGraph::resize_dictionaries() {
581 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 581, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint!"); ::breakpoint(); } } while (0)
;
582 int resized = 0;
583 assert (Dictionary::does_any_dictionary_needs_resizing(), "some dictionary should need resizing")do { if (!(Dictionary::does_any_dictionary_needs_resizing()))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 583, "assert(" "Dictionary::does_any_dictionary_needs_resizing()"
") failed", "some dictionary should need resizing"); ::breakpoint
(); } } while (0)
;
584 FOR_ALL_DICTIONARY(cld)ClassLoaderDataGraphIterator iter; while (ClassLoaderData* cld
= iter.get_next()) if (cld->dictionary() != __null)
{
585 if (cld->dictionary()->resize_if_needed()) {
586 resized++;
587 }
588 }
589 return resized;
590}
591
592ClassLoaderDataGraphKlassIteratorAtomic::ClassLoaderDataGraphKlassIteratorAtomic()
593 : _next_klass(NULL__null) {
594 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 594, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint!"); ::breakpoint(); } } while (0)
;
595 ClassLoaderData* cld = ClassLoaderDataGraph::_head;
596 Klass* klass = NULL__null;
597
598 // Find the first klass in the CLDG.
599 while (cld != NULL__null) {
600 assert_locked_or_safepoint(cld->metaspace_lock());
601 klass = cld->_klasses;
602 if (klass != NULL__null) {
603 _next_klass = klass;
604 return;
605 }
606 cld = cld->next();
607 }
608}
609
610Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass_in_cldg(Klass* klass) {
611 Klass* next = klass->next_link();
612 if (next != NULL__null) {
613 return next;
614 }
615
616 // No more klasses in the current CLD. Time to find a new CLD.
617 ClassLoaderData* cld = klass->class_loader_data();
618 assert_locked_or_safepoint(cld->metaspace_lock());
619 while (next == NULL__null) {
620 cld = cld->next();
621 if (cld == NULL__null) {
622 break;
623 }
624 next = cld->_klasses;
625 }
626
627 return next;
628}
629
630Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() {
631 Klass* head = _next_klass;
632
633 while (head != NULL__null) {
634 Klass* next = next_klass_in_cldg(head);
635
636 Klass* old_head = Atomic::cmpxchg(&_next_klass, head, next);
637
638 if (old_head == head) {
639 return head; // Won the CAS.
640 }
641
642 head = old_head;
643 }
644
645 // Nothing more for the iterator to hand out.
646 assert(head == NULL, "head is " PTR_FORMAT ", expected not null:", p2i(head))do { if (!(head == __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/classLoaderDataGraph.cpp"
, 646, "assert(" "head == __null" ") failed", "head is " "0x%016"
"l" "x" ", expected not null:", p2i(head)); ::breakpoint(); }
} while (0)
;
647 return NULL__null;
648}
649
650void ClassLoaderDataGraph::verify() {
651 ClassLoaderDataGraphIterator iter;
652 while (ClassLoaderData* cld = iter.get_next()) {
653 cld->verify();
654 }
655}
656
657#ifndef PRODUCT
658// callable from debugger
659extern "C" int print_loader_data_graph() {
660 ResourceMark rm;
661 MutexLocker ml(ClassLoaderDataGraph_lock);
662 ClassLoaderDataGraph::print_on(tty);
663 return 0;
664}
665
666void ClassLoaderDataGraph::print_on(outputStream * const out) {
667 ClassLoaderDataGraphIterator iter;
668 while (ClassLoaderData* cld = iter.get_next()) {
669 cld->print_on(out);
670 }
671}
672#endif // PRODUCT
673
674void ClassLoaderDataGraph::print() { print_on(tty); }