1 /* 2 * Copyright (c) 2017, 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/protectionDomainCache.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "logging/log.hpp" 29 #include "logging/logStream.hpp" 30 #include "memory/iterator.hpp" 31 #include "memory/resourceArea.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "utilities/hashtable.inline.hpp" 34 35 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) { 36 // Identity hash can safepoint, so keep protection domain in a Handle. 37 return (unsigned int)(protection_domain->identity_hash()); 38 } 39 40 int ProtectionDomainCacheTable::index_for(Handle protection_domain) { 41 return hash_to_index(compute_hash(protection_domain)); 42 } 43 44 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size) 45 : Hashtable<oop, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry)) 46 { 47 } 48 49 void ProtectionDomainCacheTable::unlink(BoolObjectClosure* is_alive) { 50 assert(SafepointSynchronize::is_at_safepoint(), "must be"); 51 for (int i = 0; i < table_size(); ++i) { 52 ProtectionDomainCacheEntry** p = bucket_addr(i); 53 ProtectionDomainCacheEntry* entry = bucket(i); 54 while (entry != NULL) { 55 if (is_alive->do_object_b(entry->literal())) { 56 p = entry->next_addr(); 57 } else { 58 LogTarget(Debug, protectiondomain) lt; 59 if (lt.is_enabled()) { 60 LogStream ls(lt); 61 ls.print("protection domain unlinked: "); 62 entry->literal()->print_value_on(&ls); 63 ls.cr(); 64 } 65 *p = entry->next(); 66 free_entry(entry); 67 } 68 entry = *p; 69 } 70 } 71 } 72 73 void ProtectionDomainCacheTable::oops_do(OopClosure* f) { 74 for (int index = 0; index < table_size(); index++) { 75 for (ProtectionDomainCacheEntry* probe = bucket(index); 76 probe != NULL; 77 probe = probe->next()) { 78 probe->oops_do(f); 79 } 80 } 81 } 82 83 void ProtectionDomainCacheTable::print_on(outputStream* st) const { 84 st->print_cr("Protection domain cache table (table_size=%d, classes=%d)", 85 table_size(), number_of_entries()); 86 for (int index = 0; index < table_size(); index++) { 87 for (ProtectionDomainCacheEntry* probe = bucket(index); 88 probe != NULL; 89 probe = probe->next()) { 90 st->print_cr("%4d: protection_domain: " PTR_FORMAT, index, p2i(probe->literal())); 91 } 92 } 93 } 94 95 void ProtectionDomainCacheTable::verify() { 96 verify_table<ProtectionDomainCacheEntry>("Protection Domain Table"); 97 } 98 99 void ProtectionDomainCacheEntry::verify() { 100 guarantee(oopDesc::is_oop(literal()), "must be an oop"); 101 } 102 103 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) { 104 unsigned int hash = compute_hash(protection_domain); 105 int index = hash_to_index(hash); 106 107 ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain); 108 if (entry == NULL) { 109 entry = add_entry(index, hash, protection_domain); 110 } 111 return entry; 112 } 113 114 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) { 115 for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) { 116 if (e->protection_domain() == protection_domain()) { 117 return e; 118 } 119 } 120 121 return NULL; 122 } 123 124 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, Handle protection_domain) { 125 assert_locked_or_safepoint(SystemDictionary_lock); 126 assert(index == index_for(protection_domain), "incorrect index?"); 127 assert(find_entry(index, protection_domain) == NULL, "no double entry"); 128 129 ProtectionDomainCacheEntry* p = new_entry(hash, protection_domain); 130 Hashtable<oop, mtClass>::add_entry(index, p); 131 return p; 132 }