src/share/vm/classfile/placeholders.hpp

Mon, 07 Jul 2014 10:12:40 +0200

author
stefank
date
Mon, 07 Jul 2014 10:12:40 +0200
changeset 6992
2c6ef90f030a
parent 4425
aefb345d3f5e
child 6876
710a3c8b516e
child 8316
626f594dffa6
permissions
-rw-r--r--

8049421: G1 Class Unloading after completing a concurrent mark cycle
Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov
Contributed-by: stefan.karlsson@oracle.com, mikael.gerdin@oracle.com

     1 /*
     2  * Copyright (c) 2003, 2013, 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  */
    25 #ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
    26 #define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
    28 #include "runtime/thread.hpp"
    29 #include "utilities/hashtable.hpp"
    31 class PlaceholderEntry;
    33 // Placeholder objects. These represent classes currently
    34 // being loaded, as well as arrays of primitives.
    35 //
    37 class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> {
    38   friend class VMStructs;
    40 public:
    41   PlaceholderTable(int table_size);
    43   PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
    44   void free_entry(PlaceholderEntry* entry);
    46   PlaceholderEntry* bucket(int i) {
    47     return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
    48   }
    50   PlaceholderEntry** bucket_addr(int i) {
    51     return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
    52   }
    54   void add_entry(int index, PlaceholderEntry* new_entry) {
    55     Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry);
    56   }
    58   void add_entry(int index, unsigned int hash, Symbol* name,
    59                 ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
    61   // This returns a Symbol* to match type for SystemDictionary
    62   Symbol* find_entry(int index, unsigned int hash,
    63                        Symbol* name, ClassLoaderData* loader_data);
    65   PlaceholderEntry* get_entry(int index, unsigned int hash,
    66                        Symbol* name, ClassLoaderData* loader_data);
    68 // caller to create a placeholder entry must enumerate an action
    69 // caller claims ownership of that action
    70 // For parallel classloading:
    71 // multiple LOAD_INSTANCE threads can proceed in parallel
    72 // multiple LOAD_SUPER threads can proceed in parallel
    73 // LOAD_SUPER needed to check for class circularity
    74 // DEFINE_CLASS: ultimately define class must be single threaded
    75 // on a class/classloader basis
    76 // so the head of that queue owns the token
    77 // and the rest of the threads return the result the first thread gets
    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  };
    84   // find_and_add returns probe pointer - old or new
    85   // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
    86   // If entry exists, reuse entry and push SeenThread for classloadAction
    87   PlaceholderEntry* find_and_add(int index, unsigned int hash,
    88                                  Symbol* name, ClassLoaderData* loader_data,
    89                                  classloadAction action, Symbol* supername,
    90                                  Thread* thread);
    92   void remove_entry(int index, unsigned int hash,
    93                     Symbol* name, ClassLoaderData* loader_data);
    95   // find_and_remove first removes SeenThread for classloadAction
    96   // If all queues are empty and definer is null, remove the PlacheholderEntry completely
    97   void find_and_remove(int index, unsigned int hash,
    98                        Symbol* name, ClassLoaderData* loader_data,
    99                        classloadAction action, Thread* thread);
   101   // GC support.
   102   void classes_do(KlassClosure* f);
   104   // JVMTI support
   105   void entries_do(void f(Symbol*));
   107 #ifndef PRODUCT
   108   void print();
   109 #endif
   110   void verify();
   111 };
   113 // SeenThread objects represent list of threads that are
   114 // currently performing a load action on a class.
   115 // For class circularity, set before loading a superclass.
   116 // For bootclasssearchpath, set before calling load_instance_class.
   117 // Defining must be single threaded on a class/classloader basis
   118 // For DEFINE_CLASS, the head of the queue owns the
   119 // define token and the rest of the threads wait to return the
   120 // result the first thread gets.
   121 class SeenThread: public CHeapObj<mtInternal> {
   122 private:
   123    Thread *_thread;
   124    SeenThread* _stnext;
   125    SeenThread* _stprev;
   126 public:
   127    SeenThread(Thread *thread) {
   128        _thread = thread;
   129        _stnext = NULL;
   130        _stprev = NULL;
   131    }
   132    Thread* thread()                const { return _thread;}
   133    void set_thread(Thread *thread) { _thread = thread; }
   135    SeenThread* next()              const { return _stnext;}
   136    void set_next(SeenThread *seen) { _stnext = seen; }
   137    void set_prev(SeenThread *seen) { _stprev = seen; }
   139 #ifndef PRODUCT
   140   void printActionQ() {
   141     SeenThread* seen = this;
   142     while (seen != NULL) {
   143       seen->thread()->print_value();
   144       tty->print(", ");
   145       seen = seen->next();
   146     }
   147   }
   148 #endif // PRODUCT
   149 };
   151 // Placeholder objects represent classes currently being loaded.
   152 // All threads examining the placeholder table must hold the
   153 // SystemDictionary_lock, so we don't need special precautions
   154 // on store ordering here.
   155 // The system dictionary is the only user of this class.
   157 class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
   158   friend class VMStructs;
   161  private:
   162   ClassLoaderData*  _loader_data;   // initiating loader
   163   bool              _havesupername; // distinguish between null supername, and unknown
   164   Symbol*           _supername;
   165   Thread*           _definer;       // owner of define token
   166   Klass*            _instanceKlass; // InstanceKlass from successful define
   167   SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
   168   SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
   169                                     // can be multiple threads if classloader object lock broken by application
   170                                     // or if classloader supports parallel classloading
   172   SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
   173                                     // including _definer
   174                                     // _definer owns token
   175                                     // queue waits for and returns results from _definer
   177  public:
   178   // Simple accessors, used only by SystemDictionary
   179   Symbol*            klassname()           const { return literal(); }
   181   ClassLoaderData*   loader_data()         const { return _loader_data; }
   182   void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
   184   bool               havesupername()       const { return _havesupername; }
   185   void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
   187   Symbol*            supername()           const { return _supername; }
   188   void               set_supername(Symbol* supername) {
   189     _supername = supername;
   190     if (_supername != NULL) _supername->increment_refcount();
   191   }
   193   Thread*            definer()             const {return _definer; }
   194   void               set_definer(Thread* definer) { _definer = definer; }
   196   Klass*             instance_klass()      const {return _instanceKlass; }
   197   void               set_instance_klass(Klass* ik) { _instanceKlass = ik; }
   199   SeenThread*        superThreadQ()        const { return _superThreadQ; }
   200   void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
   202   SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
   203   void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
   205   SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
   206   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
   208   PlaceholderEntry* next() const {
   209     return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
   210   }
   212   PlaceholderEntry** next_addr() {
   213     return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
   214   }
   216   // Test for equality
   217   // Entries are unique for class/classloader name pair
   218   bool equals(Symbol* class_name, ClassLoaderData* loader) const {
   219     return (klassname() == class_name && loader_data() == loader);
   220   }
   222   SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
   223     SeenThread* queuehead;
   224     switch (action) {
   225       case PlaceholderTable::LOAD_INSTANCE:
   226          queuehead = _loadInstanceThreadQ;
   227          break;
   228       case PlaceholderTable::LOAD_SUPER:
   229          queuehead = _superThreadQ;
   230          break;
   231       case PlaceholderTable::DEFINE_CLASS:
   232          queuehead = _defineThreadQ;
   233          break;
   234       default: Unimplemented();
   235     }
   236     return queuehead;
   237   }
   239   void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
   240     switch (action) {
   241       case PlaceholderTable::LOAD_INSTANCE:
   242          _loadInstanceThreadQ = seenthread;
   243          break;
   244       case PlaceholderTable::LOAD_SUPER:
   245          _superThreadQ = seenthread;
   246          break;
   247       case PlaceholderTable::DEFINE_CLASS:
   248          _defineThreadQ = seenthread;
   249          break;
   250       default: Unimplemented();
   251     }
   252     return;
   253   }
   255   bool super_load_in_progress() {
   256      return (_superThreadQ != NULL);
   257   }
   259   bool instance_load_in_progress() {
   260     return (_loadInstanceThreadQ != NULL);
   261   }
   263   bool define_class_in_progress() {
   264     return (_defineThreadQ != NULL);
   265   }
   267 // Doubly-linked list of Threads per action for class/classloader pair
   268 // Class circularity support: links in thread before loading superclass
   269 // bootstrapsearchpath support: links in a thread before load_instance_class
   270 // definers: use as queue of define requestors, including owner of
   271 // define token. Appends for debugging of requestor order
   272   void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   273     assert_lock_strong(SystemDictionary_lock);
   274     SeenThread* threadEntry = new SeenThread(thread);
   275     SeenThread* seen = actionToQueue(action);
   277     if (seen == NULL) {
   278       set_threadQ(threadEntry, action);
   279       return;
   280     }
   281     SeenThread* next;
   282     while ((next = seen->next()) != NULL) {
   283       seen = next;
   284     }
   285     seen->set_next(threadEntry);
   286     threadEntry->set_prev(seen);
   287     return;
   288   }
   290   bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   291     assert_lock_strong(SystemDictionary_lock);
   292     SeenThread* threadQ = actionToQueue(action);
   293     SeenThread* seen = threadQ;
   294     while (seen) {
   295       if (thread == seen->thread()) {
   296         return true;
   297       }
   298       seen = seen->next();
   299     }
   300     return false;
   301   }
   303   // returns true if seenthreadQ is now empty
   304   // Note, caller must ensure probe still exists while holding
   305   // SystemDictionary_lock
   306   // ignores if cleanup has already been done
   307   // if found, deletes SeenThread
   308   bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   309     assert_lock_strong(SystemDictionary_lock);
   310     SeenThread* threadQ = actionToQueue(action);
   311     SeenThread* seen = threadQ;
   312     SeenThread* prev = NULL;
   313     while (seen) {
   314       if (thread == seen->thread()) {
   315         if (prev) {
   316           prev->set_next(seen->next());
   317         } else {
   318           set_threadQ(seen->next(), action);
   319         }
   320         if (seen->next()) {
   321           seen->next()->set_prev(prev);
   322         }
   323         delete seen;
   324         break;
   325       }
   326       prev = seen;
   327       seen = seen->next();
   328     }
   329     return (actionToQueue(action) == NULL);
   330   }
   332   // GC support
   333   // Applies "f->do_oop" to all root oops in the placeholder table.
   334   void classes_do(KlassClosure* closure);
   336   // Print method doesn't append a cr
   337   void print() const  PRODUCT_RETURN;
   338   void verify() const;
   339 };
   341 #endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP

mercurial