placeholders.cpp revision 1879:f95d63e2154a
1/* 2 * Copyright (c) 2003, 2010, 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/placeholders.hpp" 27#include "classfile/systemDictionary.hpp" 28#include "oops/oop.inline.hpp" 29#include "runtime/fieldType.hpp" 30#include "utilities/hashtable.inline.hpp" 31 32// Placeholder methods 33 34PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name, 35 oop loader, bool havesupername, 36 symbolOop supername) { 37 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); 38 entry->set_loader(loader); 39 entry->set_havesupername(havesupername); 40 entry->set_supername(supername); 41 entry->set_superThreadQ(NULL); 42 entry->set_loadInstanceThreadQ(NULL); 43 entry->set_defineThreadQ(NULL); 44 entry->set_definer(NULL); 45 entry->set_instanceKlass(NULL); 46 return entry; 47} 48 49 50// Placeholder objects represent classes currently being loaded. 51// All threads examining the placeholder table must hold the 52// SystemDictionary_lock, so we don't need special precautions 53// on store ordering here. 54void PlaceholderTable::add_entry(int index, unsigned int hash, 55 symbolHandle class_name, Handle class_loader, 56 bool havesupername, symbolHandle supername){ 57 assert_locked_or_safepoint(SystemDictionary_lock); 58 assert(!class_name.is_null(), "adding NULL obj"); 59 60 // Both readers and writers are locked so it's safe to just 61 // create the placeholder and insert it in the list without a membar. 62 PlaceholderEntry* entry = new_entry(hash, class_name(), class_loader(), havesupername, supername()); 63 add_entry(index, entry); 64} 65 66 67// Remove a placeholder object. 68void PlaceholderTable::remove_entry(int index, unsigned int hash, 69 symbolHandle class_name, 70 Handle class_loader) { 71 assert_locked_or_safepoint(SystemDictionary_lock); 72 PlaceholderEntry** p = bucket_addr(index); 73 while (*p) { 74 PlaceholderEntry *probe = *p; 75 if (probe->hash() == hash && probe->equals(class_name(), class_loader())) { 76 // Delete entry 77 *p = probe->next(); 78 free_entry(probe); 79 return; 80 } 81 p = probe->next_addr(); 82 } 83} 84 85PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, 86 symbolHandle class_name, 87 Handle class_loader) { 88 assert_locked_or_safepoint(SystemDictionary_lock); 89 90 symbolOop class_name_ = class_name(); 91 oop class_loader_ = class_loader(); 92 93 for (PlaceholderEntry *place_probe = bucket(index); 94 place_probe != NULL; 95 place_probe = place_probe->next()) { 96 if (place_probe->hash() == hash && 97 place_probe->equals(class_name_, class_loader_)) { 98 return place_probe; 99 } 100 } 101 return NULL; 102} 103 104symbolOop PlaceholderTable::find_entry(int index, unsigned int hash, 105 symbolHandle class_name, 106 Handle class_loader) { 107 PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); 108 return (probe? probe->klass(): symbolOop(NULL)); 109} 110 111 // find_and_add returns probe pointer - old or new 112 // If no entry exists, add a placeholder entry 113 // If entry exists, reuse entry 114 // For both, push SeenThread for classloadAction 115 // if havesupername: this is used for circularity for instanceklass loading 116PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) { 117 PlaceholderEntry* probe = get_entry(index, hash, name, loader); 118 if (probe == NULL) { 119 // Nothing found, add place holder 120 add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername); 121 probe = get_entry(index, hash, name, loader); 122 } else { 123 if (action == LOAD_SUPER) { 124 probe->set_havesupername(true); 125 probe->set_supername(supername()); 126 } 127 } 128 if (probe) probe->add_seen_thread(thread, action); 129 return probe; 130} 131 132 133// placeholder used to track class loading internal states 134// placeholder existence now for loading superclass/superinterface 135// superthreadQ tracks class circularity, while loading superclass/superinterface 136// loadInstanceThreadQ tracks load_instance_class calls 137// definer() tracks the single thread that owns define token 138// defineThreadQ tracks waiters on defining thread's results 139// 1st claimant creates placeholder 140// find_and_add adds SeenThread entry for appropriate queue 141// All claimants remove SeenThread after completing action 142// On removal: if definer and all queues empty, remove entry 143// Note: you can be in both placeholders and systemDictionary 144// see parse_stream for redefine classes 145// Therefore - must always check SD first 146// Ignores the case where entry is not found 147void PlaceholderTable::find_and_remove(int index, unsigned int hash, 148 symbolHandle name, Handle loader, Thread* thread) { 149 assert_locked_or_safepoint(SystemDictionary_lock); 150 PlaceholderEntry *probe = get_entry(index, hash, name, loader); 151 if (probe != NULL) { 152 // No other threads using this entry 153 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) 154 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { 155 remove_entry(index, hash, name, loader); 156 } 157 } 158 } 159 160PlaceholderTable::PlaceholderTable(int table_size) 161 : TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) { 162} 163 164 165void PlaceholderTable::oops_do(OopClosure* f) { 166 for (int index = 0; index < table_size(); index++) { 167 for (PlaceholderEntry* probe = bucket(index); 168 probe != NULL; 169 probe = probe->next()) { 170 probe->oops_do(f); 171 } 172 } 173} 174 175 176void PlaceholderEntry::oops_do(OopClosure* blk) { 177 assert(klass() != NULL, "should have a non-null klass"); 178 blk->do_oop((oop*)klass_addr()); 179 if (_loader != NULL) { 180 blk->do_oop(loader_addr()); 181 } 182 if (_supername != NULL) { 183 blk->do_oop((oop*)supername_addr()); 184 } 185 if (_instanceKlass != NULL) { 186 blk->do_oop((oop*)instanceKlass_addr()); 187 } 188} 189 190// do all entries in the placeholder table 191void PlaceholderTable::entries_do(void f(symbolOop, oop)) { 192 for (int index = 0; index < table_size(); index++) { 193 for (PlaceholderEntry* probe = bucket(index); 194 probe != NULL; 195 probe = probe->next()) { 196 f(probe->klass(), probe->loader()); 197 } 198 } 199} 200 201 202#ifndef PRODUCT 203// Note, doesn't append a cr 204void PlaceholderEntry::print() const { 205 klass()->print_value(); 206 if (loader() != NULL) { 207 tty->print(", loader "); 208 loader()->print_value(); 209 } 210 if (supername() != NULL) { 211 tty->print(", supername "); 212 supername()->print_value(); 213 } 214 if (definer() != NULL) { 215 tty->print(", definer "); 216 definer()->print_value(); 217 } 218 if (instanceKlass() != NULL) { 219 tty->print(", instanceKlass "); 220 instanceKlass()->print_value(); 221 } 222 tty->print("\n"); 223 tty->print("loadInstanceThreadQ threads:"); 224 loadInstanceThreadQ()->printActionQ(); 225 tty->print("\n"); 226 tty->print("superThreadQ threads:"); 227 superThreadQ()->printActionQ(); 228 tty->print("\n"); 229 tty->print("defineThreadQ threads:"); 230 defineThreadQ()->printActionQ(); 231 tty->print("\n"); 232} 233#endif 234 235void PlaceholderEntry::verify() const { 236 guarantee(loader() == NULL || loader()->is_instance(), 237 "checking type of _loader"); 238 guarantee(instanceKlass() == NULL 239 || Klass::cast(instanceKlass())->oop_is_instance(), 240 "checking type of instanceKlass result"); 241 klass()->verify(); 242} 243 244void PlaceholderTable::verify() { 245 int element_count = 0; 246 for (int pindex = 0; pindex < table_size(); pindex++) { 247 for (PlaceholderEntry* probe = bucket(pindex); 248 probe != NULL; 249 probe = probe->next()) { 250 probe->verify(); 251 element_count++; // both klasses and place holders count 252 } 253 } 254 guarantee(number_of_entries() == element_count, 255 "Verify of system dictionary failed"); 256} 257 258 259#ifndef PRODUCT 260void PlaceholderTable::print() { 261 for (int pindex = 0; pindex < table_size(); pindex++) { 262 for (PlaceholderEntry* probe = bucket(pindex); 263 probe != NULL; 264 probe = probe->next()) { 265 if (Verbose) tty->print("%4d: ", pindex); 266 tty->print(" place holder "); 267 268 probe->print(); 269 tty->cr(); 270 } 271 } 272} 273#endif 274