placeholders.hpp revision 13353:46bb2774fc88
1151497Sru/* 2104862Sru * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3104862Sru * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4104862Sru * 5104862Sru * This code is free software; you can redistribute it and/or modify it 6104862Sru * under the terms of the GNU General Public License version 2 only, as 7104862Sru * published by the Free Software Foundation. 8104862Sru * 9104862Sru * This code is distributed in the hope that it will be useful, but WITHOUT 10104862Sru * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11104862Sru * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12104862Sru * version 2 for more details (a copy is included in the LICENSE file that 13104862Sru * accompanied this code). 14104862Sru * 15104862Sru * You should have received a copy of the GNU General Public License version 16104862Sru * 2 along with this work; if not, write to the Free Software Foundation, 17104862Sru * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18151497Sru * 19104862Sru * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20114402Sru * or visit www.oracle.com if you need additional information or have any 21114402Sru * questions. 22151497Sru * 23114402Sru */ 24151497Sru 25151497Sru#ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP 26151497Sru#define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP 27104862Sru 28104862Sru#include "runtime/thread.hpp" 29104862Sru#include "utilities/hashtable.hpp" 30104862Sru 31104862Sruclass PlaceholderEntry; 32104862Sru 33104862Sru// Placeholder objects. These represent classes currently 34104862Sru// being loaded, as well as arrays of primitives. 35104862Sru// 36104862Sru 37104862Sruclass PlaceholderTable : public Hashtable<Symbol*, mtClass> { 38104862Sru 39104862Srupublic: 40104862Sru PlaceholderTable(int table_size); 41104862Sru 42104862Sru PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername); 43104862Sru void free_entry(PlaceholderEntry* entry); 44104862Sru 45104862Sru PlaceholderEntry* bucket(int i) { 46104862Sru return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i); 47104862Sru } 48114402Sru 49104862Sru PlaceholderEntry** bucket_addr(int i) { 50104862Sru return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i); 51114402Sru } 52104862Sru 53104862Sru void add_entry(int index, PlaceholderEntry* new_entry) { 54104862Sru Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry); 55104862Sru } 56104862Sru 57104862Sru void add_entry(int index, unsigned int hash, Symbol* name, 58104862Sru ClassLoaderData* loader_data, bool havesupername, Symbol* supername); 59104862Sru 60104862Sru // This returns a Symbol* to match type for SystemDictionary 61104862Sru Symbol* find_entry(int index, unsigned int hash, 62104862Sru Symbol* name, ClassLoaderData* loader_data); 63104862Sru 64104862Sru PlaceholderEntry* get_entry(int index, unsigned int hash, 65104862Sru Symbol* name, ClassLoaderData* loader_data); 66151497Sru 67151497Sru// caller to create a placeholder entry must enumerate an action 68151497Sru// caller claims ownership of that action 69104862Sru// For parallel classloading: 70104862Sru// multiple LOAD_INSTANCE threads can proceed in parallel 71104862Sru// multiple LOAD_SUPER threads can proceed in parallel 72104862Sru// LOAD_SUPER needed to check for class circularity 73104862Sru// DEFINE_CLASS: ultimately define class must be single threaded 74151497Sru// on a class/classloader basis 75104862Sru// so the head of that queue owns the token 76104862Sru// and the rest of the threads return the result the first thread gets 77104862Sru enum classloadAction { 78104862Sru LOAD_INSTANCE = 1, // calling load_instance_class 79104862Sru LOAD_SUPER = 2, // loading superclass for this class 80104862Sru DEFINE_CLASS = 3 // find_or_define class 81104862Sru }; 82104862Sru 83104862Sru // find_and_add returns probe pointer - old or new 84104862Sru // If no entry exists, add a placeholder entry and push SeenThread for classloadAction 85104862Sru // If entry exists, reuse entry and push SeenThread for classloadAction 86104862Sru PlaceholderEntry* find_and_add(int index, unsigned int hash, 87104862Sru Symbol* name, ClassLoaderData* loader_data, 88104862Sru classloadAction action, Symbol* supername, 89104862Sru Thread* thread); 90104862Sru 91104862Sru void remove_entry(int index, unsigned int hash, 92104862Sru Symbol* name, ClassLoaderData* loader_data); 93104862Sru 94104862Sru // find_and_remove first removes SeenThread for classloadAction 95104862Sru // If all queues are empty and definer is null, remove the PlacheholderEntry completely 96151497Sru void find_and_remove(int index, unsigned int hash, 97151497Sru Symbol* name, ClassLoaderData* loader_data, 98151497Sru classloadAction action, Thread* thread); 99151497Sru 100151497Sru#ifndef PRODUCT 101104862Sru void print(); 102104862Sru#endif 103104862Sru void verify(); 104104862Sru}; 105104862Sru 106151497Sru// SeenThread objects represent list of threads that are 107104862Sru// currently performing a load action on a class. 108104862Sru// For class circularity, set before loading a superclass. 109104862Sru// For bootclasssearchpath, set before calling load_instance_class. 110104862Sru// Defining must be single threaded on a class/classloader basis 111104862Sru// For DEFINE_CLASS, the head of the queue owns the 112104862Sru// define token and the rest of the threads wait to return the 113104862Sru// result the first thread gets. 114104862Sruclass SeenThread: public CHeapObj<mtInternal> { 115104862Sruprivate: 116104862Sru Thread *_thread; 117104862Sru SeenThread* _stnext; 118104862Sru SeenThread* _stprev; 119104862Srupublic: 120104862Sru SeenThread(Thread *thread) { 121104862Sru _thread = thread; 122104862Sru _stnext = NULL; 123104862Sru _stprev = NULL; 124104862Sru } 125104862Sru Thread* thread() const { return _thread;} 126104862Sru void set_thread(Thread *thread) { _thread = thread; } 127104862Sru 128104862Sru SeenThread* next() const { return _stnext;} 129104862Sru void set_next(SeenThread *seen) { _stnext = seen; } 130104862Sru void set_prev(SeenThread *seen) { _stprev = seen; } 131151497Sru 132151497Sru#ifndef PRODUCT 133151497Sru void printActionQ() { 134104862Sru SeenThread* seen = this; 135151497Sru while (seen != NULL) { 136151497Sru seen->thread()->print_value(); 137151497Sru tty->print(", "); 138151497Sru seen = seen->next(); 139151497Sru } 140151497Sru } 141151497Sru#endif // PRODUCT 142151497Sru}; 143151497Sru 144104862Sru// Placeholder objects represent classes currently being loaded. 145104862Sru// All threads examining the placeholder table must hold the 146151497Sru// SystemDictionary_lock, so we don't need special precautions 147104862Sru// on store ordering here. 148104862Sru// The system dictionary is the only user of this class. 149114402Sru 150114402Sruclass PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> { 151151497Sru 152104862Sru private: 153104862Sru ClassLoaderData* _loader_data; // initiating loader 154104862Sru bool _havesupername; // distinguish between null supername, and unknown 155151497Sru Symbol* _supername; 156151497Sru Thread* _definer; // owner of define token 157151497Sru InstanceKlass* _instanceKlass; // InstanceKlass from successful define 158151497Sru SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class 159151497Sru SeenThread* _loadInstanceThreadQ; // loadInstance thread 160151497Sru // can be multiple threads if classloader object lock broken by application 161104862Sru // or if classloader supports parallel classloading 162104862Sru 163104862Sru SeenThread* _defineThreadQ; // queue of Threads trying to define this class 164104862Sru // including _definer 165104862Sru // _definer owns token 166104862Sru // queue waits for and returns results from _definer 167104862Sru 168104862Sru public: 169104862Sru // Simple accessors, used only by SystemDictionary 170104862Sru Symbol* klassname() const { return literal(); } 171104862Sru 172104862Sru ClassLoaderData* loader_data() const { return _loader_data; } 173104862Sru void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; } 174151497Sru 175104862Sru bool havesupername() const { return _havesupername; } 176104862Sru void set_havesupername(bool havesupername) { _havesupername = havesupername; } 177104862Sru 178104862Sru Symbol* supername() const { return _supername; } 179104862Sru void set_supername(Symbol* supername) { 180104862Sru _supername = supername; 181104862Sru if (_supername != NULL) _supername->increment_refcount(); 182104862Sru } 183104862Sru 184104862Sru Thread* definer() const {return _definer; } 185104862Sru void set_definer(Thread* definer) { _definer = definer; } 186104862Sru 187104862Sru InstanceKlass* instance_klass() const {return _instanceKlass; } 188104862Sru void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; } 189104862Sru 190104862Sru SeenThread* superThreadQ() const { return _superThreadQ; } 191104862Sru void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; } 192104862Sru 193104862Sru SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; } 194104862Sru void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; } 195104862Sru 196104862Sru SeenThread* defineThreadQ() const { return _defineThreadQ; } 197104862Sru void set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; } 198104862Sru 199104862Sru PlaceholderEntry* next() const { 200151497Sru return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next(); 201104862Sru } 202104862Sru 203104862Sru PlaceholderEntry** next_addr() { 204104862Sru return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr(); 205104862Sru } 206104862Sru 207104862Sru // Test for equality 208104862Sru // Entries are unique for class/classloader name pair 209104862Sru bool equals(Symbol* class_name, ClassLoaderData* loader) const { 210104862Sru return (klassname() == class_name && loader_data() == loader); 211104862Sru } 212104862Sru 213104862Sru SeenThread* actionToQueue(PlaceholderTable::classloadAction action) { 214104862Sru SeenThread* queuehead = NULL; 215104862Sru switch (action) { 216104862Sru case PlaceholderTable::LOAD_INSTANCE: 217151497Sru queuehead = _loadInstanceThreadQ; 218104862Sru break; 219104862Sru case PlaceholderTable::LOAD_SUPER: 220151497Sru queuehead = _superThreadQ; 221104862Sru break; 222104862Sru case PlaceholderTable::DEFINE_CLASS: 223104862Sru queuehead = _defineThreadQ; 224151497Sru break; 225104862Sru default: Unimplemented(); 226104862Sru } 227104862Sru return queuehead; 228104862Sru } 229151497Sru 230104862Sru void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) { 231104862Sru switch (action) { 232104862Sru case PlaceholderTable::LOAD_INSTANCE: 233104862Sru _loadInstanceThreadQ = seenthread; 234 break; 235 case PlaceholderTable::LOAD_SUPER: 236 _superThreadQ = seenthread; 237 break; 238 case PlaceholderTable::DEFINE_CLASS: 239 _defineThreadQ = seenthread; 240 break; 241 default: Unimplemented(); 242 } 243 return; 244 } 245 246 bool super_load_in_progress() { 247 return (_superThreadQ != NULL); 248 } 249 250 bool instance_load_in_progress() { 251 return (_loadInstanceThreadQ != NULL); 252 } 253 254 bool define_class_in_progress() { 255 return (_defineThreadQ != NULL); 256 } 257 258// Doubly-linked list of Threads per action for class/classloader pair 259// Class circularity support: links in thread before loading superclass 260// bootstrapsearchpath support: links in a thread before load_instance_class 261// definers: use as queue of define requestors, including owner of 262// define token. Appends for debugging of requestor order 263 void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { 264 assert_lock_strong(SystemDictionary_lock); 265 SeenThread* threadEntry = new SeenThread(thread); 266 SeenThread* seen = actionToQueue(action); 267 268 if (seen == NULL) { 269 set_threadQ(threadEntry, action); 270 return; 271 } 272 SeenThread* next; 273 while ((next = seen->next()) != NULL) { 274 seen = next; 275 } 276 seen->set_next(threadEntry); 277 threadEntry->set_prev(seen); 278 return; 279 } 280 281 bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { 282 assert_lock_strong(SystemDictionary_lock); 283 SeenThread* threadQ = actionToQueue(action); 284 SeenThread* seen = threadQ; 285 while (seen) { 286 if (thread == seen->thread()) { 287 return true; 288 } 289 seen = seen->next(); 290 } 291 return false; 292 } 293 294 // returns true if seenthreadQ is now empty 295 // Note, caller must ensure probe still exists while holding 296 // SystemDictionary_lock 297 // ignores if cleanup has already been done 298 // if found, deletes SeenThread 299 bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { 300 assert_lock_strong(SystemDictionary_lock); 301 SeenThread* threadQ = actionToQueue(action); 302 SeenThread* seen = threadQ; 303 SeenThread* prev = NULL; 304 while (seen) { 305 if (thread == seen->thread()) { 306 if (prev) { 307 prev->set_next(seen->next()); 308 } else { 309 set_threadQ(seen->next(), action); 310 } 311 if (seen->next()) { 312 seen->next()->set_prev(prev); 313 } 314 delete seen; 315 break; 316 } 317 prev = seen; 318 seen = seen->next(); 319 } 320 return (actionToQueue(action) == NULL); 321 } 322 323 // Print method doesn't append a cr 324 void print() const PRODUCT_RETURN; 325 void verify() const; 326}; 327 328#endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP 329