src/share/vm/classfile/placeholders.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/classfile/placeholders.hpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,341 @@
     1.4 +/*
     1.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#ifndef SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
    1.29 +#define SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP
    1.30 +
    1.31 +#include "runtime/thread.hpp"
    1.32 +#include "utilities/hashtable.hpp"
    1.33 +
    1.34 +class PlaceholderEntry;
    1.35 +
    1.36 +// Placeholder objects. These represent classes currently
    1.37 +// being loaded, as well as arrays of primitives.
    1.38 +//
    1.39 +
    1.40 +class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> {
    1.41 +  friend class VMStructs;
    1.42 +
    1.43 +public:
    1.44 +  PlaceholderTable(int table_size);
    1.45 +
    1.46 +  PlaceholderEntry* new_entry(int hash, Symbol* name, ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
    1.47 +  void free_entry(PlaceholderEntry* entry);
    1.48 +
    1.49 +  PlaceholderEntry* bucket(int i) {
    1.50 +    return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
    1.51 +  }
    1.52 +
    1.53 +  PlaceholderEntry** bucket_addr(int i) {
    1.54 +    return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
    1.55 +  }
    1.56 +
    1.57 +  void add_entry(int index, PlaceholderEntry* new_entry) {
    1.58 +    Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry);
    1.59 +  }
    1.60 +
    1.61 +  void add_entry(int index, unsigned int hash, Symbol* name,
    1.62 +                ClassLoaderData* loader_data, bool havesupername, Symbol* supername);
    1.63 +
    1.64 +  // This returns a Symbol* to match type for SystemDictionary
    1.65 +  Symbol* find_entry(int index, unsigned int hash,
    1.66 +                       Symbol* name, ClassLoaderData* loader_data);
    1.67 +
    1.68 +  PlaceholderEntry* get_entry(int index, unsigned int hash,
    1.69 +                       Symbol* name, ClassLoaderData* loader_data);
    1.70 +
    1.71 +// caller to create a placeholder entry must enumerate an action
    1.72 +// caller claims ownership of that action
    1.73 +// For parallel classloading:
    1.74 +// multiple LOAD_INSTANCE threads can proceed in parallel
    1.75 +// multiple LOAD_SUPER threads can proceed in parallel
    1.76 +// LOAD_SUPER needed to check for class circularity
    1.77 +// DEFINE_CLASS: ultimately define class must be single threaded
    1.78 +// on a class/classloader basis
    1.79 +// so the head of that queue owns the token
    1.80 +// and the rest of the threads return the result the first thread gets
    1.81 + enum classloadAction {
    1.82 +    LOAD_INSTANCE = 1,             // calling load_instance_class
    1.83 +    LOAD_SUPER = 2,                // loading superclass for this class
    1.84 +    DEFINE_CLASS = 3               // find_or_define class
    1.85 + };
    1.86 +
    1.87 +  // find_and_add returns probe pointer - old or new
    1.88 +  // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
    1.89 +  // If entry exists, reuse entry and push SeenThread for classloadAction
    1.90 +  PlaceholderEntry* find_and_add(int index, unsigned int hash,
    1.91 +                                 Symbol* name, ClassLoaderData* loader_data,
    1.92 +                                 classloadAction action, Symbol* supername,
    1.93 +                                 Thread* thread);
    1.94 +
    1.95 +  void remove_entry(int index, unsigned int hash,
    1.96 +                    Symbol* name, ClassLoaderData* loader_data);
    1.97 +
    1.98 +  // find_and_remove first removes SeenThread for classloadAction
    1.99 +  // If all queues are empty and definer is null, remove the PlacheholderEntry completely
   1.100 +  void find_and_remove(int index, unsigned int hash,
   1.101 +                       Symbol* name, ClassLoaderData* loader_data,
   1.102 +                       classloadAction action, Thread* thread);
   1.103 +
   1.104 +  // GC support.
   1.105 +  void classes_do(KlassClosure* f);
   1.106 +
   1.107 +  // JVMTI support
   1.108 +  void entries_do(void f(Symbol*));
   1.109 +
   1.110 +#ifndef PRODUCT
   1.111 +  void print();
   1.112 +#endif
   1.113 +  void verify();
   1.114 +};
   1.115 +
   1.116 +// SeenThread objects represent list of threads that are
   1.117 +// currently performing a load action on a class.
   1.118 +// For class circularity, set before loading a superclass.
   1.119 +// For bootclasssearchpath, set before calling load_instance_class.
   1.120 +// Defining must be single threaded on a class/classloader basis
   1.121 +// For DEFINE_CLASS, the head of the queue owns the
   1.122 +// define token and the rest of the threads wait to return the
   1.123 +// result the first thread gets.
   1.124 +class SeenThread: public CHeapObj<mtInternal> {
   1.125 +private:
   1.126 +   Thread *_thread;
   1.127 +   SeenThread* _stnext;
   1.128 +   SeenThread* _stprev;
   1.129 +public:
   1.130 +   SeenThread(Thread *thread) {
   1.131 +       _thread = thread;
   1.132 +       _stnext = NULL;
   1.133 +       _stprev = NULL;
   1.134 +   }
   1.135 +   Thread* thread()                const { return _thread;}
   1.136 +   void set_thread(Thread *thread) { _thread = thread; }
   1.137 +
   1.138 +   SeenThread* next()              const { return _stnext;}
   1.139 +   void set_next(SeenThread *seen) { _stnext = seen; }
   1.140 +   void set_prev(SeenThread *seen) { _stprev = seen; }
   1.141 +
   1.142 +#ifndef PRODUCT
   1.143 +  void printActionQ() {
   1.144 +    SeenThread* seen = this;
   1.145 +    while (seen != NULL) {
   1.146 +      seen->thread()->print_value();
   1.147 +      tty->print(", ");
   1.148 +      seen = seen->next();
   1.149 +    }
   1.150 +  }
   1.151 +#endif // PRODUCT
   1.152 +};
   1.153 +
   1.154 +// Placeholder objects represent classes currently being loaded.
   1.155 +// All threads examining the placeholder table must hold the
   1.156 +// SystemDictionary_lock, so we don't need special precautions
   1.157 +// on store ordering here.
   1.158 +// The system dictionary is the only user of this class.
   1.159 +
   1.160 +class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
   1.161 +  friend class VMStructs;
   1.162 +
   1.163 +
   1.164 + private:
   1.165 +  ClassLoaderData*  _loader_data;   // initiating loader
   1.166 +  bool              _havesupername; // distinguish between null supername, and unknown
   1.167 +  Symbol*           _supername;
   1.168 +  Thread*           _definer;       // owner of define token
   1.169 +  Klass*            _instanceKlass; // InstanceKlass from successful define
   1.170 +  SeenThread*       _superThreadQ;  // doubly-linked queue of Threads loading a superclass for this class
   1.171 +  SeenThread*       _loadInstanceThreadQ;  // loadInstance thread
   1.172 +                                    // can be multiple threads if classloader object lock broken by application
   1.173 +                                    // or if classloader supports parallel classloading
   1.174 +
   1.175 +  SeenThread*       _defineThreadQ; // queue of Threads trying to define this class
   1.176 +                                    // including _definer
   1.177 +                                    // _definer owns token
   1.178 +                                    // queue waits for and returns results from _definer
   1.179 +
   1.180 + public:
   1.181 +  // Simple accessors, used only by SystemDictionary
   1.182 +  Symbol*            klassname()           const { return literal(); }
   1.183 +
   1.184 +  ClassLoaderData*   loader_data()         const { return _loader_data; }
   1.185 +  void               set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
   1.186 +
   1.187 +  bool               havesupername()       const { return _havesupername; }
   1.188 +  void               set_havesupername(bool havesupername) { _havesupername = havesupername; }
   1.189 +
   1.190 +  Symbol*            supername()           const { return _supername; }
   1.191 +  void               set_supername(Symbol* supername) {
   1.192 +    _supername = supername;
   1.193 +    if (_supername != NULL) _supername->increment_refcount();
   1.194 +  }
   1.195 +
   1.196 +  Thread*            definer()             const {return _definer; }
   1.197 +  void               set_definer(Thread* definer) { _definer = definer; }
   1.198 +
   1.199 +  Klass*             instance_klass()      const {return _instanceKlass; }
   1.200 +  void               set_instance_klass(Klass* ik) { _instanceKlass = ik; }
   1.201 +
   1.202 +  SeenThread*        superThreadQ()        const { return _superThreadQ; }
   1.203 +  void               set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
   1.204 +
   1.205 +  SeenThread*        loadInstanceThreadQ() const { return _loadInstanceThreadQ; }
   1.206 +  void               set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; }
   1.207 +
   1.208 +  SeenThread*        defineThreadQ()        const { return _defineThreadQ; }
   1.209 +  void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
   1.210 +
   1.211 +  PlaceholderEntry* next() const {
   1.212 +    return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
   1.213 +  }
   1.214 +
   1.215 +  PlaceholderEntry** next_addr() {
   1.216 +    return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
   1.217 +  }
   1.218 +
   1.219 +  // Test for equality
   1.220 +  // Entries are unique for class/classloader name pair
   1.221 +  bool equals(Symbol* class_name, ClassLoaderData* loader) const {
   1.222 +    return (klassname() == class_name && loader_data() == loader);
   1.223 +  }
   1.224 +
   1.225 +  SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
   1.226 +    SeenThread* queuehead;
   1.227 +    switch (action) {
   1.228 +      case PlaceholderTable::LOAD_INSTANCE:
   1.229 +         queuehead = _loadInstanceThreadQ;
   1.230 +         break;
   1.231 +      case PlaceholderTable::LOAD_SUPER:
   1.232 +         queuehead = _superThreadQ;
   1.233 +         break;
   1.234 +      case PlaceholderTable::DEFINE_CLASS:
   1.235 +         queuehead = _defineThreadQ;
   1.236 +         break;
   1.237 +      default: Unimplemented();
   1.238 +    }
   1.239 +    return queuehead;
   1.240 +  }
   1.241 +
   1.242 +  void set_threadQ(SeenThread* seenthread, PlaceholderTable::classloadAction action) {
   1.243 +    switch (action) {
   1.244 +      case PlaceholderTable::LOAD_INSTANCE:
   1.245 +         _loadInstanceThreadQ = seenthread;
   1.246 +         break;
   1.247 +      case PlaceholderTable::LOAD_SUPER:
   1.248 +         _superThreadQ = seenthread;
   1.249 +         break;
   1.250 +      case PlaceholderTable::DEFINE_CLASS:
   1.251 +         _defineThreadQ = seenthread;
   1.252 +         break;
   1.253 +      default: Unimplemented();
   1.254 +    }
   1.255 +    return;
   1.256 +  }
   1.257 +
   1.258 +  bool super_load_in_progress() {
   1.259 +     return (_superThreadQ != NULL);
   1.260 +  }
   1.261 +
   1.262 +  bool instance_load_in_progress() {
   1.263 +    return (_loadInstanceThreadQ != NULL);
   1.264 +  }
   1.265 +
   1.266 +  bool define_class_in_progress() {
   1.267 +    return (_defineThreadQ != NULL);
   1.268 +  }
   1.269 +
   1.270 +// Doubly-linked list of Threads per action for class/classloader pair
   1.271 +// Class circularity support: links in thread before loading superclass
   1.272 +// bootstrapsearchpath support: links in a thread before load_instance_class
   1.273 +// definers: use as queue of define requestors, including owner of
   1.274 +// define token. Appends for debugging of requestor order
   1.275 +  void add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   1.276 +    assert_lock_strong(SystemDictionary_lock);
   1.277 +    SeenThread* threadEntry = new SeenThread(thread);
   1.278 +    SeenThread* seen = actionToQueue(action);
   1.279 +
   1.280 +    if (seen == NULL) {
   1.281 +      set_threadQ(threadEntry, action);
   1.282 +      return;
   1.283 +    }
   1.284 +    SeenThread* next;
   1.285 +    while ((next = seen->next()) != NULL) {
   1.286 +      seen = next;
   1.287 +    }
   1.288 +    seen->set_next(threadEntry);
   1.289 +    threadEntry->set_prev(seen);
   1.290 +    return;
   1.291 +  }
   1.292 +
   1.293 +  bool check_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   1.294 +    assert_lock_strong(SystemDictionary_lock);
   1.295 +    SeenThread* threadQ = actionToQueue(action);
   1.296 +    SeenThread* seen = threadQ;
   1.297 +    while (seen) {
   1.298 +      if (thread == seen->thread()) {
   1.299 +        return true;
   1.300 +      }
   1.301 +      seen = seen->next();
   1.302 +    }
   1.303 +    return false;
   1.304 +  }
   1.305 +
   1.306 +  // returns true if seenthreadQ is now empty
   1.307 +  // Note, caller must ensure probe still exists while holding
   1.308 +  // SystemDictionary_lock
   1.309 +  // ignores if cleanup has already been done
   1.310 +  // if found, deletes SeenThread
   1.311 +  bool remove_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) {
   1.312 +    assert_lock_strong(SystemDictionary_lock);
   1.313 +    SeenThread* threadQ = actionToQueue(action);
   1.314 +    SeenThread* seen = threadQ;
   1.315 +    SeenThread* prev = NULL;
   1.316 +    while (seen) {
   1.317 +      if (thread == seen->thread()) {
   1.318 +        if (prev) {
   1.319 +          prev->set_next(seen->next());
   1.320 +        } else {
   1.321 +          set_threadQ(seen->next(), action);
   1.322 +        }
   1.323 +        if (seen->next()) {
   1.324 +          seen->next()->set_prev(prev);
   1.325 +        }
   1.326 +        delete seen;
   1.327 +        break;
   1.328 +      }
   1.329 +      prev = seen;
   1.330 +      seen = seen->next();
   1.331 +    }
   1.332 +    return (actionToQueue(action) == NULL);
   1.333 +  }
   1.334 +
   1.335 +  // GC support
   1.336 +  // Applies "f->do_oop" to all root oops in the placeholder table.
   1.337 +  void classes_do(KlassClosure* closure);
   1.338 +
   1.339 +  // Print method doesn't append a cr
   1.340 +  void print() const  PRODUCT_RETURN;
   1.341 +  void verify() const;
   1.342 +};
   1.343 +
   1.344 +#endif // SHARE_VM_CLASSFILE_PLACEHOLDERS_HPP

mercurial