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