moduleEntry.hpp revision 12290:8953c0318163
10Sstevel@tonic-gate/*
20Sstevel@tonic-gate * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
30Sstevel@tonic-gate * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This code is free software; you can redistribute it and/or modify it
60Sstevel@tonic-gate * under the terms of the GNU General Public License version 2 only, as
70Sstevel@tonic-gate * published by the Free Software Foundation.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This code is distributed in the hope that it will be useful, but WITHOUT
100Sstevel@tonic-gate * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
110Sstevel@tonic-gate * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
120Sstevel@tonic-gate * version 2 for more details (a copy is included in the LICENSE file that
130Sstevel@tonic-gate * accompanied this code).
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * You should have received a copy of the GNU General Public License version
160Sstevel@tonic-gate * 2 along with this work; if not, write to the Free Software Foundation,
170Sstevel@tonic-gate * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
200Sstevel@tonic-gate * or visit www.oracle.com if you need additional information or have any
210Sstevel@tonic-gate * questions.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate#ifndef SHARE_VM_CLASSFILE_MODULEENTRY_HPP
260Sstevel@tonic-gate#define SHARE_VM_CLASSFILE_MODULEENTRY_HPP
270Sstevel@tonic-gate
280Sstevel@tonic-gate#include "classfile/classLoaderData.hpp"
290Sstevel@tonic-gate#include "classfile/vmSymbols.hpp"
300Sstevel@tonic-gate#include "oops/symbol.hpp"
310Sstevel@tonic-gate#include "prims/jni.h"
320Sstevel@tonic-gate#include "runtime/mutexLocker.hpp"
330Sstevel@tonic-gate#include "trace/traceMacros.hpp"
340Sstevel@tonic-gate#include "utilities/growableArray.hpp"
350Sstevel@tonic-gate#include "utilities/hashtable.hpp"
360Sstevel@tonic-gate#include "utilities/ostream.hpp"
370Sstevel@tonic-gate
380Sstevel@tonic-gate#define UNNAMED_MODULE "Unnamed Module"
390Sstevel@tonic-gate#define JAVAPKG "java/"
400Sstevel@tonic-gate#define JAVAPKG_LEN 5
410Sstevel@tonic-gate
429845SJan.Pechanec@Sun.COMclass ModuleClosure;
430Sstevel@tonic-gate
440Sstevel@tonic-gate// A ModuleEntry describes a module that has been defined by a call to JVM_DefineModule.
450Sstevel@tonic-gate// It contains:
460Sstevel@tonic-gate//   - Symbol* containing the module's name.
470Sstevel@tonic-gate//   - pointer to the java.lang.reflect.Module for this module.
480Sstevel@tonic-gate//   - pointer to the java.security.ProtectionDomain shared by classes defined to this module.
490Sstevel@tonic-gate//   - ClassLoaderData*, class loader of this module.
500Sstevel@tonic-gate//   - a growable array containg other module entries that this module can read.
510Sstevel@tonic-gate//   - a flag indicating if this module can read all unnamed modules.
520Sstevel@tonic-gate//
530Sstevel@tonic-gate// The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
540Sstevel@tonic-gate// data structure.
550Sstevel@tonic-gateclass ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
560Sstevel@tonic-gateprivate:
570Sstevel@tonic-gate  jobject _module;                     // java.lang.reflect.Module
580Sstevel@tonic-gate  jobject _pd;                         // java.security.ProtectionDomain, cached
590Sstevel@tonic-gate                                       // for shared classes from this module
600Sstevel@tonic-gate  ClassLoaderData* _loader_data;
610Sstevel@tonic-gate  GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
620Sstevel@tonic-gate  Symbol* _version;                    // module version number
630Sstevel@tonic-gate  Symbol* _location;                   // module location
640Sstevel@tonic-gate  bool _can_read_all_unnamed;
650Sstevel@tonic-gate  bool _has_default_read_edges;        // JVMTI redefine/retransform support
660Sstevel@tonic-gate  bool _must_walk_reads;               // walk module's reads list at GC safepoints to purge out dead modules
670Sstevel@tonic-gate  TRACE_DEFINE_TRACE_ID_FIELD;
680Sstevel@tonic-gate  enum {MODULE_READS_SIZE = 101};      // Initial size of list of modules that the module can read.
690Sstevel@tonic-gate
700Sstevel@tonic-gatepublic:
710Sstevel@tonic-gate  void init() {
720Sstevel@tonic-gate    _module = NULL;
730Sstevel@tonic-gate    _loader_data = NULL;
740Sstevel@tonic-gate    _pd = NULL;
750Sstevel@tonic-gate    _reads = NULL;
760Sstevel@tonic-gate    _version = NULL;
770Sstevel@tonic-gate    _location = NULL;
780Sstevel@tonic-gate    _can_read_all_unnamed = false;
790Sstevel@tonic-gate    _has_default_read_edges = false;
800Sstevel@tonic-gate    _must_walk_reads = false;
810Sstevel@tonic-gate  }
820Sstevel@tonic-gate
830Sstevel@tonic-gate  Symbol*          name() const                        { return literal(); }
840Sstevel@tonic-gate  void             set_name(Symbol* n)                 { set_literal(n); }
850Sstevel@tonic-gate
860Sstevel@tonic-gate  jobject          module() const                      { return _module; }
870Sstevel@tonic-gate  void             set_module(jobject j)               { _module = j; }
880Sstevel@tonic-gate
890Sstevel@tonic-gate  // The shared ProtectionDomain reference is set once the VM loads a shared class
900Sstevel@tonic-gate  // originated from the current Module. The referenced ProtectionDomain object is
910Sstevel@tonic-gate  // created by the ClassLoader when loading a class (shared or non-shared) from the
920Sstevel@tonic-gate  // Module for the first time. This ProtectionDomain object is used for all
930Sstevel@tonic-gate  // classes from the Module loaded by the same ClassLoader.
940Sstevel@tonic-gate  Handle           shared_protection_domain();
950Sstevel@tonic-gate  void             set_shared_protection_domain(ClassLoaderData *loader_data, Handle pd);
960Sstevel@tonic-gate
970Sstevel@tonic-gate  ClassLoaderData* loader_data() const                 { return _loader_data; }
980Sstevel@tonic-gate  void             set_loader_data(ClassLoaderData* l) { _loader_data = l; }
990Sstevel@tonic-gate
1000Sstevel@tonic-gate  Symbol*          version() const                     { return _version; }
1010Sstevel@tonic-gate  void             set_version(Symbol* version);
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate  Symbol*          location() const                    { return _location; }
1040Sstevel@tonic-gate  void             set_location(Symbol* location);
1050Sstevel@tonic-gate
1060Sstevel@tonic-gate  bool             can_read(ModuleEntry* m) const;
1070Sstevel@tonic-gate  bool             has_reads() const;
1080Sstevel@tonic-gate  void             add_read(ModuleEntry* m);
1090Sstevel@tonic-gate  void             set_read_walk_required(ClassLoaderData* m_loader_data);
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate  bool             is_named() const                    { return (name() != NULL); }
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate  bool can_read_all_unnamed() const {
1140Sstevel@tonic-gate    assert(is_named() || _can_read_all_unnamed == true,
1150Sstevel@tonic-gate           "unnamed modules can always read all unnamed modules");
1160Sstevel@tonic-gate    return _can_read_all_unnamed;
1170Sstevel@tonic-gate  }
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate  // Modules can only go from strict to loose.
1200Sstevel@tonic-gate  void set_can_read_all_unnamed() { _can_read_all_unnamed = true; }
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate  bool has_default_read_edges() const {
1230Sstevel@tonic-gate    return _has_default_read_edges;
1240Sstevel@tonic-gate  }
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate  // Sets true and returns the previous value.
1270Sstevel@tonic-gate  bool set_has_default_read_edges() {
1280Sstevel@tonic-gate    MutexLocker ml(Module_lock);
1290Sstevel@tonic-gate    bool prev = _has_default_read_edges;
1300Sstevel@tonic-gate    _has_default_read_edges = true;
1310Sstevel@tonic-gate    return prev;
1320Sstevel@tonic-gate  }
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate  ModuleEntry* next() const {
1350Sstevel@tonic-gate    return (ModuleEntry*)HashtableEntry<Symbol*, mtModule>::next();
1360Sstevel@tonic-gate  }
1370Sstevel@tonic-gate  ModuleEntry** next_addr() {
1380Sstevel@tonic-gate    return (ModuleEntry**)HashtableEntry<Symbol*, mtModule>::next_addr();
1390Sstevel@tonic-gate  }
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate  // iteration support for readability
1420Sstevel@tonic-gate  void module_reads_do(ModuleClosure* const f);
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate  TRACE_DEFINE_TRACE_ID_METHODS;
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate  // Purge dead weak references out of reads list when any given class loader is unloaded.
1470Sstevel@tonic-gate  void purge_reads();
1480Sstevel@tonic-gate  void delete_reads();
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate  void print(outputStream* st = tty);
1510Sstevel@tonic-gate  void verify();
1520Sstevel@tonic-gate};
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate// Iterator interface
1550Sstevel@tonic-gateclass ModuleClosure: public StackObj {
1560Sstevel@tonic-gate public:
1570Sstevel@tonic-gate  virtual void do_module(ModuleEntry* const module) = 0;
1580Sstevel@tonic-gate};
1590Sstevel@tonic-gate
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate// The ModuleEntryTable is a Hashtable containing a list of all modules defined
1620Sstevel@tonic-gate// by a particular class loader.  Each module is represented as a ModuleEntry node.
1630Sstevel@tonic-gate//
1640Sstevel@tonic-gate// Each ModuleEntryTable contains a _javabase_module field which allows for the
1650Sstevel@tonic-gate// creation of java.base's ModuleEntry very early in bootstrapping before the
1660Sstevel@tonic-gate// corresponding JVM_DefineModule call for java.base occurs during module system
1670Sstevel@tonic-gate// initialization.  Setting up java.base's ModuleEntry early enables classes,
1680Sstevel@tonic-gate// loaded prior to the module system being initialized to be created with their
1690Sstevel@tonic-gate// PackageEntry node's correctly pointing at java.base's ModuleEntry.  No class
1700Sstevel@tonic-gate// outside of java.base is allowed to be loaded pre-module system initialization.
1710Sstevel@tonic-gate//
1720Sstevel@tonic-gate// The ModuleEntryTable's lookup is lock free.
1730Sstevel@tonic-gate//
1740Sstevel@tonic-gateclass ModuleEntryTable : public Hashtable<Symbol*, mtModule> {
1750Sstevel@tonic-gate  friend class VMStructs;
1760Sstevel@tonic-gatepublic:
1770Sstevel@tonic-gate  enum Constants {
1780Sstevel@tonic-gate    _moduletable_entry_size  = 109 // number of entries in module entry table
1790Sstevel@tonic-gate  };
1800Sstevel@tonic-gate
1810Sstevel@tonic-gateprivate:
1820Sstevel@tonic-gate  static ModuleEntry* _javabase_module;
1830Sstevel@tonic-gate  ModuleEntry* _unnamed_module;
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate  ModuleEntry* new_entry(unsigned int hash, Handle module_handle, Symbol* name, Symbol* version,
1860Sstevel@tonic-gate                         Symbol* location, ClassLoaderData* loader_data);
1870Sstevel@tonic-gate  void add_entry(int index, ModuleEntry* new_entry);
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate  int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate  ModuleEntry** bucket_addr(int i) {
1920Sstevel@tonic-gate    return (ModuleEntry**)Hashtable<Symbol*, mtModule>::bucket_addr(i);
1930Sstevel@tonic-gate  }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate  static unsigned int compute_hash(Symbol* name) { return ((name == NULL) ? 0 : (unsigned int)(name->identity_hash())); }
1960Sstevel@tonic-gate  int index_for(Symbol* name) const              { return hash_to_index(compute_hash(name)); }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gatepublic:
1990Sstevel@tonic-gate  ModuleEntryTable(int table_size);
2000Sstevel@tonic-gate  ~ModuleEntryTable();
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate  ModuleEntry* bucket(int i) {
2030Sstevel@tonic-gate    return (ModuleEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
2040Sstevel@tonic-gate  }
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate  // Create module in loader's module entry table, if already exists then
2070Sstevel@tonic-gate  // return null.  Assume Module_lock has been locked by caller.
2080Sstevel@tonic-gate  ModuleEntry* locked_create_entry_or_null(Handle module_handle,
2090Sstevel@tonic-gate                                           Symbol* module_name,
2100Sstevel@tonic-gate                                           Symbol* module_version,
2110Sstevel@tonic-gate                                           Symbol* module_location,
2120Sstevel@tonic-gate                                           ClassLoaderData* loader_data);
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate  // Only lookup module within loader's module entry table.  The table read is lock-free.
2150Sstevel@tonic-gate  ModuleEntry* lookup_only(Symbol* name);
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate  // purge dead weak references out of reads list
2180Sstevel@tonic-gate  void purge_all_module_reads();
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate  // Special handling for unnamed module, one per class loader's ModuleEntryTable
2210Sstevel@tonic-gate  void create_unnamed_module(ClassLoaderData* loader_data);
2220Sstevel@tonic-gate  ModuleEntry* unnamed_module()                                { return _unnamed_module; }
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate  // Special handling for java.base
2250Sstevel@tonic-gate  static ModuleEntry* javabase_moduleEntry()                   { return _javabase_module; }
2269845SJan.Pechanec@Sun.COM  static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
2270Sstevel@tonic-gate  static bool javabase_defined()                               { return ((_javabase_module != NULL) &&
2280Sstevel@tonic-gate                                                                         (_javabase_module->module() != NULL)); }
2290Sstevel@tonic-gate  static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
2300Sstevel@tonic-gate  static void patch_javabase_entries(Handle module_handle);
2310Sstevel@tonic-gate
2325334Sjp161948  void print(outputStream* st = tty);
2330Sstevel@tonic-gate  void verify();
2340Sstevel@tonic-gate};
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate#endif // SHARE_VM_CLASSFILE_MODULEENTRY_HPP
2370Sstevel@tonic-gate