1 /* 2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP 26 #define SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP 27 28 #include "oops/oop.hpp" 29 #include "oops/weakHandle.hpp" 30 #include "memory/iterator.hpp" 31 #include "utilities/hashtable.hpp" 32 33 // This class caches the approved protection domains that can access loaded classes. 34 // Dictionary entry pd_set point to entries in this hashtable. Please refer 35 // to dictionary.hpp pd_set for more information about how protection domain entries 36 // are used. 37 // This table is walked during GC, rather than the class loader data graph dictionaries. 38 class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass> { 39 friend class VMStructs; 40 public: 41 oop object(); 42 oop object_no_keepalive(); 43 next()44 ProtectionDomainCacheEntry* next() { 45 return (ProtectionDomainCacheEntry*)HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass>::next(); 46 } 47 next_addr()48 ProtectionDomainCacheEntry** next_addr() { 49 return (ProtectionDomainCacheEntry**)HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass>::next_addr(); 50 } 51 52 void verify(); 53 }; 54 55 // The ProtectionDomainCacheTable contains all protection domain oops. The 56 // dictionary entries reference its entries instead of having references to oops 57 // directly. 58 // This is used to speed up system dictionary iteration: the oops in the 59 // protection domain are the only ones referring the Java heap. So when there is 60 // need to update these, instead of going over every entry of the system dictionary, 61 // we only need to iterate over this set. 62 // The amount of different protection domains used is typically magnitudes smaller 63 // than the number of system dictionary entries (loaded classes). 64 class ProtectionDomainCacheTable : public Hashtable<WeakHandle<vm_class_loader_data>, mtClass> { 65 friend class VMStructs; 66 private: bucket(int i) const67 ProtectionDomainCacheEntry* bucket(int i) const { 68 return (ProtectionDomainCacheEntry*) Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::bucket(i); 69 } 70 71 // The following method is not MT-safe and must be done under lock. bucket_addr(int i)72 ProtectionDomainCacheEntry** bucket_addr(int i) { 73 return (ProtectionDomainCacheEntry**) Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::bucket_addr(i); 74 } 75 new_entry(unsigned int hash,WeakHandle<vm_class_loader_data> protection_domain)76 ProtectionDomainCacheEntry* new_entry(unsigned int hash, WeakHandle<vm_class_loader_data> protection_domain) { 77 ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) 78 Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::new_entry(hash, protection_domain); 79 return entry; 80 } 81 82 static unsigned int compute_hash(Handle protection_domain); 83 84 int index_for(Handle protection_domain); 85 ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, Handle protection_domain); 86 ProtectionDomainCacheEntry* find_entry(int index, Handle protection_domain); 87 88 bool _dead_entries; 89 int _total_oops_removed; 90 91 public: 92 ProtectionDomainCacheTable(int table_size); 93 ProtectionDomainCacheEntry* get(Handle protection_domain); 94 95 void unlink(); 96 97 void print_on(outputStream* st) const; 98 void verify(); 99 has_work()100 bool has_work() { return _dead_entries; } 101 void trigger_cleanup(); 102 removed_entries_count()103 int removed_entries_count() { return _total_oops_removed; }; 104 }; 105 106 107 class ProtectionDomainEntry :public CHeapObj<mtClass> { 108 friend class VMStructs; 109 public: 110 ProtectionDomainEntry* _next; 111 ProtectionDomainCacheEntry* _pd_cache; 112 ProtectionDomainEntry(ProtectionDomainCacheEntry * pd_cache,ProtectionDomainEntry * next)113 ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) { 114 _pd_cache = pd_cache; 115 _next = next; 116 } 117 next()118 ProtectionDomainEntry* next() { return _next; } set_next(ProtectionDomainEntry * entry)119 void set_next(ProtectionDomainEntry* entry) { _next = entry; } 120 oop object(); 121 oop object_no_keepalive(); 122 }; 123 #endif // SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP 124