Bug Summary

File:jdk/src/hotspot/share/classfile/dictionary.cpp
Warning:line 449, column 14
Value stored to 'e' 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 dictionary.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/dictionary.cpp
1/*
2 * Copyright (c) 2003, 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/classLoaderData.inline.hpp"
27#include "classfile/dictionary.hpp"
28#include "classfile/javaClasses.hpp"
29#include "classfile/protectionDomainCache.hpp"
30#include "classfile/systemDictionary.hpp"
31#include "classfile/vmSymbols.hpp"
32#include "logging/log.hpp"
33#include "logging/logStream.hpp"
34#include "memory/iterator.hpp"
35#include "memory/metaspaceClosure.hpp"
36#include "memory/resourceArea.hpp"
37#include "memory/universe.hpp"
38#include "oops/klass.inline.hpp"
39#include "oops/method.hpp"
40#include "oops/oop.inline.hpp"
41#include "oops/oopHandle.inline.hpp"
42#include "runtime/arguments.hpp"
43#include "runtime/handles.inline.hpp"
44#include "runtime/javaCalls.hpp"
45#include "runtime/mutexLocker.hpp"
46#include "runtime/safepointVerifiers.hpp"
47#include "utilities/growableArray.hpp"
48#include "utilities/hashtable.inline.hpp"
49
50// Optimization: if any dictionary needs resizing, we set this flag,
51// so that we dont't have to walk all dictionaries to check if any actually
52// needs resizing, which is costly to do at Safepoint.
53bool Dictionary::_some_dictionary_needs_resizing = false;
54
55Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable)
56 : Hashtable<InstanceKlass*, mtClass>(table_size, (int)sizeof(DictionaryEntry)),
57 _resizable(resizable), _needs_resizing(false), _loader_data(loader_data) {
58};
59
60
61Dictionary::Dictionary(ClassLoaderData* loader_data,
62 int table_size, HashtableBucket<mtClass>* t,
63 int number_of_entries, bool resizable)
64 : Hashtable<InstanceKlass*, mtClass>(table_size, (int)sizeof(DictionaryEntry), t, number_of_entries),
65 _resizable(resizable), _needs_resizing(false), _loader_data(loader_data) {
66};
67
68Dictionary::~Dictionary() {
69 DictionaryEntry* probe = NULL__null;
70 for (int index = 0; index < table_size(); index++) {
71 for (DictionaryEntry** p = bucket_addr(index); *p != NULL__null; ) {
72 probe = *p;
73 *p = probe->next();
74 free_entry(probe);
75 }
76 }
77 assert(number_of_entries() == 0, "should have removed all entries")do { if (!(number_of_entries() == 0)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 77, "assert(" "number_of_entries() == 0" ") failed", "should have removed all entries"
); ::breakpoint(); } } while (0)
;
78}
79
80DictionaryEntry* Dictionary::new_entry(unsigned int hash, InstanceKlass* klass) {
81 DictionaryEntry* entry = (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::new_entry(hash, klass);
82 entry->release_set_pd_set(NULL__null);
83 assert(klass->is_instance_klass(), "Must be")do { if (!(klass->is_instance_klass())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 83, "assert(" "klass->is_instance_klass()" ") failed", "Must be"
); ::breakpoint(); } } while (0)
;
84 return entry;
85}
86
87void Dictionary::free_entry(DictionaryEntry* entry) {
88 // avoid recursion when deleting linked list
89 // pd_set is accessed during a safepoint.
90 // This doesn't require a lock because nothing is reading this
91 // entry anymore. The ClassLoader is dead.
92 while (entry->pd_set_acquire() != NULL__null) {
93 ProtectionDomainEntry* to_delete = entry->pd_set_acquire();
94 entry->release_set_pd_set(to_delete->next_acquire());
95 delete to_delete;
96 }
97 BasicHashtable<mtClass>::free_entry(entry);
98}
99
100const int _resize_load_trigger = 5; // load factor that will trigger the resize
101
102bool Dictionary::does_any_dictionary_needs_resizing() {
103 return Dictionary::_some_dictionary_needs_resizing;
104}
105
106void Dictionary::check_if_needs_resize() {
107 if (_resizable == true) {
108 if (number_of_entries() > (_resize_load_trigger*table_size())) {
109 _needs_resizing = true;
110 Dictionary::_some_dictionary_needs_resizing = true;
111 }
112 }
113}
114
115bool Dictionary::resize_if_needed() {
116 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/dictionary.cpp"
, 116, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must be at safepoint"); ::breakpoint(); } } while (0)
;
117 int desired_size = 0;
118 if (_needs_resizing == true) {
119 desired_size = calculate_resize(false);
120 assert(desired_size != 0, "bug in calculate_resize")do { if (!(desired_size != 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 120, "assert(" "desired_size != 0" ") failed", "bug in calculate_resize"
); ::breakpoint(); } } while (0)
;
121 if (desired_size == table_size()) {
122 _resizable = false; // hit max
123 } else {
124 if (!resize(desired_size)) {
125 // Something went wrong, turn resizing off
126 _resizable = false;
127 }
128 }
129 }
130
131 _needs_resizing = false;
132 Dictionary::_some_dictionary_needs_resizing = false;
133
134 return (desired_size != 0);
135}
136
137bool DictionaryEntry::is_valid_protection_domain(Handle protection_domain) {
138
139 return protection_domain() == NULL__null || !java_lang_System::allow_security_manager()
140 ? true
141 : contains_protection_domain(protection_domain());
142}
143
144// Reading the pd_set on each DictionaryEntry is lock free and cannot safepoint.
145// Adding and deleting entries is under the SystemDictionary_lock
146// Deleting unloaded entries on ClassLoaderData for dictionaries that are not unloaded
147// is a three step process:
148// moving the entries to a separate list, handshake to wait for
149// readers to complete (see NSV here), and then actually deleting the entries.
150// Deleting entries is done by the ServiceThread when triggered by class unloading.
151
152bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
153 assert(Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint(),do { if (!(Thread::current()->is_Java_thread() || SafepointSynchronize
::is_at_safepoint())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 154, "assert(" "Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint()"
") failed", "can only be called by a JavaThread or at safepoint"
); ::breakpoint(); } } while (0)
154 "can only be called by a JavaThread or at safepoint")do { if (!(Thread::current()->is_Java_thread() || SafepointSynchronize
::is_at_safepoint())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 154, "assert(" "Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint()"
") failed", "can only be called by a JavaThread or at safepoint"
); ::breakpoint(); } } while (0)
;
155 // This cannot safepoint while reading the protection domain set.
156 NoSafepointVerifier nsv;
157#ifdef ASSERT1
158 if (protection_domain == instance_klass()->protection_domain()) {
159 // Ensure this doesn't show up in the pd_set (invariant)
160 bool in_pd_set = false;
161 for (ProtectionDomainEntry* current = pd_set_acquire();
162 current != NULL__null;
163 current = current->next_acquire()) {
164 if (current->object_no_keepalive() == protection_domain) {
165 in_pd_set = true;
166 break;
167 }
168 }
169 if (in_pd_set) {
170 assert(false, "A klass's protection domain should not show up "do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 171, "assert(" "false" ") failed", "A klass's protection domain should not show up "
"in its sys. dict. PD set"); ::breakpoint(); } } while (0)
171 "in its sys. dict. PD set")do { if (!(false)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 171, "assert(" "false" ") failed", "A klass's protection domain should not show up "
"in its sys. dict. PD set"); ::breakpoint(); } } while (0)
;
172 }
173 }
174#endif /* ASSERT */
175
176 if (protection_domain == instance_klass()->protection_domain()) {
177 // Succeeds trivially
178 return true;
179 }
180
181 for (ProtectionDomainEntry* current = pd_set_acquire();
182 current != NULL__null;
183 current = current->next_acquire()) {
184 if (current->object_no_keepalive() == protection_domain) {
185 return true;
186 }
187 }
188 return false;
189}
190
191void DictionaryEntry::add_protection_domain(ClassLoaderData* loader_data, Handle protection_domain) {
192 assert_lock_strong(SystemDictionary_lock);
193 if (!contains_protection_domain(protection_domain())) {
194 ProtectionDomainCacheEntry* entry = SystemDictionary::pd_cache_table()->get(protection_domain);
195 // Additions and deletions hold the SystemDictionary_lock, readers are lock-free
196 ProtectionDomainEntry* new_head = new ProtectionDomainEntry(entry, _pd_set);
197 release_set_pd_set(new_head);
198 }
199 LogTarget(Trace, protectiondomain)LogTargetImpl<LogLevel::Trace, (LogTag::_protectiondomain)
, (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG),
(LogTag::__NO_TAG), (LogTag::__NO_TAG)>
lt;
200 if (lt.is_enabled()) {
201 ResourceMark rm;
202 LogStream ls(lt);
203 ls.print("adding protection domain for class %s", instance_klass()->name()->as_C_string());
204 ls.print(" class loader: ");
205 loader_data->class_loader()->print_value_on(&ls);
206 ls.print(" protection domain: ");
207 protection_domain->print_value_on(&ls);
208 ls.print(" ");
209 print_count(&ls);
210 ls.cr();
211 }
212}
213
214// Just the classes from defining class loaders
215void Dictionary::classes_do(void f(InstanceKlass*)) {
216 for (int index = 0; index < table_size(); index++) {
217 for (DictionaryEntry* probe = bucket(index);
218 probe != NULL__null;
219 probe = probe->next()) {
220 InstanceKlass* k = probe->instance_klass();
221 if (loader_data() == k->class_loader_data()) {
222 f(k);
223 }
224 }
225 }
226}
227
228// Added for initialize_itable_for_klass to handle exceptions
229// Just the classes from defining class loaders
230void Dictionary::classes_do(void f(InstanceKlass*, TRAPSJavaThread* __the_thread__), TRAPSJavaThread* __the_thread__) {
231 for (int index = 0; index < table_size(); index++) {
232 for (DictionaryEntry* probe = bucket(index);
233 probe != NULL__null;
234 probe = probe->next()) {
235 InstanceKlass* k = probe->instance_klass();
236 if (loader_data() == k->class_loader_data()) {
237 f(k, CHECK__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return ; (void)(0
);
238 }
239 }
240 }
241}
242
243// All classes, and their class loaders, including initiating class loaders
244void Dictionary::all_entries_do(KlassClosure* closure) {
245 for (int index = 0; index < table_size(); index++) {
246 for (DictionaryEntry* probe = bucket(index);
247 probe != NULL__null;
248 probe = probe->next()) {
249 InstanceKlass* k = probe->instance_klass();
250 closure->do_klass(k);
251 }
252 }
253}
254
255// Used to scan and relocate the classes during CDS archive dump.
256void Dictionary::classes_do(MetaspaceClosure* it) {
257 Arguments::assert_is_dumping_archive();
258 for (int index = 0; index < table_size(); index++) {
259 for (DictionaryEntry* probe = bucket(index);
260 probe != NULL__null;
261 probe = probe->next()) {
262 it->push(probe->klass_addr());
263 }
264 }
265}
266
267
268
269// Add a loaded class to the dictionary.
270// Readers of the SystemDictionary aren't always locked, so _buckets
271// is volatile. The store of the next field in the constructor is
272// also cast to volatile; we do this to ensure store order is maintained
273// by the compilers.
274
275void Dictionary::add_klass(unsigned int hash, Symbol* class_name,
276 InstanceKlass* obj) {
277 assert_locked_or_safepoint(SystemDictionary_lock);
278 assert(obj != NULL, "adding NULL obj")do { if (!(obj != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 278, "assert(" "obj != __null" ") failed", "adding NULL obj"
); ::breakpoint(); } } while (0)
;
279 assert(obj->name() == class_name, "sanity check on name")do { if (!(obj->name() == class_name)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 279, "assert(" "obj->name() == class_name" ") failed", "sanity check on name"
); ::breakpoint(); } } while (0)
;
280
281 DictionaryEntry* entry = new_entry(hash, obj);
282 int index = hash_to_index(hash);
283 add_entry(index, entry);
284 check_if_needs_resize();
285}
286
287
288// This routine does not lock the dictionary.
289//
290// Since readers don't hold a lock, we must make sure that system
291// dictionary entries are only removed at a safepoint (when only one
292// thread is running), and are added to in a safe way (all links must
293// be updated in an MT-safe manner).
294//
295// Callers should be aware that an entry could be added just after
296// _buckets[index] is read here, so the caller will not see the new entry.
297DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
298 Symbol* class_name) {
299 for (DictionaryEntry* entry = bucket(index);
300 entry != NULL__null;
301 entry = entry->next()) {
302 if (entry->hash() == hash && entry->instance_klass()->name() == class_name) {
303 return entry;
304 }
305 }
306 return NULL__null;
307}
308
309
310
311InstanceKlass* Dictionary::find(unsigned int hash, Symbol* name,
312 Handle protection_domain) {
313 NoSafepointVerifier nsv;
314
315 int index = hash_to_index(hash);
316 DictionaryEntry* entry = get_entry(index, hash, name);
317 if (entry != NULL__null && entry->is_valid_protection_domain(protection_domain)) {
318 return entry->instance_klass();
319 } else {
320 return NULL__null;
321 }
322}
323
324InstanceKlass* Dictionary::find_class(unsigned int hash,
325 Symbol* name) {
326 assert_locked_or_safepoint(SystemDictionary_lock);
327
328 int index = hash_to_index(hash);
329 assert (index == index_for(name), "incorrect index?")do { if (!(index == index_for(name))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 329, "assert(" "index == index_for(name)" ") failed", "incorrect index?"
); ::breakpoint(); } } while (0)
;
330
331 DictionaryEntry* entry = get_entry(index, hash, name);
332 return (entry != NULL__null) ? entry->instance_klass() : NULL__null;
333}
334
335void Dictionary::add_protection_domain(int index, unsigned int hash,
336 InstanceKlass* klass,
337 Handle protection_domain) {
338 assert(java_lang_System::allow_security_manager(), "only needed if security manager allowed")do { if (!(java_lang_System::allow_security_manager())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 338, "assert(" "java_lang_System::allow_security_manager()"
") failed", "only needed if security manager allowed"); ::breakpoint
(); } } while (0)
;
339 Symbol* klass_name = klass->name();
340 DictionaryEntry* entry = get_entry(index, hash, klass_name);
341
342 assert(entry != NULL,"entry must be present, we just created it")do { if (!(entry != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 342, "assert(" "entry != __null" ") failed", "entry must be present, we just created it"
); ::breakpoint(); } } while (0)
;
343 assert(protection_domain() != NULL,do { if (!(protection_domain() != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 344, "assert(" "protection_domain() != __null" ") failed", "real protection domain should be present"
); ::breakpoint(); } } while (0)
344 "real protection domain should be present")do { if (!(protection_domain() != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 344, "assert(" "protection_domain() != __null" ") failed", "real protection domain should be present"
); ::breakpoint(); } } while (0)
;
345
346 entry->add_protection_domain(loader_data(), protection_domain);
347
348#ifdef ASSERT1
349 assert(loader_data() != ClassLoaderData::the_null_class_loader_data(), "doesn't make sense")do { if (!(loader_data() != ClassLoaderData::the_null_class_loader_data
())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 349, "assert(" "loader_data() != ClassLoaderData::the_null_class_loader_data()"
") failed", "doesn't make sense"); ::breakpoint(); } } while
(0)
;
350#endif
351
352 assert(entry->contains_protection_domain(protection_domain()),do { if (!(entry->contains_protection_domain(protection_domain
()))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 353, "assert(" "entry->contains_protection_domain(protection_domain())"
") failed", "now protection domain should be present"); ::breakpoint
(); } } while (0)
353 "now protection domain should be present")do { if (!(entry->contains_protection_domain(protection_domain
()))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 353, "assert(" "entry->contains_protection_domain(protection_domain())"
") failed", "now protection domain should be present"); ::breakpoint
(); } } while (0)
;
354}
355
356
357inline bool Dictionary::is_valid_protection_domain(unsigned int hash,
358 Symbol* name,
359 Handle protection_domain) {
360 int index = hash_to_index(hash);
361 DictionaryEntry* entry = get_entry(index, hash, name);
362 return entry->is_valid_protection_domain(protection_domain);
363}
364
365void Dictionary::validate_protection_domain(unsigned int name_hash,
366 InstanceKlass* klass,
367 Handle class_loader,
368 Handle protection_domain,
369 TRAPSJavaThread* __the_thread__) {
370
371 assert(class_loader() != NULL, "Should not call this")do { if (!(class_loader() != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 371, "assert(" "class_loader() != __null" ") failed", "Should not call this"
); ::breakpoint(); } } while (0)
;
372 assert(protection_domain() != NULL, "Should not call this")do { if (!(protection_domain() != __null)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 372, "assert(" "protection_domain() != __null" ") failed", "Should not call this"
); ::breakpoint(); } } while (0)
;
373
374 if (!java_lang_System::allow_security_manager() ||
375 is_valid_protection_domain(name_hash, klass->name(), protection_domain)) {
376 return;
377 }
378
379 // We only have to call checkPackageAccess if there's a security manager installed.
380 if (java_lang_System::has_security_manager()) {
381
382 // This handle and the class_loader handle passed in keeps this class from
383 // being unloaded through several GC points.
384 // The class_loader handle passed in is the initiating loader.
385 Handle mirror(THREAD__the_thread__, klass->java_mirror());
386
387 // Now we have to call back to java to check if the initating class has access
388 InstanceKlass* system_loader = vmClasses::ClassLoader_klass();
389 JavaValue result(T_VOID);
390 JavaCalls::call_special(&result,
391 class_loader,
392 system_loader,
393 vmSymbols::checkPackageAccess_name(),
394 vmSymbols::class_protectiondomain_signature(),
395 mirror,
396 protection_domain,
397 THREAD__the_thread__);
398
399 LogTarget(Debug, protectiondomain)LogTargetImpl<LogLevel::Debug, (LogTag::_protectiondomain)
, (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG),
(LogTag::__NO_TAG), (LogTag::__NO_TAG)>
lt;
400 if (lt.is_enabled()) {
401 ResourceMark rm(THREAD__the_thread__);
402 // Print out trace information
403 LogStream ls(lt);
404 ls.print_cr("Checking package access");
405 ls.print("class loader: ");
406 class_loader()->print_value_on(&ls);
407 ls.print(" protection domain: ");
408 protection_domain()->print_value_on(&ls);
409 ls.print(" loading: "); klass->print_value_on(&ls);
410 if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) {
411 ls.print_cr(" DENIED !!!!!!!!!!!!!!!!!!!!!");
412 } else {
413 ls.print_cr(" granted");
414 }
415 }
416
417 if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) return;
418 }
419
420 // If no exception has been thrown, we have validated the protection domain
421 // Insert the protection domain of the initiating class into the set.
422 // We still have to add the protection_domain to the dictionary in case a new
423 // security manager is installed later. Calls to load the same class with class loader
424 // and protection domain are expected to succeed.
425 {
426 MutexLocker mu(THREAD__the_thread__, SystemDictionary_lock);
427 int d_index = hash_to_index(name_hash);
428 add_protection_domain(d_index, name_hash, klass,
429 protection_domain);
430 }
431}
432
433// During class loading we may have cached a protection domain that has
434// since been unreferenced, so this entry should be cleared.
435void Dictionary::clean_cached_protection_domains(GrowableArray<ProtectionDomainEntry*>* delete_list) {
436 assert(Thread::current()->is_Java_thread(), "only called by JavaThread")do { if (!(Thread::current()->is_Java_thread())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 436, "assert(" "Thread::current()->is_Java_thread()" ") failed"
, "only called by JavaThread"); ::breakpoint(); } } while (0)
;
437 assert_lock_strong(SystemDictionary_lock);
438 assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder")do { if (!(!loader_data()->has_class_mirror_holder())) { (
*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 438, "assert(" "!loader_data()->has_class_mirror_holder()"
") failed", "cld should have a ClassLoader holder not a Class holder"
); ::breakpoint(); } } while (0)
;
439
440 if (loader_data()->is_the_null_class_loader_data()) {
441 // Classes in the boot loader are not loaded with protection domains
442 return;
443 }
444
445 for (int index = 0; index < table_size(); index++) {
446 for (DictionaryEntry* probe = bucket(index);
447 probe != NULL__null;
448 probe = probe->next()) {
449 Klass* e = probe->instance_klass();
Value stored to 'e' during its initialization is never read
450
451 ProtectionDomainEntry* current = probe->pd_set_acquire();
452 ProtectionDomainEntry* prev = NULL__null;
453 while (current != NULL__null) {
454 if (current->object_no_keepalive() == NULL__null) {
455 LogTarget(Debug, protectiondomain)LogTargetImpl<LogLevel::Debug, (LogTag::_protectiondomain)
, (LogTag::__NO_TAG), (LogTag::__NO_TAG), (LogTag::__NO_TAG),
(LogTag::__NO_TAG), (LogTag::__NO_TAG)>
lt;
456 if (lt.is_enabled()) {
457 ResourceMark rm;
458 // Print out trace information
459 LogStream ls(lt);
460 ls.print_cr("PD in set is not alive:");
461 ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls);
462 ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls);
463 ls.cr();
464 }
465 if (probe->pd_set_acquire() == current) {
466 probe->release_set_pd_set(current->next_acquire());
467 } else {
468 assert(prev != NULL, "should be set by alive entry")do { if (!(prev != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 468, "assert(" "prev != __null" ") failed", "should be set by alive entry"
); ::breakpoint(); } } while (0)
;
469 prev->release_set_next(current->next_acquire());
470 }
471 // Mark current for deletion but in the meantime it can still be
472 // traversed.
473 delete_list->push(current);
474 current = current->next_acquire();
475 } else {
476 prev = current;
477 current = current->next_acquire();
478 }
479 }
480 }
481 }
482}
483
484oop SymbolPropertyEntry::method_type() const {
485 return _method_type.resolve();
486}
487
488void SymbolPropertyEntry::set_method_type(oop p) {
489 _method_type = OopHandle(Universe::vm_global(), p);
490}
491
492void SymbolPropertyEntry::free_entry() {
493 // decrement Symbol refcount here because hashtable doesn't.
494 literal()->decrement_refcount();
495 // Free OopHandle
496 _method_type.release(Universe::vm_global());
497}
498
499void SymbolPropertyEntry::print_entry(outputStream* st) const {
500 symbol()->print_value_on(st);
501 st->print("/mode=" INTX_FORMAT"%" "l" "d", symbol_mode());
502 st->print(" -> ");
503 bool printed = false;
504 if (method() != NULL__null) {
505 method()->print_value_on(st);
506 printed = true;
507 }
508 if (method_type() != NULL__null) {
509 if (printed) st->print(" and ");
510 st->print(INTPTR_FORMAT"0x%016" "l" "x", p2i((void *)method_type()));
511 printed = true;
512 }
513 st->print_cr(printed ? "" : "(empty)");
514}
515
516SymbolPropertyTable::SymbolPropertyTable(int table_size)
517 : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))
518{
519}
520SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t,
521 int number_of_entries)
522 : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
523{
524}
525
526
527SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash,
528 Symbol* sym,
529 intptr_t sym_mode) {
530 assert(index == index_for(sym, sym_mode), "incorrect index?")do { if (!(index == index_for(sym, sym_mode))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 530, "assert(" "index == index_for(sym, sym_mode)" ") failed"
, "incorrect index?"); ::breakpoint(); } } while (0)
;
531 for (SymbolPropertyEntry* p = bucket(index); p != NULL__null; p = p->next()) {
532 if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) {
533 return p;
534 }
535 }
536 return NULL__null;
537}
538
539
540SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash,
541 Symbol* sym, intptr_t sym_mode) {
542 assert_locked_or_safepoint(SystemDictionary_lock);
543 assert(index == index_for(sym, sym_mode), "incorrect index?")do { if (!(index == index_for(sym, sym_mode))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 543, "assert(" "index == index_for(sym, sym_mode)" ") failed"
, "incorrect index?"); ::breakpoint(); } } while (0)
;
544 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry")do { if (!(find_entry(index, hash, sym, sym_mode) == __null))
{ (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 544, "assert(" "find_entry(index, hash, sym, sym_mode) == __null"
") failed", "no double entry"); ::breakpoint(); } } while (0
)
;
545
546 SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);
547 Hashtable<Symbol*, mtSymbol>::add_entry(index, p);
548 return p;
549}
550
551void SymbolPropertyTable::methods_do(void f(Method*)) {
552 for (int index = 0; index < table_size(); index++) {
553 for (SymbolPropertyEntry* p = bucket(index); p != NULL__null; p = p->next()) {
554 Method* prop = p->method();
555 if (prop != NULL__null) {
556 f((Method*)prop);
557 }
558 }
559 }
560}
561
562void SymbolPropertyTable::free_entry(SymbolPropertyEntry* entry) {
563 entry->free_entry();
564 BasicHashtable<mtSymbol>::free_entry(entry);
565}
566
567void DictionaryEntry::verify_protection_domain_set() {
568 assert(SafepointSynchronize::is_at_safepoint(), "must only be called as safepoint")do { if (!(SafepointSynchronize::is_at_safepoint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 568, "assert(" "SafepointSynchronize::is_at_safepoint()" ") failed"
, "must only be called as safepoint"); ::breakpoint(); } } while
(0)
;
569 for (ProtectionDomainEntry* current = pd_set_acquire(); // accessed at a safepoint
570 current != NULL__null;
571 current = current->next_acquire()) {
572 guarantee(oopDesc::is_oop_or_null(current->object_no_keepalive()), "Invalid oop")do { if (!(oopDesc::is_oop_or_null(current->object_no_keepalive
()))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 572, "guarantee(" "oopDesc::is_oop_or_null(current->object_no_keepalive())"
") failed", "Invalid oop"); ::breakpoint(); } } while (0)
;
573 }
574}
575
576void DictionaryEntry::print_count(outputStream *st) {
577 assert_locked_or_safepoint(SystemDictionary_lock);
578 int count = 0;
579 for (ProtectionDomainEntry* current = pd_set_acquire();
580 current != NULL__null;
581 current = current->next_acquire()) {
582 count++;
583 }
584 st->print("pd set count = #%d", count);
585}
586
587// ----------------------------------------------------------------------------
588
589void Dictionary::print_on(outputStream* st) const {
590 ResourceMark rm;
591
592 assert(loader_data() != NULL, "loader data should not be null")do { if (!(loader_data() != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 592, "assert(" "loader_data() != __null" ") failed", "loader data should not be null"
); ::breakpoint(); } } while (0)
;
593 assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder")do { if (!(!loader_data()->has_class_mirror_holder())) { (
*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 593, "assert(" "!loader_data()->has_class_mirror_holder()"
") failed", "cld should have a ClassLoader holder not a Class holder"
); ::breakpoint(); } } while (0)
;
594 st->print_cr("Java dictionary (table_size=%d, classes=%d, resizable=%s)",
595 table_size(), number_of_entries(), BOOL_TO_STR(_resizable)((_resizable) ? "true" : "false"));
596 st->print_cr("^ indicates that initiating loader is different from defining loader");
597
598 for (int index = 0; index < table_size(); index++) {
599 for (DictionaryEntry* probe = bucket(index);
600 probe != NULL__null;
601 probe = probe->next()) {
602 Klass* e = probe->instance_klass();
603 bool is_defining_class =
604 (loader_data() == e->class_loader_data());
605 st->print("%4d: %s%s", index, is_defining_class ? " " : "^", e->external_name());
606 ClassLoaderData* cld = e->class_loader_data();
607 if (!loader_data()->is_the_null_class_loader_data()) {
608 // Class loader output for the dictionary for the null class loader data is
609 // redundant and obvious.
610 st->print(", ");
611 cld->print_value_on(st);
612 st->print(", ");
613 probe->print_count(st);
614 }
615 st->cr();
616 }
617 }
618 tty->cr();
619}
620
621void DictionaryEntry::verify() {
622 Klass* e = instance_klass();
623 guarantee(e->is_instance_klass(),do { if (!(e->is_instance_klass())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 624, "guarantee(" "e->is_instance_klass()" ") failed", "Verify of dictionary failed"
); ::breakpoint(); } } while (0)
624 "Verify of dictionary failed")do { if (!(e->is_instance_klass())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 624, "guarantee(" "e->is_instance_klass()" ") failed", "Verify of dictionary failed"
); ::breakpoint(); } } while (0)
;
625 e->verify();
626 verify_protection_domain_set();
627}
628
629void Dictionary::verify() {
630 guarantee(number_of_entries() >= 0, "Verify of dictionary failed")do { if (!(number_of_entries() >= 0)) { (*g_assert_poison)
= 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 630, "guarantee(" "number_of_entries() >= 0" ") failed",
"Verify of dictionary failed"); ::breakpoint(); } } while (0
)
;
631
632 ClassLoaderData* cld = loader_data();
633 // class loader must be present; a null class loader is the
634 // boostrap loader
635 guarantee(cld != NULL &&do { if (!(cld != __null && (cld->the_null_class_loader_data
() || cld->class_loader()->is_instance()))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 637, "guarantee(" "cld != NULL && (cld->the_null_class_loader_data() || cld->class_loader()->is_instance())"
") failed", "checking type of class_loader"); ::breakpoint()
; } } while (0)
636 (cld->the_null_class_loader_data() || cld->class_loader()->is_instance()),do { if (!(cld != __null && (cld->the_null_class_loader_data
() || cld->class_loader()->is_instance()))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 637, "guarantee(" "cld != NULL && (cld->the_null_class_loader_data() || cld->class_loader()->is_instance())"
") failed", "checking type of class_loader"); ::breakpoint()
; } } while (0)
637 "checking type of class_loader")do { if (!(cld != __null && (cld->the_null_class_loader_data
() || cld->class_loader()->is_instance()))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/classfile/dictionary.cpp"
, 637, "guarantee(" "cld != NULL && (cld->the_null_class_loader_data() || cld->class_loader()->is_instance())"
") failed", "checking type of class_loader"); ::breakpoint()
; } } while (0)
;
638
639 ResourceMark rm;
640 stringStream tempst;
641 tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
642 verify_table<DictionaryEntry>(tempst.as_string());
643}