void PlaceholderTable::classes_do(KlassClosure* f) { for (int index = 0; index < table_size(); index++) { for (PlaceholderEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { probe->classes_do(f); } } }
// do all entries in the placeholder table void PlaceholderTable::entries_do(void f(Symbol*)) { for (int index = 0; index < table_size(); index++) { for (PlaceholderEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { f(probe->klassname()); } } }
// do all entries in the placeholder table void PlaceholderTable::entries_do(void f(symbolOop, oop)) { for (int index = 0; index < table_size(); index++) { for (PlaceholderEntry* probe = bucket(index); probe != NULL; probe = probe->next()) { f(probe->klass(), probe->loader()); } } }
// placeholder used to track class loading internal states // placeholder existence now for loading superclass/superinterface // superthreadQ tracks class circularity, while loading superclass/superinterface // loadInstanceThreadQ tracks load_instance_class calls // definer() tracks the single thread that owns define token // defineThreadQ tracks waiters on defining thread's results // 1st claimant creates placeholder // find_and_add adds SeenThread entry for appropriate queue // All claimants remove SeenThread after completing action // On removal: if definer and all queues empty, remove entry // Note: you can be in both placeholders and systemDictionary // see parse_stream for redefine classes // Therefore - must always check SD first // Ignores the case where entry is not found void PlaceholderTable::find_and_remove(int index, unsigned int hash, symbolHandle name, Handle loader, Thread* thread) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry *probe = get_entry(index, hash, name, loader); if (probe != NULL) { // No other threads using this entry if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { remove_entry(index, hash, name, loader); } } }
void PlaceholderTable::print() { for (int pindex = 0; pindex < table_size(); pindex++) { for (PlaceholderEntry* probe = bucket(pindex); probe != NULL; probe = probe->next()) { if (Verbose) tty->print("%4d: ", pindex); tty->print(" place holder "); probe->print(); tty->cr(); } } }
void PlaceholderTable::verify() { int element_count = 0; for (int pindex = 0; pindex < table_size(); pindex++) { for (PlaceholderEntry* probe = bucket(pindex); probe != NULL; probe = probe->next()) { probe->verify(); element_count++; // both klasses and place holders count } } guarantee(number_of_entries() == element_count, "Verify of system dictionary failed"); }
// find_and_add returns probe pointer - old or new // If no entry exists, add a placeholder entry // If entry exists, reuse entry // For both, push SeenThread for classloadAction // if havesupername: this is used for circularity for instanceklass loading PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) { PlaceholderEntry* probe = get_entry(index, hash, name, loader); if (probe == NULL) { // Nothing found, add place holder add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername); probe = get_entry(index, hash, name, loader); } else { if (action == LOAD_SUPER) { probe->set_havesupername(true); probe->set_supername(supername()); } } if (probe) probe->add_seen_thread(thread, action); return probe; }
// Remove a placeholder object. void PlaceholderTable::remove_entry(int index, unsigned int hash, Symbol* class_name, ClassLoaderData* loader_data) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry** p = bucket_addr(index); while (*p) { PlaceholderEntry *probe = *p; if (probe->hash() == hash && probe->equals(class_name, loader_data)) { // Delete entry *p = probe->next(); free_entry(probe); return; } p = probe->next_addr(); } }
PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name, oop loader, bool havesupername, symbolOop supername) { PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); entry->set_loader(loader); entry->set_havesupername(havesupername); entry->set_supername(supername); entry->set_superThreadQ(NULL); entry->set_loadInstanceThreadQ(NULL); entry->set_defineThreadQ(NULL); entry->set_definer(NULL); entry->set_instanceKlass(NULL); return entry; }
PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername) { PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name); // Hashtable with Symbol* literal must increment and decrement refcount. name->increment_refcount(); entry->set_loader_data(loader_data); entry->set_havesupername(havesupername); entry->set_supername(supername); entry->set_superThreadQ(NULL); entry->set_loadInstanceThreadQ(NULL); entry->set_defineThreadQ(NULL); entry->set_definer(NULL); entry->set_instance_klass(NULL); return entry; }
// placeholder is used to track class loading internal states // placeholder existence now for loading superclass/superinterface // superthreadQ tracks class circularity, while loading superclass/superinterface // loadInstanceThreadQ tracks load_instance_class calls // definer() tracks the single thread that owns define token // defineThreadQ tracks waiters on defining thread's results // 1st claimant creates placeholder // find_and_add adds SeenThread entry for appropriate queue // All claimants remove SeenThread after completing action // On removal: if definer and all queues empty, remove entry // Note: you can be in both placeholders and systemDictionary // Therefore - must always check SD first // Ignores the case where entry is not found void PlaceholderTable::find_and_remove(int index, unsigned int hash, Symbol* name, ClassLoaderData* loader_data, classloadAction action, Thread* thread) { assert_locked_or_safepoint(SystemDictionary_lock); PlaceholderEntry *probe = get_entry(index, hash, name, loader_data); if (probe != NULL) { probe->remove_seen_thread(thread, action); // If no other threads using this entry, and this thread is not using this entry for other states if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { remove_entry(index, hash, name, loader_data); } } }
Symbol* PlaceholderTable::find_entry(int index, unsigned int hash, Symbol* class_name, ClassLoaderData* loader_data) { PlaceholderEntry* probe = get_entry(index, hash, class_name, loader_data); return (probe? probe->klassname(): (Symbol*)NULL); }
symbolOop PlaceholderTable::find_entry(int index, unsigned int hash, symbolHandle class_name, Handle class_loader) { PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); return (probe? probe->klass(): symbolOop(NULL)); }