< prev index next >

src/hotspot/share/classfile/placeholders.hpp

Print this page




  57   void add_entry(int index, unsigned int hash, Symbol* name,
  58                 ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
  59 
  60   // This returns a Symbol* to match type for SystemDictionary
  61   Symbol* find_entry(int index, unsigned int hash,
  62                        Symbol* name, ClassLoaderData* loader_data);
  63 
  64   PlaceholderEntry* get_entry(int index, unsigned int hash,
  65                        Symbol* name, ClassLoaderData* loader_data);
  66 
  67 // caller to create a placeholder entry must enumerate an action
  68 // caller claims ownership of that action
  69 // For parallel classloading:
  70 // multiple LOAD_INSTANCE threads can proceed in parallel
  71 // multiple LOAD_SUPER threads can proceed in parallel
  72 // LOAD_SUPER needed to check for class circularity
  73 // DEFINE_CLASS: ultimately define class must be single threaded
  74 // on a class/classloader basis
  75 // so the head of that queue owns the token
  76 // and the rest of the threads return the result the first thread gets

  77  enum classloadAction {
  78     LOAD_INSTANCE = 1,             // calling load_instance_class
  79     LOAD_SUPER = 2,                // loading superclass for this class
  80     DEFINE_CLASS = 3               // find_or_define class

  81  };
  82 
  83   // find_and_add returns probe pointer - old or new
  84   // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
  85   // If entry exists, reuse entry and push SeenThread for classloadAction
  86   PlaceholderEntry* find_and_add(int index, unsigned int hash,
  87                                  Symbol* name, ClassLoaderData* loader_data,
  88                                  classloadAction action, Symbol* supername,
  89                                  Thread* thread);
  90 
  91   void remove_entry(int index, unsigned int hash,
  92                     Symbol* name, ClassLoaderData* loader_data);
  93 
  94   // find_and_remove first removes SeenThread for classloadAction
  95   // If all queues are empty and definer is null, remove the PlacheholderEntry completely
  96   void find_and_remove(int index, unsigned int hash,
  97                        Symbol* name, ClassLoaderData* loader_data,
  98                        classloadAction action, Thread* thread);
  99 
 100   void print_on(outputStream* st) const;
 101   void verify();
 102 };
 103 
 104 // SeenThread objects represent list of threads that are
 105 // currently performing a load action on a class.
 106 // For class circularity, set before loading a superclass.
 107 // For bootclasssearchpath, set before calling load_instance_class.
 108 // Defining must be single threaded on a class/classloader basis
 109 // For DEFINE_CLASS, the head of the queue owns the
 110 // define token and the rest of the threads wait to return the
 111 // result the first thread gets.


 112 class SeenThread: public CHeapObj<mtInternal> {
 113 private:
 114    Thread *_thread;
 115    SeenThread* _stnext;
 116    SeenThread* _stprev;
 117 public:
 118    SeenThread(Thread *thread) {
 119        _thread = thread;
 120        _stnext = NULL;
 121        _stprev = NULL;
 122    }
 123    Thread* thread()                const { return _thread;}
 124    void set_thread(Thread *thread) { _thread = thread; }
 125 
 126    SeenThread* next()              const { return _stnext;}
 127    void set_next(SeenThread *seen) { _stnext = seen; }
 128    void set_prev(SeenThread *seen) { _stprev = seen; }
 129 
 130   void print_action_queue(outputStream* st) {
 131     SeenThread* seen = this;


 143 // on store ordering here.
 144 // The system dictionary is the only user of this class.
 145 
 146 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
 147 
 148  private:
 149   ClassLoaderData*  _loader_data;   // initiating loader
 150   bool              _havesupername; // distinguish between null supername, and unknown
 151   Symbol*           _supername;
 152   Thread*           _definer;       // owner of define token
 153   InstanceKlass*    _instanceKlass; // InstanceKlass from successful define
 154   SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
 155   SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
 156                                     // can be multiple threads if classloader object lock broken by application
 157                                     // or if classloader supports parallel classloading
 158 
 159   SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
 160                                     // including _definer
 161                                     // _definer owns token
 162                                     // queue waits for and returns results from _definer

 163 
 164  public:
 165   // Simple accessors, used only by SystemDictionary
 166   Symbol*            klassname()           const { return literal(); }
 167 
 168   ClassLoaderData*   loader_data()         const { return _loader_data; }
 169   void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
 170 
 171   bool               havesupername()       const { return _havesupername; }
 172   void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
 173 
 174   Symbol*            supername()           const { return _supername; }
 175   void               set_supername(Symbol* supername) {
 176     _supername = supername;
 177     if (_supername != NULL) _supername->increment_refcount();
 178   }
 179 
 180   Thread*            definer()             const {return _definer; }
 181   void               set_definer(Thread* definer) { _definer = definer; }
 182 
 183   InstanceKlass*     instance_klass()      const {return _instanceKlass; }
 184   void               set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
 185 
 186   SeenThread*        superThreadQ()        const { return _superThreadQ; }
 187   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
 188 
 189   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
 190   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
 191 
 192   SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
 193   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
 194 



 195   PlaceholderEntry* next() const {
 196     return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
 197   }
 198 
 199   PlaceholderEntry** next_addr() {
 200     return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
 201   }
 202 
 203   // Test for equality
 204   // Entries are unique for class/classloader name pair
 205   bool equals(Symbol* class_name, ClassLoaderData* loader) const {
 206     return (klassname() == class_name && loader_data() == loader);
 207   }
 208 
 209   SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
 210     SeenThread* queuehead = NULL;
 211     switch (action) {
 212       case PlaceholderTable::LOAD_INSTANCE:
 213          queuehead = _loadInstanceThreadQ;
 214          break;
 215       case PlaceholderTable::LOAD_SUPER:
 216          queuehead = _superThreadQ;
 217          break;
 218       case PlaceholderTable::DEFINE_CLASS:
 219          queuehead = _defineThreadQ;
 220          break;



 221       default: Unimplemented();
 222     }
 223     return queuehead;
 224   }
 225 
 226   void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
 227     switch (action) {
 228       case PlaceholderTable::LOAD_INSTANCE:
 229          _loadInstanceThreadQ = seenthread;
 230          break;
 231       case PlaceholderTable::LOAD_SUPER:
 232          _superThreadQ = seenthread;
 233          break;
 234       case PlaceholderTable::DEFINE_CLASS:
 235          _defineThreadQ = seenthread;
 236          break;



 237       default: Unimplemented();
 238     }
 239     return;
 240   }
 241 
 242   bool super_load_in_progress() {
 243      return (_superThreadQ != NULL);
 244   }
 245 
 246   bool instance_load_in_progress() {
 247     return (_loadInstanceThreadQ != NULL);
 248   }
 249 
 250   bool define_class_in_progress() {
 251     return (_defineThreadQ != NULL);




 252   }
 253 
 254 // Doubly-linked list of Threads per action for class/classloader pair
 255 // Class circularity support: links in thread before loading superclass
 256 // bootstrapsearchpath support: links in a thread before load_instance_class
 257 // definers: use as queue of define requestors, including owner of
 258 // define token. Appends for debugging of requestor order
 259   void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
 260     assert_lock_strong(SystemDictionary_lock);
 261     SeenThread* threadEntry = new SeenThread(thread);
 262     SeenThread* seen = actionToQueue(action);
 263 
 264     if (seen == NULL) {
 265       set_threadQ(threadEntry, action);
 266       return;
 267     }
 268     SeenThread* next;
 269     while ((next = seen->next()) != NULL) {
 270       seen = next;
 271     }




  57   void add_entry(int index, unsigned int hash, Symbol* name,
  58                 ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
  59 
  60   // This returns a Symbol* to match type for SystemDictionary
  61   Symbol* find_entry(int index, unsigned int hash,
  62                        Symbol* name, ClassLoaderData* loader_data);
  63 
  64   PlaceholderEntry* get_entry(int index, unsigned int hash,
  65                        Symbol* name, ClassLoaderData* loader_data);
  66 
  67 // caller to create a placeholder entry must enumerate an action
  68 // caller claims ownership of that action
  69 // For parallel classloading:
  70 // multiple LOAD_INSTANCE threads can proceed in parallel
  71 // multiple LOAD_SUPER threads can proceed in parallel
  72 // LOAD_SUPER needed to check for class circularity
  73 // DEFINE_CLASS: ultimately define class must be single threaded
  74 // on a class/classloader basis
  75 // so the head of that queue owns the token
  76 // and the rest of the threads return the result the first thread gets
  77 // FLATTENABLE_FIELD: needed to check for value type flattenable fields circularity
  78  enum classloadAction {
  79     LOAD_INSTANCE = 1,             // calling load_instance_class
  80     LOAD_SUPER = 2,                // loading superclass for this class
  81     DEFINE_CLASS = 3,              // find_or_define class
  82     FLATTENABLE_FIELD = 4          // flattenable value type fields
  83  };
  84 
  85   // find_and_add returns probe pointer - old or new
  86   // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
  87   // If entry exists, reuse entry and push SeenThread for classloadAction
  88   PlaceholderEntry* find_and_add(int index, unsigned int hash,
  89                                  Symbol* name, ClassLoaderData* loader_data,
  90                                  classloadAction action, Symbol* supername,
  91                                  Thread* thread);
  92 
  93   void remove_entry(int index, unsigned int hash,
  94                     Symbol* name, ClassLoaderData* loader_data);
  95 
  96   // find_and_remove first removes SeenThread for classloadAction
  97   // If all queues are empty and definer is null, remove the PlacheholderEntry completely
  98   void find_and_remove(int index, unsigned int hash,
  99                        Symbol* name, ClassLoaderData* loader_data,
 100                        classloadAction action, Thread* thread);
 101 
 102   void print_on(outputStream* st) const;
 103   void verify();
 104 };
 105 
 106 // SeenThread objects represent list of threads that are
 107 // currently performing a load action on a class.
 108 // For class circularity, set before loading a superclass.
 109 // For bootclasssearchpath, set before calling load_instance_class.
 110 // Defining must be single threaded on a class/classloader basis
 111 // For DEFINE_CLASS, the head of the queue owns the
 112 // define token and the rest of the threads wait to return the
 113 // result the first thread gets.
 114 // For FLATTENABLE_FIELD, set when loading value type fields for
 115 // class circularity checking.
 116 class SeenThread: public CHeapObj<mtInternal> {
 117 private:
 118    Thread *_thread;
 119    SeenThread* _stnext;
 120    SeenThread* _stprev;
 121 public:
 122    SeenThread(Thread *thread) {
 123        _thread = thread;
 124        _stnext = NULL;
 125        _stprev = NULL;
 126    }
 127    Thread* thread()                const { return _thread;}
 128    void set_thread(Thread *thread) { _thread = thread; }
 129 
 130    SeenThread* next()              const { return _stnext;}
 131    void set_next(SeenThread *seen) { _stnext = seen; }
 132    void set_prev(SeenThread *seen) { _stprev = seen; }
 133 
 134   void print_action_queue(outputStream* st) {
 135     SeenThread* seen = this;


 147 // on store ordering here.
 148 // The system dictionary is the only user of this class.
 149 
 150 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
 151 
 152  private:
 153   ClassLoaderData*  _loader_data;   // initiating loader
 154   bool              _havesupername; // distinguish between null supername, and unknown
 155   Symbol*           _supername;
 156   Thread*           _definer;       // owner of define token
 157   InstanceKlass*    _instanceKlass; // InstanceKlass from successful define
 158   SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
 159   SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
 160                                     // can be multiple threads if classloader object lock broken by application
 161                                     // or if classloader supports parallel classloading
 162 
 163   SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
 164                                     // including _definer
 165                                     // _definer owns token
 166                                     // queue waits for and returns results from _definer
 167   SeenThread*       _flattenableFieldQ; // queue of value types for circularity checking
 168 
 169  public:
 170   // Simple accessors, used only by SystemDictionary
 171   Symbol*            klassname()           const { return literal(); }
 172 
 173   ClassLoaderData*   loader_data()         const { return _loader_data; }
 174   void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
 175 
 176   bool               havesupername()       const { return _havesupername; }
 177   void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
 178 
 179   Symbol*            supername()           const { return _supername; }
 180   void               set_supername(Symbol* supername) {
 181     _supername = supername;
 182     if (_supername != NULL) _supername->increment_refcount();
 183   }
 184 
 185   Thread*            definer()             const {return _definer; }
 186   void               set_definer(Thread* definer) { _definer = definer; }
 187 
 188   InstanceKlass*     instance_klass()      const {return _instanceKlass; }
 189   void               set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; }
 190 
 191   SeenThread*        superThreadQ()        const { return _superThreadQ; }
 192   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
 193 
 194   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
 195   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
 196 
 197   SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
 198   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
 199 
 200   SeenThread*        flattenableFieldQ()    const { return _flattenableFieldQ; }
 201   void               set_flattenableFieldQ(SeenThread* SeenThread) { _flattenableFieldQ = SeenThread; }
 202 
 203   PlaceholderEntry* next() const {
 204     return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
 205   }
 206 
 207   PlaceholderEntry** next_addr() {
 208     return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
 209   }
 210 
 211   // Test for equality
 212   // Entries are unique for class/classloader name pair
 213   bool equals(Symbol* class_name, ClassLoaderData* loader) const {
 214     return (klassname() == class_name && loader_data() == loader);
 215   }
 216 
 217   SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
 218     SeenThread* queuehead = NULL;
 219     switch (action) {
 220       case PlaceholderTable::LOAD_INSTANCE:
 221          queuehead = _loadInstanceThreadQ;
 222          break;
 223       case PlaceholderTable::LOAD_SUPER:
 224          queuehead = _superThreadQ;
 225          break;
 226       case PlaceholderTable::DEFINE_CLASS:
 227          queuehead = _defineThreadQ;
 228          break;
 229       case PlaceholderTable::FLATTENABLE_FIELD:
 230          queuehead = _flattenableFieldQ;
 231          break;
 232       default: Unimplemented();
 233     }
 234     return queuehead;
 235   }
 236 
 237   void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
 238     switch (action) {
 239       case PlaceholderTable::LOAD_INSTANCE:
 240          _loadInstanceThreadQ = seenthread;
 241          break;
 242       case PlaceholderTable::LOAD_SUPER:
 243          _superThreadQ = seenthread;
 244          break;
 245       case PlaceholderTable::DEFINE_CLASS:
 246          _defineThreadQ = seenthread;
 247          break;
 248       case PlaceholderTable::FLATTENABLE_FIELD:
 249          _flattenableFieldQ = seenthread;
 250          break;
 251       default: Unimplemented();
 252     }
 253     return;
 254   }
 255 
 256   bool super_load_in_progress() {
 257      return (_superThreadQ != NULL);
 258   }
 259 
 260   bool instance_load_in_progress() {
 261     return (_loadInstanceThreadQ != NULL);
 262   }
 263 
 264   bool define_class_in_progress() {
 265     return (_defineThreadQ != NULL);
 266   }
 267 
 268   bool flattenable_field_in_progress() {
 269     return (_flattenableFieldQ != NULL);
 270   }
 271 
 272 // Doubly-linked list of Threads per action for class/classloader pair
 273 // Class circularity support: links in thread before loading superclass
 274 // bootstrapsearchpath support: links in a thread before load_instance_class
 275 // definers: use as queue of define requestors, including owner of
 276 // define token. Appends for debugging of requestor order
 277   void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
 278     assert_lock_strong(SystemDictionary_lock);
 279     SeenThread* threadEntry = new SeenThread(thread);
 280     SeenThread* seen = actionToQueue(action);
 281 
 282     if (seen == NULL) {
 283       set_threadQ(threadEntry, action);
 284       return;
 285     }
 286     SeenThread* next;
 287     while ((next = seen->next()) != NULL) {
 288       seen = next;
 289     }


< prev index next >