src/share/vm/classfile/placeholders.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4425
aefb345d3f5e
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/placeholders.hpp"
aoqi@0 27 #include "classfile/systemDictionary.hpp"
aoqi@0 28 #include "oops/oop.inline.hpp"
aoqi@0 29 #include "runtime/fieldType.hpp"
aoqi@0 30 #include "utilities/hashtable.inline.hpp"
aoqi@0 31
aoqi@0 32 // Placeholder methods
aoqi@0 33
aoqi@0 34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
aoqi@0 35 ClassLoaderData* loader_data,
aoqi@0 36 bool havesupername,
aoqi@0 37 Symbol* supername) {
aoqi@0 38 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
aoqi@0 39 // Hashtable with Symbol* literal must increment and decrement refcount.
aoqi@0 40 name->increment_refcount();
aoqi@0 41 entry->set_loader_data(loader_data);
aoqi@0 42 entry->set_havesupername(havesupername);
aoqi@0 43 entry->set_supername(supername);
aoqi@0 44 entry->set_superThreadQ(NULL);
aoqi@0 45 entry->set_loadInstanceThreadQ(NULL);
aoqi@0 46 entry->set_defineThreadQ(NULL);
aoqi@0 47 entry->set_definer(NULL);
aoqi@0 48 entry->set_instance_klass(NULL);
aoqi@0 49 return entry;
aoqi@0 50 }
aoqi@0 51
aoqi@0 52 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
aoqi@0 53 // decrement Symbol refcount here because Hashtable doesn't.
aoqi@0 54 entry->literal()->decrement_refcount();
aoqi@0 55 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
aoqi@0 56 Hashtable<Symbol*, mtClass>::free_entry(entry);
aoqi@0 57 }
aoqi@0 58
aoqi@0 59
aoqi@0 60 // Placeholder objects represent classes currently being loaded.
aoqi@0 61 // All threads examining the placeholder table must hold the
aoqi@0 62 // SystemDictionary_lock, so we don't need special precautions
aoqi@0 63 // on store ordering here.
aoqi@0 64 void PlaceholderTable::add_entry(int index, unsigned int hash,
aoqi@0 65 Symbol* class_name, ClassLoaderData* loader_data,
aoqi@0 66 bool havesupername, Symbol* supername){
aoqi@0 67 assert_locked_or_safepoint(SystemDictionary_lock);
aoqi@0 68 assert(class_name != NULL, "adding NULL obj");
aoqi@0 69
aoqi@0 70 // Both readers and writers are locked so it's safe to just
aoqi@0 71 // create the placeholder and insert it in the list without a membar.
aoqi@0 72 PlaceholderEntry* entry = new_entry(hash, class_name, loader_data, havesupername, supername);
aoqi@0 73 add_entry(index, entry);
aoqi@0 74 }
aoqi@0 75
aoqi@0 76
aoqi@0 77 // Remove a placeholder object.
aoqi@0 78 void PlaceholderTable::remove_entry(int index, unsigned int hash,
aoqi@0 79 Symbol* class_name,
aoqi@0 80 ClassLoaderData* loader_data) {
aoqi@0 81 assert_locked_or_safepoint(SystemDictionary_lock);
aoqi@0 82 PlaceholderEntry** p = bucket_addr(index);
aoqi@0 83 while (*p) {
aoqi@0 84 PlaceholderEntry *probe = *p;
aoqi@0 85 if (probe->hash() == hash && probe->equals(class_name, loader_data)) {
aoqi@0 86 // Delete entry
aoqi@0 87 *p = probe->next();
aoqi@0 88 free_entry(probe);
aoqi@0 89 return;
aoqi@0 90 }
aoqi@0 91 p = probe->next_addr();
aoqi@0 92 }
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
aoqi@0 96 Symbol* class_name,
aoqi@0 97 ClassLoaderData* loader_data) {
aoqi@0 98 assert_locked_or_safepoint(SystemDictionary_lock);
aoqi@0 99
aoqi@0 100 for (PlaceholderEntry *place_probe = bucket(index);
aoqi@0 101 place_probe != NULL;
aoqi@0 102 place_probe = place_probe->next()) {
aoqi@0 103 if (place_probe->hash() == hash &&
aoqi@0 104 place_probe->equals(class_name, loader_data)) {
aoqi@0 105 return place_probe;
aoqi@0 106 }
aoqi@0 107 }
aoqi@0 108 return NULL;
aoqi@0 109 }
aoqi@0 110
aoqi@0 111 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
aoqi@0 112 Symbol* class_name,
aoqi@0 113 ClassLoaderData* loader_data) {
aoqi@0 114 PlaceholderEntry* probe = get_entry(index, hash, class_name, loader_data);
aoqi@0 115 return (probe? probe->klassname(): (Symbol*)NULL);
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 // find_and_add returns probe pointer - old or new
aoqi@0 119 // If no entry exists, add a placeholder entry
aoqi@0 120 // If entry exists, reuse entry
aoqi@0 121 // For both, push SeenThread for classloadAction
aoqi@0 122 // if havesupername: this is used for circularity for instanceklass loading
aoqi@0 123 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
aoqi@0 124 Symbol* name,
aoqi@0 125 ClassLoaderData* loader_data,
aoqi@0 126 classloadAction action,
aoqi@0 127 Symbol* supername,
aoqi@0 128 Thread* thread) {
aoqi@0 129 PlaceholderEntry* probe = get_entry(index, hash, name, loader_data);
aoqi@0 130 if (probe == NULL) {
aoqi@0 131 // Nothing found, add place holder
aoqi@0 132 add_entry(index, hash, name, loader_data, (action == LOAD_SUPER), supername);
aoqi@0 133 probe = get_entry(index, hash, name, loader_data);
aoqi@0 134 } else {
aoqi@0 135 if (action == LOAD_SUPER) {
aoqi@0 136 probe->set_havesupername(true);
aoqi@0 137 probe->set_supername(supername);
aoqi@0 138 }
aoqi@0 139 }
aoqi@0 140 if (probe) probe->add_seen_thread(thread, action);
aoqi@0 141 return probe;
aoqi@0 142 }
aoqi@0 143
aoqi@0 144
aoqi@0 145 // placeholder is used to track class loading internal states
aoqi@0 146 // placeholder existence now for loading superclass/superinterface
aoqi@0 147 // superthreadQ tracks class circularity, while loading superclass/superinterface
aoqi@0 148 // loadInstanceThreadQ tracks load_instance_class calls
aoqi@0 149 // definer() tracks the single thread that owns define token
aoqi@0 150 // defineThreadQ tracks waiters on defining thread's results
aoqi@0 151 // 1st claimant creates placeholder
aoqi@0 152 // find_and_add adds SeenThread entry for appropriate queue
aoqi@0 153 // All claimants remove SeenThread after completing action
aoqi@0 154 // On removal: if definer and all queues empty, remove entry
aoqi@0 155 // Note: you can be in both placeholders and systemDictionary
aoqi@0 156 // Therefore - must always check SD first
aoqi@0 157 // Ignores the case where entry is not found
aoqi@0 158 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
aoqi@0 159 Symbol* name, ClassLoaderData* loader_data,
aoqi@0 160 classloadAction action,
aoqi@0 161 Thread* thread) {
aoqi@0 162 assert_locked_or_safepoint(SystemDictionary_lock);
aoqi@0 163 PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
aoqi@0 164 if (probe != NULL) {
aoqi@0 165 probe->remove_seen_thread(thread, action);
aoqi@0 166 // If no other threads using this entry, and this thread is not using this entry for other states
aoqi@0 167 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
aoqi@0 168 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
aoqi@0 169 remove_entry(index, hash, name, loader_data);
aoqi@0 170 }
aoqi@0 171 }
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 PlaceholderTable::PlaceholderTable(int table_size)
aoqi@0 175 : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
aoqi@0 176 }
aoqi@0 177
aoqi@0 178
aoqi@0 179 void PlaceholderTable::classes_do(KlassClosure* f) {
aoqi@0 180 for (int index = 0; index < table_size(); index++) {
aoqi@0 181 for (PlaceholderEntry* probe = bucket(index);
aoqi@0 182 probe != NULL;
aoqi@0 183 probe = probe->next()) {
aoqi@0 184 probe->classes_do(f);
aoqi@0 185 }
aoqi@0 186 }
aoqi@0 187 }
aoqi@0 188
aoqi@0 189
aoqi@0 190 void PlaceholderEntry::classes_do(KlassClosure* closure) {
aoqi@0 191 assert(klassname() != NULL, "should have a non-null klass");
aoqi@0 192 if (_instanceKlass != NULL) {
aoqi@0 193 closure->do_klass(instance_klass());
aoqi@0 194 }
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 // do all entries in the placeholder table
aoqi@0 198 void PlaceholderTable::entries_do(void f(Symbol*)) {
aoqi@0 199 for (int index = 0; index < table_size(); index++) {
aoqi@0 200 for (PlaceholderEntry* probe = bucket(index);
aoqi@0 201 probe != NULL;
aoqi@0 202 probe = probe->next()) {
aoqi@0 203 f(probe->klassname());
aoqi@0 204 }
aoqi@0 205 }
aoqi@0 206 }
aoqi@0 207
aoqi@0 208
aoqi@0 209 #ifndef PRODUCT
aoqi@0 210 // Note, doesn't append a cr
aoqi@0 211 void PlaceholderEntry::print() const {
aoqi@0 212 klassname()->print_value();
aoqi@0 213 if (loader_data() != NULL) {
aoqi@0 214 tty->print(", loader ");
aoqi@0 215 loader_data()->print_value();
aoqi@0 216 }
aoqi@0 217 if (supername() != NULL) {
aoqi@0 218 tty->print(", supername ");
aoqi@0 219 supername()->print_value();
aoqi@0 220 }
aoqi@0 221 if (definer() != NULL) {
aoqi@0 222 tty->print(", definer ");
aoqi@0 223 definer()->print_value();
aoqi@0 224 }
aoqi@0 225 if (instance_klass() != NULL) {
aoqi@0 226 tty->print(", InstanceKlass ");
aoqi@0 227 instance_klass()->print_value();
aoqi@0 228 }
aoqi@0 229 tty->print("\n");
aoqi@0 230 tty->print("loadInstanceThreadQ threads:");
aoqi@0 231 loadInstanceThreadQ()->printActionQ();
aoqi@0 232 tty->print("\n");
aoqi@0 233 tty->print("superThreadQ threads:");
aoqi@0 234 superThreadQ()->printActionQ();
aoqi@0 235 tty->print("\n");
aoqi@0 236 tty->print("defineThreadQ threads:");
aoqi@0 237 defineThreadQ()->printActionQ();
aoqi@0 238 tty->print("\n");
aoqi@0 239 }
aoqi@0 240 #endif
aoqi@0 241
aoqi@0 242 void PlaceholderEntry::verify() const {
aoqi@0 243 guarantee(loader_data() != NULL, "Must have been setup.");
aoqi@0 244 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
aoqi@0 245 "checking type of _loader");
aoqi@0 246 guarantee(instance_klass() == NULL
aoqi@0 247 || instance_klass()->oop_is_instance(),
aoqi@0 248 "checking type of instance_klass result");
aoqi@0 249 }
aoqi@0 250
aoqi@0 251 void PlaceholderTable::verify() {
aoqi@0 252 int element_count = 0;
aoqi@0 253 for (int pindex = 0; pindex < table_size(); pindex++) {
aoqi@0 254 for (PlaceholderEntry* probe = bucket(pindex);
aoqi@0 255 probe != NULL;
aoqi@0 256 probe = probe->next()) {
aoqi@0 257 probe->verify();
aoqi@0 258 element_count++; // both klasses and place holders count
aoqi@0 259 }
aoqi@0 260 }
aoqi@0 261 guarantee(number_of_entries() == element_count,
aoqi@0 262 "Verify of system dictionary failed");
aoqi@0 263 }
aoqi@0 264
aoqi@0 265
aoqi@0 266 #ifndef PRODUCT
aoqi@0 267 void PlaceholderTable::print() {
aoqi@0 268 for (int pindex = 0; pindex < table_size(); pindex++) {
aoqi@0 269 for (PlaceholderEntry* probe = bucket(pindex);
aoqi@0 270 probe != NULL;
aoqi@0 271 probe = probe->next()) {
aoqi@0 272 if (Verbose) tty->print("%4d: ", pindex);
aoqi@0 273 tty->print(" place holder ");
aoqi@0 274
aoqi@0 275 probe->print();
aoqi@0 276 tty->cr();
aoqi@0 277 }
aoqi@0 278 }
aoqi@0 279 }
aoqi@0 280 #endif

mercurial