1/*
2 * Copyright (c) 2016, 2019, 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 */
24
25#ifndef SHARE_CLASSFILE_PACKAGEENTRY_HPP
26#define SHARE_CLASSFILE_PACKAGEENTRY_HPP
27
28#include "classfile/moduleEntry.hpp"
29#include "oops/symbol.hpp"
30#include "utilities/growableArray.hpp"
31#include "utilities/hashtable.hpp"
32#include "utilities/macros.hpp"
33#include "utilities/ostream.hpp"
34#if INCLUDE_JFR
35#include "jfr/support/jfrTraceIdExtension.hpp"
36#endif
37
38
39// A PackageEntry basically represents a Java package. It contains:
40// - Symbol* containing the package's name.
41// - ModuleEntry* for this package's containing module.
42// - a field indicating if the package is exported unqualifiedly or to all
43// unnamed modules.
44// - a growable array containing other module entries that this
45// package is exported to.
46//
47// Packages can be exported in the following 3 ways:
48// - not exported: the package does not have qualified or unqualified exports.
49// - qualified exports: the package has been explicitly qualified to at least
50// one particular module or has been qualifiedly exported
51// to all unnamed modules.
52// Note: being exported to all unnamed is a form of a qualified
53// export. It is equivalent to the package being explicitly
54// exported to all current and future unnamed modules.
55// - unqualified exports: the package is exported to all modules.
56//
57// A package can transition from:
58// - being not exported, to being exported either in a qualified or unqualified manner
59// - being qualifiedly exported, to unqualifiedly exported. Its exported scope is widened.
60//
61// A package cannot transition from:
62// - being unqualifiedly exported, to exported qualifiedly to a specific module.
63// This transition attempt is silently ignored in set_exported.
64// - being qualifiedly exported to not exported.
65// Because transitions are only allowed from less exposure to greater exposure,
66// the transition from qualifiedly exported to not exported would be considered
67// a backward direction. Therefore the implementation considers a package as
68// qualifiedly exported even if its export-list exists but is empty.
69//
70// The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
71// data structure.
72
73// PKG_EXP_UNQUALIFIED and PKG_EXP_ALLUNNAMED indicate whether the package is
74// exported unqualifiedly or exported to all unnamed modules. They are used to
75// set the value of _export_flags. Field _export_flags and the _qualified_exports
76// list are used to determine a package's export state.
77// Valid states are:
78//
79// 1. Package is not exported
80// _export_flags is zero and _qualified_exports is null
81// 2. Package is unqualifiedly exported
82// _export_flags is set to PKG_EXP_UNQUALIFIED
83// _qualified_exports may or may not be null depending on whether the package
84// transitioned from qualifiedly exported to unqualifiedly exported.
85// 3. Package is qualifiedly exported
86// _export_flags may be set to PKG_EXP_ALLUNNAMED if the package is also
87// exported to all unnamed modules
88// _qualified_exports will be non-null
89// 4. Package is exported to all unnamed modules
90// _export_flags is set to PKG_EXP_ALLUNNAMED
91// _qualified_exports may or may not be null depending on whether the package
92// is also qualifiedly exported to one or more named modules.
93#define PKG_EXP_UNQUALIFIED 0x0001
94#define PKG_EXP_ALLUNNAMED 0x0002
95#define PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED (PKG_EXP_UNQUALIFIED | PKG_EXP_ALLUNNAMED)
96
97class PackageEntry : public HashtableEntry<Symbol*, mtModule> {
98private:
99 ModuleEntry* _module;
100 // Indicates if package is exported unqualifiedly or to all unnamed. Access to
101 // this field is protected by the Module_lock.
102 int _export_flags;
103 // Used to indicate for packages with classes loaded by the boot loader that
104 // a class in that package has been loaded. And, for packages with classes
105 // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it
106 // indicates from which class path entry.
107 s2 _classpath_index;
108 bool _must_walk_exports;
109 // Contains list of modules this package is qualifiedly exported to. Access
110 // to this list is protected by the Module_lock.
111 GrowableArray<ModuleEntry*>* _qualified_exports;
112 JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
113
114 // Initial size of a package entry's list of qualified exports.
115 enum {QUAL_EXP_SIZE = 43};
116
117public:
118 void init() {
119 _module = NULL;
120 _export_flags = 0;
121 _classpath_index = -1;
122 _must_walk_exports = false;
123 _qualified_exports = NULL;
124 }
125
126 // package name
127 Symbol* name() const { return literal(); }
128
129 // the module containing the package definition
130 ModuleEntry* module() const { return _module; }
131 void set_module(ModuleEntry* m) { _module = m; }
132
133 // package's export state
134 bool is_exported() const { // qualifiedly or unqualifiedly exported
135 assert_locked_or_safepoint(Module_lock);
136 return module()->is_open() ||
137 ((_export_flags & PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED) != 0) ||
138 has_qual_exports_list();
139 }
140 // Returns true if the package has any explicit qualified exports or is exported to all unnamed
141 bool is_qual_exported() const {
142 assert_locked_or_safepoint(Module_lock);
143 return (has_qual_exports_list() || is_exported_allUnnamed());
144 }
145 // Returns true if there are any explicit qualified exports. Note that even
146 // if the _qualified_exports list is now empty (because the modules that were
147 // on the list got gc-ed and deleted from the list) this method may still
148 // return true.
149 bool has_qual_exports_list() const {
150 assert_locked_or_safepoint(Module_lock);
151 return (!is_unqual_exported() && _qualified_exports != NULL);
152 }
153 bool is_exported_allUnnamed() const {
154 assert_locked_or_safepoint(Module_lock);
155 return (module()->is_open() || _export_flags == PKG_EXP_ALLUNNAMED);
156 }
157 bool is_unqual_exported() const {
158 assert_locked_or_safepoint(Module_lock);
159 return (module()->is_open() || _export_flags == PKG_EXP_UNQUALIFIED);
160 }
161
162 // Explicitly set _export_flags to PKG_EXP_UNQUALIFIED and clear
163 // PKG_EXP_ALLUNNAMED, if it was set.
164 void set_unqual_exported() {
165 if (module()->is_open()) {
166 // No-op for open modules since all packages are unqualifiedly exported
167 return;
168 }
169 assert(Module_lock->owned_by_self(), "should have the Module_lock");
170 _export_flags = PKG_EXP_UNQUALIFIED;
171 }
172
173 bool exported_pending_delete() const;
174
175 void set_exported(ModuleEntry* m);
176
177 void set_is_exported_allUnnamed();
178
179 void set_classpath_index(s2 classpath_index) {
180 _classpath_index = classpath_index;
181 }
182 s2 classpath_index() const { return _classpath_index; }
183
184 bool has_loaded_class() const { return _classpath_index != -1; }
185
186 // returns true if the package is defined in the unnamed module
187 bool in_unnamed_module() const { return !_module->is_named(); }
188
189 // returns true if the package specifies m as a qualified export, including through an unnamed export
190 bool is_qexported_to(ModuleEntry* m) const;
191
192 // add the module to the package's qualified exports
193 void add_qexport(ModuleEntry* m);
194 void set_export_walk_required(ClassLoaderData* m_loader_data);
195
196 PackageEntry* next() const {
197 return (PackageEntry*)HashtableEntry<Symbol*, mtModule>::next();
198 }
199
200 PackageEntry** next_addr() {
201 return (PackageEntry**)HashtableEntry<Symbol*, mtModule>::next_addr();
202 }
203
204 // iteration of qualified exports
205 void package_exports_do(ModuleClosure* f);
206
207 JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
208
209 // Purge dead weak references out of exported list when any given class loader is unloaded.
210 void purge_qualified_exports();
211 void delete_qualified_exports();
212
213 void print(outputStream* st = tty);
214 void verify();
215};
216
217// The PackageEntryTable is a Hashtable containing a list of all packages defined
218// by a particular class loader. Each package is represented as a PackageEntry node.
219// The PackageEntryTable's lookup is lock free.
220//
221class PackageEntryTable : public Hashtable<Symbol*, mtModule> {
222 friend class VMStructs;
223public:
224 enum Constants {
225 _packagetable_entry_size = 109 // number of entries in package entry table
226 };
227
228private:
229 PackageEntry* new_entry(unsigned int hash, Symbol* name, ModuleEntry* module);
230 void add_entry(int index, PackageEntry* new_entry);
231
232 int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
233
234 PackageEntry** bucket_addr(int i) {
235 return (PackageEntry**)Hashtable<Symbol*, mtModule>::bucket_addr(i);
236 }
237
238 static unsigned int compute_hash(Symbol* name) { return (unsigned int)(name->identity_hash()); }
239 int index_for(Symbol* name) const { return hash_to_index(compute_hash(name)); }
240
241public:
242 PackageEntryTable(int table_size);
243 ~PackageEntryTable();
244
245 PackageEntry* bucket(int i) {
246 return (PackageEntry*)Hashtable<Symbol*, mtModule>::bucket(i);
247 }
248
249 // Create package entry in loader's package entry table. Assume Module
250 // lock was taken by caller.
251 void locked_create_entry(Symbol* name, ModuleEntry* module);
252
253 // Create package entry in loader's package entry table if it does not
254 // already exist. Assume Module lock was taken by caller.
255 void locked_create_entry_if_not_exist(Symbol* name, ModuleEntry* module);
256
257 // Lookup Package with loader's package entry table, add it if not found.
258 // This will acquire the Module lock.
259 PackageEntry* lookup(Symbol* name, ModuleEntry* module);
260
261 // Only lookup Package within loader's package entry table.
262 // This will acquire the Module lock.
263 PackageEntry* lookup_only(Symbol* Package);
264
265 // Only lookup Package within loader's package entry table. Assume Module lock
266 // was taken by caller.
267 PackageEntry* locked_lookup_only(Symbol* Package);
268
269 void verify_javabase_packages(GrowableArray<Symbol*> *pkg_list);
270
271 // purge dead weak references out of exported list
272 void purge_all_package_exports();
273
274 void print(outputStream* st = tty);
275 void verify();
276};
277
278#endif // SHARE_CLASSFILE_PACKAGEENTRY_HPP
279