dictionary.cpp revision 1879:f95d63e2154a
11541Srgrimes/* 222521Sdyson * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 322521Sdyson * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41541Srgrimes * 51541Srgrimes * This code is free software; you can redistribute it and/or modify it 61541Srgrimes * under the terms of the GNU General Public License version 2 only, as 71541Srgrimes * published by the Free Software Foundation. 81541Srgrimes * 91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131541Srgrimes * accompanied this code). 141541Srgrimes * 151541Srgrimes * You should have received a copy of the GNU General Public License version 161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 181541Srgrimes * 191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 201541Srgrimes * or visit www.oracle.com if you need additional information or have any 211541Srgrimes * questions. 221541Srgrimes * 231541Srgrimes */ 241541Srgrimes 251541Srgrimes#include "precompiled.hpp" 261541Srgrimes#include "classfile/dictionary.hpp" 271541Srgrimes#include "classfile/systemDictionary.hpp" 281541Srgrimes#include "oops/oop.inline.hpp" 291541Srgrimes#include "prims/jvmtiRedefineClassesTrace.hpp" 301541Srgrimes#include "services/classLoadingService.hpp" 311541Srgrimes#include "utilities/hashtable.inline.hpp" 321541Srgrimes 331541Srgrimes 341541SrgrimesDictionaryEntry* Dictionary::_current_class_entry = NULL; 351541Srgrimesint Dictionary::_current_class_index = 0; 361541Srgrimes 3722521Sdyson 3850477SpeterDictionary::Dictionary(int table_size) 391541Srgrimes : TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { 401541Srgrimes _current_class_index = 0; 411541Srgrimes _current_class_entry = NULL; 421541Srgrimes}; 431541Srgrimes 441541Srgrimes 451541Srgrimes 461541SrgrimesDictionary::Dictionary(int table_size, HashtableBucket* t, 472979Swollman int number_of_entries) 4878906Sjhb : TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { 4978906Sjhb _current_class_index = 0; 501541Srgrimes _current_class_entry = NULL; 511541Srgrimes}; 521541Srgrimes 531541Srgrimes 541541SrgrimesDictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, 551541Srgrimes oop loader) { 5677031Sru DictionaryEntry* entry; 571541Srgrimes entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass); 5830354Sphk entry->set_loader(loader); 5930354Sphk entry->set_pd_set(NULL); 6022521Sdyson return entry; 6131273Sphk} 6212595Sbde 6331273Sphk 6431273SphkDictionaryEntry* Dictionary::new_entry() { 6512595Sbde DictionaryEntry* entry = (DictionaryEntry*)Hashtable::new_entry(0L, NULL); 6631273Sphk entry->set_loader(NULL); 6712595Sbde entry->set_pd_set(NULL); 6812595Sbde return entry; 691541Srgrimes} 701541Srgrimes 711541Srgrimes 7231273Sphkvoid Dictionary::free_entry(DictionaryEntry* entry) { 731541Srgrimes // avoid recursion when deleting linked list 741541Srgrimes while (entry->pd_set() != NULL) { 751541Srgrimes ProtectionDomainEntry* to_delete = entry->pd_set(); 761541Srgrimes entry->set_pd_set(to_delete->next()); 771541Srgrimes delete to_delete; 781541Srgrimes } 791541Srgrimes Hashtable::free_entry(entry); 801541Srgrimes} 811541Srgrimes 821541Srgrimes 831541Srgrimesbool DictionaryEntry::contains_protection_domain(oop protection_domain) const { 8422521Sdyson#ifdef ASSERT 851541Srgrimes if (protection_domain == instanceKlass::cast(klass())->protection_domain()) { 861549Srgrimes // Ensure this doesn't show up in the pd_set (invariant) 871541Srgrimes bool in_pd_set = false; 881541Srgrimes for (ProtectionDomainEntry* current = _pd_set; 891541Srgrimes current != NULL; 9051688Sdillon current = current->next()) { 911541Srgrimes if (current->protection_domain() == protection_domain) { 921541Srgrimes in_pd_set = true; 9329888Skato break; 9429888Skato } 9529888Skato } 9629888Skato if (in_pd_set) { 9729888Skato assert(false, "A klass's protection domain should not show up " 981541Srgrimes "in its sys. dict. PD set"); 991541Srgrimes } 1001541Srgrimes } 1011541Srgrimes#endif /* ASSERT */ 1021541Srgrimes 1031541Srgrimes if (protection_domain == instanceKlass::cast(klass())->protection_domain()) { 1041541Srgrimes // Succeeds trivially 1051541Srgrimes return true; 1061541Srgrimes } 1071541Srgrimes 1081541Srgrimes for (ProtectionDomainEntry* current = _pd_set; 1091541Srgrimes current != NULL; 1101541Srgrimes current = current->next()) { 1111541Srgrimes if (current->protection_domain() == protection_domain) return true; 1121541Srgrimes } 1133496Sphk return false; 1143496Sphk} 1151541Srgrimes 1161541Srgrimes 11751688Sdillonvoid DictionaryEntry::add_protection_domain(oop protection_domain) { 11851688Sdillon assert_locked_or_safepoint(SystemDictionary_lock); 11951688Sdillon if (!contains_protection_domain(protection_domain)) { 12051688Sdillon ProtectionDomainEntry* new_head = 12151688Sdillon new ProtectionDomainEntry(protection_domain, _pd_set); 1221541Srgrimes // Warning: Preserve store ordering. The SystemDictionary is read 1231541Srgrimes // without locks. The new ProtectionDomainEntry must be 1241541Srgrimes // complete before other threads can be allowed to see it 12551688Sdillon // via a store to _pd_set. 1261541Srgrimes OrderAccess::release_store_ptr(&_pd_set, new_head); 12724921Skato } 12824921Skato if (TraceProtectionDomainVerification && WizardMode) { 12932598Skato print(); 13024921Skato } 13151688Sdillon} 13224921Skato 13324921Skato 13451688Sdillonbool Dictionary::do_unloading(BoolObjectClosure* is_alive) { 13551688Sdillon assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1361541Srgrimes bool class_was_unloaded = false; 1371541Srgrimes int index = 0; // Defined here for portability! Do not move 1381541Srgrimes 1391541Srgrimes // Remove unloadable entries and classes from system dictionary 1403496Sphk // The placeholder array has been handled in always_strong_oops_do. 14151688Sdillon DictionaryEntry* probe = NULL; 14251688Sdillon for (index = 0; index < table_size(); index++) { 14332598Skato for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) { 14424921Skato probe = *p; 14551688Sdillon klassOop e = probe->klass(); 1463496Sphk oop class_loader = probe->loader(); 1471541Srgrimes 1481541Srgrimes instanceKlass* ik = instanceKlass::cast(e); 14954655Seivind if (ik->previous_versions() != NULL) { 1501541Srgrimes // This klass has previous versions so see what we can cleanup 1511541Srgrimes // while it is safe to do so. 1521541Srgrimes 1531541Srgrimes int gc_count = 0; // leave debugging breadcrumbs 15454444Seivind int live_count = 0; 15554444Seivind 15651688Sdillon // RC_TRACE macro has an embedded ResourceMark 15724921Skato RC_TRACE(0x00000200, ("unload: %s: previous version length=%d", 15824921Skato ik->external_name(), ik->previous_versions()->length())); 15951688Sdillon 16024921Skato for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { 16124921Skato // check the previous versions array for GC'ed weak refs 16225016Skato PreviousVersionNode * pv_node = ik->previous_versions()->at(i); 16325016Skato jobject cp_ref = pv_node->prev_constant_pool(); 16425016Skato assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); 16524921Skato if (cp_ref == NULL) { 16624921Skato delete pv_node; 16724921Skato ik->previous_versions()->remove_at(i); 16824921Skato // Since we are traversing the array backwards, we don't have to 1691541Srgrimes // do anything special with the index. 1701541Srgrimes continue; // robustness 1711541Srgrimes } 1721541Srgrimes 1738876Srgrimes constantPoolOop pvcp = (constantPoolOop)JNIHandles::resolve(cp_ref); 1741541Srgrimes if (pvcp == NULL) { 17551688Sdillon // this entry has been GC'ed so remove it 17651688Sdillon delete pv_node; 17751688Sdillon ik->previous_versions()->remove_at(i); 17851688Sdillon // Since we are traversing the array backwards, we don't have to 17951688Sdillon // do anything special with the index. 18051688Sdillon gc_count++; 1811541Srgrimes continue; 1821541Srgrimes } else { 18351688Sdillon RC_TRACE(0x00000200, ("unload: previous version @%d is alive", i)); 18469781Sdwmalone if (is_alive->do_object_b(pvcp)) { 18551688Sdillon live_count++; 1861541Srgrimes } else { 18751688Sdillon guarantee(false, "sanity check"); 1881541Srgrimes } 1891541Srgrimes } 1901541Srgrimes 1911541Srgrimes GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods(); 19251688Sdillon if (method_refs != NULL) { 19351688Sdillon RC_TRACE(0x00000200, ("unload: previous methods length=%d", 1941541Srgrimes method_refs->length())); 1951541Srgrimes for (int j = method_refs->length() - 1; j >= 0; j--) { 1961541Srgrimes jweak method_ref = method_refs->at(j); 1971541Srgrimes assert(method_ref != NULL, "weak method ref was unexpectedly cleared"); 1981541Srgrimes if (method_ref == NULL) { 19951688Sdillon method_refs->remove_at(j); 20051688Sdillon // Since we are traversing the array backwards, we don't have to 2011541Srgrimes // do anything special with the index. 2021541Srgrimes continue; // robustness 2031541Srgrimes } 2041541Srgrimes 20551688Sdillon methodOop method = (methodOop)JNIHandles::resolve(method_ref); 2061541Srgrimes if (method == NULL) { 2071541Srgrimes // this method entry has been GC'ed so remove it 20851688Sdillon JNIHandles::destroy_weak_global(method_ref); 2091541Srgrimes method_refs->remove_at(j); 2101541Srgrimes } else { 2111541Srgrimes // RC_TRACE macro has an embedded ResourceMark 2121541Srgrimes RC_TRACE(0x00000200, 2131541Srgrimes ("unload: %s(%s): prev method @%d in version @%d is alive", 2141541Srgrimes method->name()->as_C_string(), 2151541Srgrimes method->signature()->as_C_string(), j, i)); 21622521Sdyson } 21722521Sdyson } 21822521Sdyson } 21922521Sdyson } 22022521Sdyson assert(ik->previous_versions()->length() == live_count, "sanity check"); 22151688Sdillon RC_TRACE(0x00000200, 22222521Sdyson ("unload: previous version stats: live=%d, GC'ed=%d", live_count, 22322521Sdyson gc_count)); 22422521Sdyson } 22522521Sdyson 22622521Sdyson // Non-unloadable classes were handled in always_strong_oops_do 22722521Sdyson if (!is_strongly_reachable(class_loader, e)) { 2281541Srgrimes // Entry was not visited in phase1 (negated test from phase1) 2291541Srgrimes assert(class_loader != NULL, "unloading entry with null class loader"); 2301541Srgrimes oop k_def_class_loader = ik->class_loader(); 2311541Srgrimes 2321541Srgrimes // Do we need to delete this system dictionary entry? 2331541Srgrimes bool purge_entry = false; 2341541Srgrimes 2351541Srgrimes // Do we need to delete this system dictionary entry? 2361541Srgrimes if (!is_alive->do_object_b(class_loader)) { 2371541Srgrimes // If the loader is not live this entry should always be 2381541Srgrimes // removed (will never be looked up again). Note that this is 2391541Srgrimes // not the same as unloading the referred class. 2401541Srgrimes if (k_def_class_loader == class_loader) { 2411541Srgrimes // This is the defining entry, so the referred class is about 2421541Srgrimes // to be unloaded. 2431541Srgrimes // Notify the debugger and clean up the class. 2441541Srgrimes guarantee(!is_alive->do_object_b(e), 2451541Srgrimes "klass should not be live if defining loader is not"); 2461541Srgrimes class_was_unloaded = true; 2471541Srgrimes // notify the debugger 2481541Srgrimes if (JvmtiExport::should_post_class_unload()) { 24935256Sdes JvmtiExport::post_class_unload(ik->as_klassOop()); 2501541Srgrimes } 2511541Srgrimes 2521541Srgrimes // notify ClassLoadingService of class unload 2531541Srgrimes ClassLoadingService::notify_class_unloaded(ik); 2541541Srgrimes 2551541Srgrimes // Clean up C heap 25622521Sdyson ik->release_C_heap_structures(); 2571541Srgrimes } 2581541Srgrimes // Also remove this system dictionary entry. 2591541Srgrimes purge_entry = true; 26022521Sdyson 2611541Srgrimes } else { 2621541Srgrimes // The loader in this entry is alive. If the klass is dead, 26322521Sdyson // the loader must be an initiating loader (rather than the 2641541Srgrimes // defining loader). Remove this entry. 2651541Srgrimes if (!is_alive->do_object_b(e)) { 2661541Srgrimes guarantee(!is_alive->do_object_b(k_def_class_loader), 2671541Srgrimes "defining loader should not be live if klass is not"); 2681541Srgrimes // If we get here, the class_loader must not be the defining 2691541Srgrimes // loader, it must be an initiating one. 2701541Srgrimes assert(k_def_class_loader != class_loader, 2711541Srgrimes "cannot have live defining loader and unreachable klass"); 2721541Srgrimes 2731541Srgrimes // Loader is live, but class and its defining loader are dead. 2741541Srgrimes // Remove the entry. The class is going away. 2751541Srgrimes purge_entry = true; 2761541Srgrimes } 2771541Srgrimes } 2784140Sdg 2794140Sdg if (purge_entry) { 28051688Sdillon *p = probe->next(); 28151688Sdillon if (probe == _current_class_entry) { 2821541Srgrimes _current_class_entry = NULL; 2831541Srgrimes } 2841541Srgrimes free_entry(probe); 28551688Sdillon continue; 28651688Sdillon } 28751688Sdillon } 28851688Sdillon p = probe->next_addr(); 28951688Sdillon } 29051688Sdillon } 29130354Sphk return class_was_unloaded; 29251688Sdillon} 2931541Srgrimes 2941541Srgrimes 2951541Srgrimesvoid Dictionary::always_strong_classes_do(OopClosure* blk) { 2961541Srgrimes // Follow all system classes and temporary placeholders in dictionary 2971541Srgrimes for (int index = 0; index < table_size(); index++) { 2981541Srgrimes for (DictionaryEntry *probe = bucket(index); 2991541Srgrimes probe != NULL; 3001541Srgrimes probe = probe->next()) { 3011541Srgrimes oop e = probe->klass(); 3021541Srgrimes oop class_loader = probe->loader(); 3031541Srgrimes if (is_strongly_reachable(class_loader, e)) { 3041541Srgrimes blk->do_oop((oop*)probe->klass_addr()); 30531273Sphk if (class_loader != NULL) { 3061541Srgrimes blk->do_oop(probe->loader_addr()); 3071541Srgrimes } 3081541Srgrimes probe->protection_domain_set_oops_do(blk); 3091541Srgrimes } 3101541Srgrimes } 3111541Srgrimes } 3121541Srgrimes} 31322521Sdyson 3141541Srgrimes 3151541Srgrimes// Just the classes from defining class loaders 31651688Sdillonvoid Dictionary::classes_do(void f(klassOop)) { 3171541Srgrimes for (int index = 0; index < table_size(); index++) { 31822521Sdyson for (DictionaryEntry* probe = bucket(index); 31922521Sdyson probe != NULL; 32022521Sdyson probe = probe->next()) { 32122521Sdyson klassOop k = probe->klass(); 32222521Sdyson if (probe->loader() == instanceKlass::cast(k)->class_loader()) { 32322521Sdyson f(k); 32422521Sdyson } 32522521Sdyson } 32622521Sdyson } 32722521Sdyson} 32822521Sdyson 32922521Sdyson// Added for initialize_itable_for_klass to handle exceptions 33076688Siedowse// Just the classes from defining class loaders 33122521Sdysonvoid Dictionary::classes_do(void f(klassOop, TRAPS), TRAPS) { 33222521Sdyson for (int index = 0; index < table_size(); index++) { 33322521Sdyson for (DictionaryEntry* probe = bucket(index); 33422521Sdyson probe != NULL; 33578906Sjhb probe = probe->next()) { 33676688Siedowse klassOop k = probe->klass(); 33776688Siedowse if (probe->loader() == instanceKlass::cast(k)->class_loader()) { 33822521Sdyson f(k, CHECK); 33978906Sjhb } 34022521Sdyson } 34122521Sdyson } 34222521Sdyson} 34322521Sdyson 34422521Sdyson 34522521Sdyson// All classes, and their class loaders 34622521Sdyson// (added for helpers that use HandleMarks and ResourceMarks) 3471541Srgrimes// Don't iterate over placeholders 3481541Srgrimesvoid Dictionary::classes_do(void f(klassOop, oop, TRAPS), TRAPS) { 34976688Siedowse for (int index = 0; index < table_size(); index++) { 35076688Siedowse for (DictionaryEntry* probe = bucket(index); 35176688Siedowse probe != NULL; 3521541Srgrimes probe = probe->next()) { 3531541Srgrimes klassOop k = probe->klass(); 3541541Srgrimes f(k, probe->loader(), CHECK); 3551541Srgrimes } 3561541Srgrimes } 3571541Srgrimes} 3581541Srgrimes 3591541Srgrimes 3601541Srgrimes// All classes, and their class loaders 3611541Srgrimes// Don't iterate over placeholders 3621541Srgrimesvoid Dictionary::classes_do(void f(klassOop, oop)) { 36330354Sphk for (int index = 0; index < table_size(); index++) { 3641541Srgrimes for (DictionaryEntry* probe = bucket(index); 3651541Srgrimes probe != NULL; 3661541Srgrimes probe = probe->next()) { 3671541Srgrimes klassOop k = probe->klass(); 36831273Sphk f(k, probe->loader()); 3691541Srgrimes } 3701541Srgrimes } 3711541Srgrimes} 3721541Srgrimes 3731541Srgrimes 3741541Srgrimesvoid Dictionary::oops_do(OopClosure* f) { 3751541Srgrimes for (int index = 0; index < table_size(); index++) { 3761541Srgrimes for (DictionaryEntry* probe = bucket(index); 37751688Sdillon probe != NULL; 37851688Sdillon probe = probe->next()) { 37951688Sdillon f->do_oop((oop*)probe->klass_addr()); 38051688Sdillon if (probe->loader() != NULL) { 3811541Srgrimes f->do_oop(probe->loader_addr()); 38254444Seivind } 38354444Seivind probe->protection_domain_set_oops_do(f); 38451688Sdillon } 3851541Srgrimes } 3861541Srgrimes} 3871541Srgrimes 3881541Srgrimes 38951688Sdillonvoid Dictionary::methods_do(void f(methodOop)) { 39051688Sdillon for (int index = 0; index < table_size(); index++) { 39151688Sdillon for (DictionaryEntry* probe = bucket(index); 39254444Seivind probe != NULL; 39354444Seivind probe = probe->next()) { 3941541Srgrimes klassOop k = probe->klass(); 3951541Srgrimes if (probe->loader() == instanceKlass::cast(k)->class_loader()) { 3961541Srgrimes // only take klass is we have the entry with the defining class loader 3971541Srgrimes instanceKlass::cast(k)->methods_do(f); 39831273Sphk } 3991541Srgrimes } 4001541Srgrimes } 4011541Srgrimes} 4021541Srgrimes 4031541Srgrimes 4041541SrgrimesklassOop Dictionary::try_get_next_class() { 4051541Srgrimes while (true) { 4061541Srgrimes if (_current_class_entry != NULL) { 4071541Srgrimes klassOop k = _current_class_entry->klass(); 4081541Srgrimes _current_class_entry = _current_class_entry->next(); 40951688Sdillon return k; 41051688Sdillon } 4111541Srgrimes _current_class_index = (_current_class_index + 1) % table_size(); 4121541Srgrimes _current_class_entry = bucket(_current_class_index); 4131541Srgrimes } 4141541Srgrimes // never reached 4151541Srgrimes} 4161541Srgrimes 4171541Srgrimes 4181541Srgrimes// Add a loaded class to the system dictionary. 4191541Srgrimes// Readers of the SystemDictionary aren't always locked, so _buckets 4201541Srgrimes// is volatile. The store of the next field in the constructor is 4211541Srgrimes// also cast to volatile; we do this to ensure store order is maintained 4221541Srgrimes// by the compilers. 4231541Srgrimes 4241541Srgrimesvoid Dictionary::add_klass(symbolHandle class_name, Handle class_loader, 4251541Srgrimes KlassHandle obj) { 4261541Srgrimes assert_locked_or_safepoint(SystemDictionary_lock); 4271541Srgrimes assert(obj() != NULL, "adding NULL obj"); 4281541Srgrimes assert(Klass::cast(obj())->name() == class_name(), "sanity check on name"); 4291541Srgrimes 4301541Srgrimes unsigned int hash = compute_hash(class_name, class_loader); 4311541Srgrimes int index = hash_to_index(hash); 4321541Srgrimes DictionaryEntry* entry = new_entry(hash, obj(), class_loader()); 4331541Srgrimes add_entry(index, entry); 4341541Srgrimes} 4351541Srgrimes 4361541Srgrimes 4371541Srgrimes// This routine does not lock the system dictionary. 4381541Srgrimes// 4391541Srgrimes// Since readers don't hold a lock, we must make sure that system 4401541Srgrimes// dictionary entries are only removed at a safepoint (when only one 4411541Srgrimes// thread is running), and are added to in a safe way (all links must 4421541Srgrimes// be updated in an MT-safe manner). 4431541Srgrimes// 4441541Srgrimes// Callers should be aware that an entry could be added just after 4451541Srgrimes// _buckets[index] is read here, so the caller will not see the new entry. 4461541SrgrimesDictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, 4471541Srgrimes symbolHandle class_name, 44822521Sdyson Handle class_loader) { 44925535Skato symbolOop name_ = class_name(); 45022521Sdyson oop loader_ = class_loader(); 45122521Sdyson debug_only(_lookup_count++); 45222521Sdyson for (DictionaryEntry* entry = bucket(index); 45322521Sdyson entry != NULL; 45422521Sdyson entry = entry->next()) { 45522521Sdyson if (entry->hash() == hash && entry->equals(name_, loader_)) { 45622521Sdyson return entry; 4571541Srgrimes } 45822521Sdyson debug_only(_lookup_length++); 45922521Sdyson } 4601541Srgrimes return NULL; 46122521Sdyson} 4621541Srgrimes 4631541Srgrimes 46422521SdysonklassOop Dictionary::find(int index, unsigned int hash, symbolHandle name, 4651541Srgrimes Handle loader, Handle protection_domain, TRAPS) { 4661541Srgrimes DictionaryEntry* entry = get_entry(index, hash, name, loader); 4671541Srgrimes if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { 4681541Srgrimes return entry->klass(); 4691541Srgrimes } else { 4701541Srgrimes return NULL; 4711541Srgrimes } 47231273Sphk} 4731541Srgrimes 47451138Salfred 4751541SrgrimesklassOop Dictionary::find_class(int index, unsigned int hash, 4761541Srgrimes symbolHandle name, Handle loader) { 47751068Salfred assert_locked_or_safepoint(SystemDictionary_lock); 4781541Srgrimes assert (index == index_for(name, loader), "incorrect index?"); 47951068Salfred 48051068Salfred DictionaryEntry* entry = get_entry(index, hash, name, loader); 48151068Salfred return (entry != NULL) ? entry->klass() : (klassOop)NULL; 48251138Salfred} 48351068Salfred 4841541Srgrimes 48554803Srwatson// Variant of find_class for shared classes. No locking required, as 48654803Srwatson// that table is static. 4871541Srgrimes 4882946SwollmanklassOop Dictionary::find_shared_class(int index, unsigned int hash, 48977133Sru symbolHandle name) { 490 assert (index == index_for(name, Handle()), "incorrect index?"); 491 492 DictionaryEntry* entry = get_entry(index, hash, name, Handle()); 493 return (entry != NULL) ? entry->klass() : (klassOop)NULL; 494} 495 496 497void Dictionary::add_protection_domain(int index, unsigned int hash, 498 instanceKlassHandle klass, 499 Handle loader, Handle protection_domain, 500 TRAPS) { 501 symbolHandle klass_name(THREAD, klass->name()); 502 DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); 503 504 assert(entry != NULL,"entry must be present, we just created it"); 505 assert(protection_domain() != NULL, 506 "real protection domain should be present"); 507 508 entry->add_protection_domain(protection_domain()); 509 510 assert(entry->contains_protection_domain(protection_domain()), 511 "now protection domain should be present"); 512} 513 514 515bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, 516 symbolHandle name, 517 Handle loader, 518 Handle protection_domain) { 519 DictionaryEntry* entry = get_entry(index, hash, name, loader); 520 return entry->is_valid_protection_domain(protection_domain); 521} 522 523 524void Dictionary::reorder_dictionary() { 525 526 // Copy all the dictionary entries into a single master list. 527 528 DictionaryEntry* master_list = NULL; 529 for (int i = 0; i < table_size(); ++i) { 530 DictionaryEntry* p = bucket(i); 531 while (p != NULL) { 532 DictionaryEntry* tmp; 533 tmp = p->next(); 534 p->set_next(master_list); 535 master_list = p; 536 p = tmp; 537 } 538 set_entry(i, NULL); 539 } 540 541 // Add the dictionary entries back to the list in the correct buckets. 542 Thread *thread = Thread::current(); 543 544 while (master_list != NULL) { 545 DictionaryEntry* p = master_list; 546 master_list = master_list->next(); 547 p->set_next(NULL); 548 symbolHandle class_name (thread, instanceKlass::cast((klassOop)(p->klass()))->name()); 549 unsigned int hash = compute_hash(class_name, Handle(thread, p->loader())); 550 int index = hash_to_index(hash); 551 p->set_hash(hash); 552 p->set_next(bucket(index)); 553 set_entry(index, p); 554 } 555} 556 557SymbolPropertyTable::SymbolPropertyTable(int table_size) 558 : Hashtable(table_size, sizeof(SymbolPropertyEntry)) 559{ 560} 561SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, 562 int number_of_entries) 563 : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) 564{ 565} 566 567 568SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, 569 symbolHandle sym, 570 intptr_t sym_mode) { 571 assert(index == index_for(sym, sym_mode), "incorrect index?"); 572 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 573 if (p->hash() == hash && p->symbol() == sym() && p->symbol_mode() == sym_mode) { 574 return p; 575 } 576 } 577 return NULL; 578} 579 580 581SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, 582 symbolHandle sym, intptr_t sym_mode) { 583 assert_locked_or_safepoint(SystemDictionary_lock); 584 assert(index == index_for(sym, sym_mode), "incorrect index?"); 585 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); 586 587 SymbolPropertyEntry* p = new_entry(hash, sym(), sym_mode); 588 Hashtable::add_entry(index, p); 589 return p; 590} 591 592 593void SymbolPropertyTable::oops_do(OopClosure* f) { 594 for (int index = 0; index < table_size(); index++) { 595 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 596 f->do_oop((oop*) p->symbol_addr()); 597 if (p->property_oop() != NULL) { 598 f->do_oop(p->property_oop_addr()); 599 } 600 } 601 } 602} 603 604void SymbolPropertyTable::methods_do(void f(methodOop)) { 605 for (int index = 0; index < table_size(); index++) { 606 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { 607 oop prop = p->property_oop(); 608 if (prop != NULL && prop->is_method()) { 609 f((methodOop)prop); 610 } 611 } 612 } 613} 614 615 616// ---------------------------------------------------------------------------- 617#ifndef PRODUCT 618 619void Dictionary::print() { 620 ResourceMark rm; 621 HandleMark hm; 622 623 tty->print_cr("Java system dictionary (classes=%d)", number_of_entries()); 624 tty->print_cr("^ indicates that initiating loader is different from " 625 "defining loader"); 626 627 for (int index = 0; index < table_size(); index++) { 628 for (DictionaryEntry* probe = bucket(index); 629 probe != NULL; 630 probe = probe->next()) { 631 if (Verbose) tty->print("%4d: ", index); 632 klassOop e = probe->klass(); 633 oop class_loader = probe->loader(); 634 bool is_defining_class = 635 (class_loader == instanceKlass::cast(e)->class_loader()); 636 tty->print("%s%s", is_defining_class ? " " : "^", 637 Klass::cast(e)->external_name()); 638 if (class_loader != NULL) { 639 tty->print(", loader "); 640 class_loader->print_value(); 641 } 642 tty->cr(); 643 } 644 } 645} 646 647#endif 648 649void Dictionary::verify() { 650 guarantee(number_of_entries() >= 0, "Verify of system dictionary failed"); 651 int element_count = 0; 652 for (int index = 0; index < table_size(); index++) { 653 for (DictionaryEntry* probe = bucket(index); 654 probe != NULL; 655 probe = probe->next()) { 656 klassOop e = probe->klass(); 657 oop class_loader = probe->loader(); 658 guarantee(Klass::cast(e)->oop_is_instance(), 659 "Verify of system dictionary failed"); 660 // class loader must be present; a null class loader is the 661 // boostrap loader 662 guarantee(class_loader == NULL || class_loader->is_instance(), 663 "checking type of class_loader"); 664 e->verify(); 665 probe->verify_protection_domain_set(); 666 element_count++; 667 } 668 } 669 guarantee(number_of_entries() == element_count, 670 "Verify of system dictionary failed"); 671 debug_only(verify_lookup_length((double)number_of_entries() / table_size())); 672} 673